diff options
author | Felix Janda <felix.janda@posteo.de> | 2013-07-26 22:49:05 -0500 |
---|---|---|
committer | Felix Janda <felix.janda@posteo.de> | 2013-07-26 22:49:05 -0500 |
commit | f97cc9ff9768b746c26c4989a632cc3891e80d76 (patch) | |
tree | b48aef34f4897af26b8841c229a4c85074030bba | |
parent | fe03a1fd159ae3272a868d248ddc1c56b20cfadd (diff) | |
download | toybox-f97cc9ff9768b746c26c4989a632cc3891e80d76.tar.gz |
lspci: use toybuf instead of dynamic memory allocation
-rw-r--r-- | toys/pending/lspci.c | 66 |
1 files changed, 28 insertions, 38 deletions
diff --git a/toys/pending/lspci.c b/toys/pending/lspci.c index c3afb3c4..b7a6aee4 100644 --- a/toys/pending/lspci.c +++ b/toys/pending/lspci.c @@ -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); } |