view toys/pending/lspci.c @ 978:6d3c39cb8a9d

Cleanup renice and implement '|' (required option) in argument parsing.
author Rob Landley <rob@landley.net>
date Wed, 31 Jul 2013 03:24:58 -0500
parents f84dd3473233
children 8caeba551a28
line wrap: on
line source

/*
 * 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 = ((toys.optflags & FLAG_e) && (p == toybuf)) ? 8 : 6;
      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);
}