summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/libc/gen/devname.31
-rw-r--r--lib/libc/gen/devname.c39
-rw-r--r--sys/kern/kern_conf.c27
3 files changed, 55 insertions, 12 deletions
diff --git a/lib/libc/gen/devname.3 b/lib/libc/gen/devname.3
index b63d6c9..2f39c80 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 <sys/stat.h>
.Fd #include <stdlib.h>
.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 898c8e8..7d84037 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 <sys/types.h>
+#include <sys/sysctl.h>
#include <db.h>
#include <err.h>
@@ -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 <sys/conf.h> */
+ 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 fb15afd..404f6f4 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");
+
OpenPOWER on IntegriCloud