[Toybox] [TOY] lspci - no *alloc

Isaac idunham at lavabit.com
Wed Jul 24 16:34:25 PDT 2013


On Wed, Jul 24, 2013 at 09:20:51PM +0200, Felix Janda wrote:
> Attached Isaac's toy edited to use toybuf instead of
> dynamic memory allocation. It could look prettier, though...
> 
> Felix
> 
Broken:
/toybox lspci -e
00:00.0 Class 0600: 8086
:27ac
 
00:02.0 Class 0300: 8086
:27ae
 
..
/toybox lspci
00:00.0 Class 0600: 8086:27ac 
00:02.0 Class 0300: 8086:27ae
..

The -e flag should be expanding the width of "class" (it isn't),
and it should not be making lspci print 3 lines per entry.
And I'm not sure how to fix it.

By the way, there are requests for more features (-v/-vv and text output) 
that would mean slightly different approaches to getting data; (p)readat_name 
would work in many of these cases, but text output means reading to toybuf
(which would clobber this), and I would also need to add more fields of varying sizes.

> 

> /*
>  * lspci - written by Isaac Dunham
> 
> USE_LSPCI(NEWTOY(lspci, "emkns:", TOYFLAG_USR|TOYFLAG_BIN))
> 
> config LSPCI
>   bool "lspci"
>   default n
>   help
>     usage: lspci [-ekmn]
> 
>     List PCI devices.
>     -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"
> 
> int do_lspci(struct dirtree *new)
> {
>   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;
>   dirfd = open(dname, O_RDONLY);
>   if (dirfd > 0) {
>     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) {
>         strcat(dname, "/driver");
>         if (readlink(dname, bufs->module, sizeof(bufs->module)) != -1)
>           driver = basename(bufs->module);
>       }
>       printf(fmt, new->name + 5, bufs->class, bufs->vendor, bufs->device, 
>                driver);
>     }
>   }
>   return 0;
> }
> 
> void lspci_main(void)
> {
>   dirtree_read("/sys/bus/pci/devices", do_lspci);
> }





More information about the Toybox mailing list