blob: c3afb3c418de775dc4693e0db6e61ceecfa23922 [file] [log] [blame]
Isaac Dunhamfe03a1f2013-07-26 15:41:31 -05001/*
2 * lspci - written by Isaac Dunham
3
4USE_LSPCI(NEWTOY(lspci, "emkn", TOYFLAG_USR|TOYFLAG_BIN))
5
6config LSPCI
7 bool "lspci"
8 default n
9 help
10 usage: lspci [-ekmn]
11
12 List PCI devices.
13 -e Output all 6 digits in class (like elspci)
14 -k Print kernel driver
15 -m Machine parseable format
16 -n Numeric output (default)
17*/
18#define FOR_lspci
19#include "toys.h"
20char * preadat_name(int dirfd, char *fname, size_t nbyte, off_t offset)
21{
22 int fd;
23 char *buf = malloc(nbyte+1);
24 memset(buf, 0, sizeof(buf));
25 fd = openat(dirfd, fname, O_RDONLY);
26 if (fd < 0) {
27 return NULL;
28 }
29 lseek(fd, offset, SEEK_SET);
30 read(fd, buf, nbyte);
31 close(fd);
32 buf[nbyte +1] = '\0';
33 return buf;
34}
35
36int do_lspci(struct dirtree *new)
37{
38 int alen = 8;
39 char *dname = dirtree_path(new, &alen);
40 errno = 0;
41 int dirfd = open(dname, O_RDONLY);
42 if (dirfd > 0) {
43 char *class = preadat_name(dirfd, "class",
44 (toys.optflags & FLAG_e) ? 6 :4, 2);
45 char *vendor = preadat_name(dirfd, "vendor", 4, 2);
46 char *device = preadat_name(dirfd, "device", 4, 2);
47 close(dirfd);
48 if (!errno) {
49 char *driver = "";
50 if (toys.optflags & FLAG_k) {
51 char module[256] = "";
52 strcat(dname, "/driver");
53 readlink(dname, module, sizeof(module));
54 driver = basename(module);
55 }
56 if (toys.optflags & FLAG_m) {
57 printf("%s, \"%s\" \"%s\" \"%s\" \"%s\"\n",new->name + 5, class,
58 vendor, device, driver);
59 } else {
60 printf("%s Class %s: %s:%s %s\n", new->name + 5, class, vendor, device,
61 driver);
62 }
63 }
64 }
65 if (!strcmp("/sys/bus/pci/devices", new->name)) {
66 return DIRTREE_RECURSE;
67 }
68 return 0;
69}
70
71void lspci_main(void)
72{
73 sprintf(toybuf, "/sys/bus/pci/devices");
74 dirtree_read(toybuf, do_lspci);
75}