diff options
| -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);  } | 
