# HG changeset patch # User Felix Janda # Date 1374896945 18000 # Node ID a47c6658210c2420d436980e9300043fe0954773 # Parent b2b4bd208b658144be28e3e6d3d7e114ec0412db lspci: use toybuf instead of dynamic memory allocation diff -r b2b4bd208b65 -r a47c6658210c toys/pending/lspci.c --- a/toys/pending/lspci.c Fri Jul 26 15:41:31 2013 -0500 +++ b/toys/pending/lspci.c Fri Jul 26 22:49:05 2013 -0500 @@ -1,75 +1,65 @@ /* * lspci - written by Isaac Dunham -USE_LSPCI(NEWTOY(lspci, "emkn", TOYFLAG_USR|TOYFLAG_BIN)) +USE_LSPCI(NEWTOY(lspci, "emkns:", TOYFLAG_USR|TOYFLAG_BIN)) config LSPCI bool "lspci" default n help - usage: lspci [-ekmn] + usage: lspci [-ekmn] List PCI devices. - -e Output all 6 digits in class (like elspci) + -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" -char * preadat_name(int dirfd, char *fname, size_t nbyte, off_t offset) -{ - int fd; - char *buf = malloc(nbyte+1); - memset(buf, 0, sizeof(buf)); - fd = openat(dirfd, fname, O_RDONLY); - if (fd < 0) { - return NULL; - } - lseek(fd, offset, SEEK_SET); - read(fd, buf, nbyte); - close(fd); - buf[nbyte +1] = '\0'; - return buf; -} int do_lspci(struct dirtree *new) { - int alen = 8; + 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; - int dirfd = open(dname, O_RDONLY); + dirfd = open(dname, O_RDONLY); if (dirfd > 0) { - char *class = preadat_name(dirfd, "class", - (toys.optflags & FLAG_e) ? 6 :4, 2); - char *vendor = preadat_name(dirfd, "vendor", 4, 2); - char *device = preadat_name(dirfd, "device", 4, 2); + 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 = 6 + 2*((toys.optflags & FLAG_e) && (p != toybuf)); + 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) { - char module[256] = ""; strcat(dname, "/driver"); - readlink(dname, module, sizeof(module)); - driver = basename(module); + if (readlink(dname, bufs->module, sizeof(bufs->module)) != -1) + driver = basename(bufs->module); } - if (toys.optflags & FLAG_m) { - printf("%s, \"%s\" \"%s\" \"%s\" \"%s\"\n",new->name + 5, class, - vendor, device, driver); - } else { - printf("%s Class %s: %s:%s %s\n", new->name + 5, class, vendor, device, + printf(fmt, new->name + 5, bufs->class, bufs->vendor, bufs->device, driver); - } } } - if (!strcmp("/sys/bus/pci/devices", new->name)) { - return DIRTREE_RECURSE; - } return 0; } void lspci_main(void) { - sprintf(toybuf, "/sys/bus/pci/devices"); - dirtree_read(toybuf, do_lspci); + dirtree_read("/sys/bus/pci/devices", do_lspci); }