# HG changeset patch # User Isaac Dunham # Date 1374871291 18000 # Node ID b2b4bd208b658144be28e3e6d3d7e114ec0412db # Parent e922fc4e7a2e5b60129991afd52e9b861a195830 I've written an lspci implementation. Currently it supports -emkn; -e is an extension ("class" is a 24-bit number, but lspci only shows 16 bits; one person on the Puppy forums mentioned that they need those last 8 bits). -n is a no-op for compatability with standard lspci. diff -r e922fc4e7a2e -r b2b4bd208b65 toys/pending/lspci.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/toys/pending/lspci.c Fri Jul 26 15:41:31 2013 -0500 @@ -0,0 +1,75 @@ +/* + * lspci - written by Isaac Dunham + +USE_LSPCI(NEWTOY(lspci, "emkn", TOYFLAG_USR|TOYFLAG_BIN)) + +config LSPCI + bool "lspci" + default n + help + usage: lspci [-ekmn] + + List PCI devices. + -e Output 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; + char *dname = dirtree_path(new, &alen); + errno = 0; + int 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); + close(dirfd); + if (!errno) { + char *driver = ""; + if (toys.optflags & FLAG_k) { + char module[256] = ""; + strcat(dname, "/driver"); + readlink(dname, module, sizeof(module)); + driver = basename(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, + 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); +}