/* * lspci - written by Isaac Dunham USE_LSPCI(NEWTOY(lspci, "emkns:", TOYFLAG_USR|TOYFLAG_BIN)) config LSPCI bool "lspci" default n help usage: lspci [-ekmn] List PCI devices. -e Print all 6 digits in class (like elspci) -k Print kernel driver -m Machine parseable format -n Numeric output (default) */ #define FOR_lspci #include "toys.h" int do_lspci(struct dirtree *new) { int alen = 8, dirfd; char *dname = dirtree_path(new, &alen); struct { char class[16], vendor[16], device[16], module[256]; } *bufs = (void*)(toybuf + 2); if (!strcmp("/sys/bus/pci/devices", dname)) return DIRTREE_RECURSE; errno = 0; dirfd = open(dname, O_RDONLY); if (dirfd > 0) { char *p, **fields = (char*[]){"class", "vendor", "device", ""}; for (p = toybuf; **fields; p+=16, fields++) { int fd, size; if ((fd = openat(dirfd, *fields, O_RDONLY)) < 0) continue; size = ((toys.optflags & FLAG_e) && (p == toybuf)) ? 8 : 6; p[read(fd, p, size)] = '\0'; close(fd); } close(dirfd); if (!errno) { char *driver = ""; char *fmt = toys.optflags & FLAG_m ? "%s, \"%s\" \"%s\" \"%s\" \"%s\"\n" : "%s Class %s: %s:%s %s\n"; if (toys.optflags & FLAG_k) { strcat(dname, "/driver"); if (readlink(dname, bufs->module, sizeof(bufs->module)) != -1) driver = basename(bufs->module); } printf(fmt, new->name + 5, bufs->class, bufs->vendor, bufs->device, driver); } } return 0; } void lspci_main(void) { dirtree_read("/sys/bus/pci/devices", do_lspci); }