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:
parent
cb9c6f9887
commit
8d25eb2c3a
@ -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"
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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");
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user