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.
This commit is contained in:
Poul-Henning Kamp 2000-09-09 11:39:59 +00:00
parent cb9c6f9887
commit 8d25eb2c3a
3 changed files with 55 additions and 12 deletions

View File

@ -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"

View File

@ -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,11 +88,24 @@ 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) {
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",
@ -100,6 +116,5 @@ devname(dev, type)
(type & S_IFMT) == S_IFCHR ? 'C' : 'B',
major(dev), minor(dev));
}
}
return (r);
}

View File

@ -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");