aboutsummaryrefslogtreecommitdiff
path: root/toys
diff options
context:
space:
mode:
Diffstat (limited to 'toys')
-rw-r--r--toys/pending/lspci.c66
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);
}