[Toybox] [TOY] lspci

Felix Janda felix.janda at posteo.de
Mon Jul 22 12:05:26 PDT 2013


Isaac wrote:
>
> I've written an lspci implementation.

Cool.

> 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.

Are there any more options you have in mind that should be implemented?
Just out of curiosity: Could you post a link to the forum post?

> 75 lines total.

Down to 70 after application of the below patch with small fixes.

It felt more sensible to me to read 2 more bytes and ignore them than to
seek for 2 bytes in a file. So preadat_name now has one argument less.

Use calloc instead of malloc + memset. With this also the off-by-one
error from (origninally) line 32 is fixed. It would be nice to use
toybuf for this, wouldn't it? That would also make valgrind happier.

Print "" instead of "." when .../driver is missing.

The only difference between the usual output and the machine readable
output is the format string. Use this to avoid some repetition.

Felix

--- a/lspci.c	2013-07-22 18:05:37.514838360 +0200
+++ b/lspci.c	2013-07-22 19:12:03.000000000 +0200
@@ -17,19 +17,14 @@
 */
 #define FOR_lspci
 #include "toys.h"
-char * preadat_name(int dirfd, char *fname, size_t nbyte, off_t offset)
+char * preadat_name(int dirfd, char *fname, size_t nbyte)
 {
   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);
+  char *buf = calloc(1, nbyte+1);
+
+  if (0 > (fd = openat(dirfd, fname, O_RDONLY))) return NULL;
   read(fd, buf, nbyte);
   close(fd);
-  buf[nbyte +1] = '\0';
   return buf;
 }
 
@@ -37,31 +32,32 @@
 {
   int alen = 8;
   char *dname = dirtree_path(new, &alen);
+
   if (!strcmp("/sys/bus/pci/devices", dname))
     return DIRTREE_RECURSE;
   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);
+                (toys.optflags & FLAG_e) ? 8 : 6);
+    char *vendor = preadat_name(dirfd, "vendor", 6);
+    char *device = preadat_name(dirfd, "device", 6);
+
     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 (-1 != 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, 
+      printf(fmt, new->name + 5, class + 2, vendor + 2, device + 2,
                driver);
-      }
     }
   }
   return 0;
@@ -69,6 +65,5 @@
 
 void lspci_main(void)
 {
-  sprintf(toybuf, "/sys/bus/pci/devices");
-  dirtree_read(toybuf, do_lspci);
+  dirtree_read("/sys/bus/pci/devices", do_lspci);
 }

 1374519926.0


More information about the Toybox mailing list