Module Name: src Committed By: christos Date: Fri Oct 19 02:49:52 UTC 2012
Modified Files: src/usr.bin/fstat: fstat.c Log Message: print major device numbers symbolically from kinfo_drivers To generate a diff of this commit: cvs rdiff -u -r1.98 -r1.99 src/usr.bin/fstat/fstat.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/usr.bin/fstat/fstat.c diff -u src/usr.bin/fstat/fstat.c:1.98 src/usr.bin/fstat/fstat.c:1.99 --- src/usr.bin/fstat/fstat.c:1.98 Thu Oct 18 22:11:25 2012 +++ src/usr.bin/fstat/fstat.c Thu Oct 18 22:49:52 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: fstat.c,v 1.98 2012/10/19 02:11:25 christos Exp $ */ +/* $NetBSD: fstat.c,v 1.99 2012/10/19 02:49:52 christos Exp $ */ /*- * Copyright (c) 1988, 1993 @@ -39,7 +39,7 @@ __COPYRIGHT("@(#) Copyright (c) 1988, 19 #if 0 static char sccsid[] = "@(#)fstat.c 8.3 (Berkeley) 5/2/95"; #else -__RCSID("$NetBSD: fstat.c,v 1.98 2012/10/19 02:11:25 christos Exp $"); +__RCSID("$NetBSD: fstat.c,v 1.99 2012/10/19 02:49:52 christos Exp $"); #endif #endif /* not lint */ @@ -177,6 +177,7 @@ static const char *vfilestat(struct vn static void vtrans(struct vnode *, int, int); static void ftrans(fdfile_t *, int); static void ptrans(struct file *, struct pipe *, int); +static void kdriver_init(void); int main(int argc, char **argv) @@ -234,6 +235,8 @@ main(int argc, char **argv) usage(); } + kdriver_init(); + if (*(argv += optind)) { for (; *argv; ++argv) { if (getfname(*argv)) @@ -314,6 +317,89 @@ pid_t Pid; break; \ } +static struct kinfo_drivers *kdriver; +static size_t kdriverlen; + +static int +kdriver_comp(const void *a, const void *b) +{ + const struct kinfo_drivers *ka = a; + const struct kinfo_drivers *kb = b; + int kac = ka->d_cmajor == -1 ? 0 : ka->d_cmajor; + int kbc = kb->d_cmajor == -1 ? 0 : kb->d_cmajor; + int kab = ka->d_bmajor == -1 ? 0 : ka->d_bmajor; + int kbb = kb->d_bmajor == -1 ? 0 : kb->d_bmajor; + int c = kac - kbc; + if (c == 0) + return kab - kbb; + else + return c; +} + +static const char * +kdriver_search(int type, dev_t num) +{ + struct kinfo_drivers k, *kp; + static char buf[64]; + + if (nflg) + goto out; + + if (type == VBLK) { + k.d_bmajor = num; + k.d_cmajor = -1; + } else { + k.d_bmajor = -1; + k.d_cmajor = num; + } + kp = bsearch(&k, kdriver, kdriverlen, sizeof(*kdriver), kdriver_comp); + if (kp) + return kp->d_name; +out: + snprintf(buf, sizeof(buf), "%llu", (unsigned long long)num); + return buf; +} + + +static void +kdriver_init(void) +{ + size_t sz; + int error; + static const int name[2] = { CTL_KERN, KERN_DRIVERS }; + + error = sysctl(name, __arraycount(name), NULL, &sz, NULL, 0); + if (error == -1) { + warn("sysctl kern.drivers"); + return; + } + + if (sz % sizeof(*kdriver)) { + warnx("bad size %zu for kern.drivers", sz); + return; + } + + kdriver = malloc(sz); + if (kdriver == NULL) { + warn("malloc"); + return; + } + + error = sysctl(name, __arraycount(name), kdriver, &sz, NULL, 0); + if (error == -1) { + warn("sysctl kern.drivers"); + return; + } + + kdriverlen = sz / sizeof(*kdriver); + qsort(kdriver, kdriverlen, sizeof(*kdriver), kdriver_comp); +#ifdef DEBUG + for (size_t i = 0; i < kdriverlen; i++) + printf("%d %d %s\n", kdriver[i].d_cmajor, kdriver[i].d_bmajor, + kdriver[i].d_name); +#endif +} + /* * print open files attributed to this process */ @@ -559,8 +645,8 @@ vtrans(struct vnode *vp, int i, int flag if (nflg || ((name = devname(fst.rdev, vn.v_type == VCHR ? S_IFCHR : S_IFBLK)) == NULL)) - (void)printf(" %2llu,%-2llu", - (unsigned long long)major(fst.rdev), + (void)printf(" %s,%-2llu", + kdriver_search(vn.v_type, major(fst.rdev)), (unsigned long long)minor(fst.rdev)); else (void)printf(" %6s", name);