From 8d25eb2c3a292113d6fd5b0f35ae3e3a40870a4f Mon Sep 17 00:00:00 2001 From: Poul-Henning Kamp Date: Sat, 9 Sep 2000 11:39:59 +0000 Subject: [PATCH] Add code to devname(3) so it can find the names of devices which were not present when dev_mkdb(8) was run. First the dev_mkdb(8) database is searched, this caters for non-DEVFS cases where people have renamed a device. If that fails we ask the kernel using sysctl kern.devname if the device driver has put a name in the dev_t. This covers DEVFS cloned devices. If that also fails we format a string which isn't entirely useless. --- lib/libc/gen/devname.3 | 1 + lib/libc/gen/devname.c | 39 +++++++++++++++++++++++++++------------ sys/kern/kern_conf.c | 27 +++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 12 deletions(-) diff --git a/lib/libc/gen/devname.3 b/lib/libc/gen/devname.3 index b63d6c99996..2f39c80e9cd 100644 --- a/lib/libc/gen/devname.3 +++ b/lib/libc/gen/devname.3 @@ -41,6 +41,7 @@ .Sh LIBRARY .Lb libc .Sh SYNOPSIS +.Fd #include .Fd #include .Ft char * .Fn devname "dev_t dev" "mode_t type" diff --git a/lib/libc/gen/devname.c b/lib/libc/gen/devname.c index 898c8e88d10..7d84037917a 100644 --- a/lib/libc/gen/devname.c +++ b/lib/libc/gen/devname.c @@ -29,6 +29,8 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. + * + * $FreeBSD$ */ #if defined(LIBC_SCCS) && !defined(lint) @@ -36,6 +38,7 @@ static char sccsid[] = "@(#)devname.c 8.2 (Berkeley) 4/29/95"; #endif /* LIBC_SCCS and not lint */ #include +#include #include #include @@ -85,21 +88,33 @@ devname(dev, type) dev_t dev; mode_t type; { - static char buf[20]; + static char buf[30]; /* XXX: pick up from */ + int i, j; char *r; + /* First check the DB file. */ r = xdevname(dev, type); - if (!r) { - r = buf; - if (minor(dev) > 255) { - sprintf(buf, "#%c%d:0x%x", - (type & S_IFMT) == S_IFCHR ? 'C' : 'B', - major(dev), minor(dev)); - } else { - sprintf(buf, "#%c%d:%d", - (type & S_IFMT) == S_IFCHR ? 'C' : 'B', - major(dev), minor(dev)); - } + if (r != NULL) + return (r); + + /* Then ask the kernel. */ + if ((type & S_IFMT) == S_IFCHR) { + j = sizeof(buf); + i = sysctlbyname("kern.devname", buf, &j, &dev, sizeof (dev)); + if (i == 0) + return (buf); + } + + /* Finally just format it */ + r = buf; + if (minor(dev) > 255) { + sprintf(buf, "#%c%d:0x%x", + (type & S_IFMT) == S_IFCHR ? 'C' : 'B', + major(dev), minor(dev)); + } else { + sprintf(buf, "#%c%d:%d", + (type & S_IFMT) == S_IFCHR ? 'C' : 'B', + major(dev), minor(dev)); } return (r); } diff --git a/sys/kern/kern_conf.c b/sys/kern/kern_conf.c index fb15afdfcea..404f6f430e1 100644 --- a/sys/kern/kern_conf.c +++ b/sys/kern/kern_conf.c @@ -406,3 +406,30 @@ dev_stdclone(char *name, char **namep, char *stem, int *unit) return (2); return (1); } + +/* + * Helper sysctl for devname(3). We're given a {u}dev_t and return + * the name, if any, registered by the device driver. + */ +static int +sysctl_devname(SYSCTL_HANDLER_ARGS) +{ + int error; + udev_t ud; + dev_t dev; + + error = SYSCTL_IN(req, &ud, sizeof (ud)); + if (error) + return (error); + dev = makedev(umajor(ud), uminor(ud)); + if (dev->si_name[0] == '\0') + error = ENOENT; + else + error = SYSCTL_OUT(req, dev->si_name, strlen(dev->si_name) + 1); + freedev(dev); + return (error); +} + +SYSCTL_PROC(_kern, OID_AUTO, devname, CTLTYPE_OPAQUE|CTLFLAG_RW, + NULL, 0, sysctl_devname, "", "devname(3) handler"); +