Allow setting of variables of type dev_t by indicating the name of
a special file on the command line, eg: sysctl kern.dumpdev=/dev/ad1s1b In parse(), when a value is given for a CTLTYPE_QUAD variable, newval and newsize erroneously fail to be set because of an early "break". show_var() contains code that duplicates the functionality of the oidfmt() function. PR: 33151, 33150 Submitted by: Thomas Quinot <thomas@cuivre.fr.eu.org>
This commit is contained in:
parent
f3366cc25b
commit
d58f005463
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=88696
@ -49,6 +49,7 @@ static const char rcsid[] =
|
||||
#include <sys/stat.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
@ -66,6 +67,8 @@ static int show_var(int *, int);
|
||||
static int sysctl_all (int *oid, int len);
|
||||
static int name2oid(char *, int *);
|
||||
|
||||
static void set_T_dev_t (char *, void **, int *);
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
@ -156,7 +159,7 @@ parse(char *string)
|
||||
size_t newsize = 0;
|
||||
quad_t quadval;
|
||||
int mib[CTL_MAXNAME];
|
||||
char *cp, *bufp, buf[BUFSIZ];
|
||||
char *cp, *bufp, buf[BUFSIZ], fmt[BUFSIZ];
|
||||
u_int kind;
|
||||
|
||||
bufp = buf;
|
||||
@ -174,7 +177,7 @@ parse(char *string)
|
||||
if (len < 0)
|
||||
errx(1, "unknown oid '%s'", bufp);
|
||||
|
||||
if (oidfmt(mib, len, 0, &kind))
|
||||
if (oidfmt(mib, len, fmt, &kind))
|
||||
err(1, "couldn't find format of oid '%s'", bufp);
|
||||
|
||||
if (newval == NULL) {
|
||||
@ -216,11 +219,16 @@ parse(char *string)
|
||||
case CTLTYPE_STRING:
|
||||
break;
|
||||
case CTLTYPE_QUAD:
|
||||
break;
|
||||
sscanf(newval, "%qd", &quadval);
|
||||
newval = &quadval;
|
||||
newsize = sizeof(quadval);
|
||||
break;
|
||||
case CTLTYPE_OPAQUE:
|
||||
if (strcmp(fmt, "T,dev_t") == 0) {
|
||||
set_T_dev_t ((char*)newval, &newval, &newsize);
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
errx(1, "oid '%s' is type %d,"
|
||||
" cannot set that", bufp,
|
||||
@ -322,6 +330,27 @@ T_dev_t(int l2, void *p)
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
set_T_dev_t (char *path, void **val, int *size)
|
||||
{
|
||||
static struct stat statb;
|
||||
|
||||
if (strcmp(path, "none") && strcmp(path, "off")) {
|
||||
int rc = stat (path, &statb);
|
||||
if (rc) {
|
||||
err(1, "cannot stat %s", path);
|
||||
}
|
||||
|
||||
if (!S_ISCHR(statb.st_mode)) {
|
||||
errx(1, "must specify a device special file.");
|
||||
}
|
||||
} else {
|
||||
statb.st_rdev = NODEV;
|
||||
}
|
||||
*val = (char*) &statb.st_rdev;
|
||||
*size = sizeof statb.st_rdev;
|
||||
}
|
||||
|
||||
/*
|
||||
* These functions uses a presently undocumented interface to the kernel
|
||||
* to walk the tree and get the type so it can print the value.
|
||||
@ -437,16 +466,8 @@ show_var(int *oid, int nlen)
|
||||
return (0);
|
||||
}
|
||||
|
||||
qoid[1] = 4;
|
||||
j = sizeof(buf);
|
||||
i = sysctl(qoid, nlen + 2, buf, &j, 0, 0);
|
||||
if (i || !j)
|
||||
err(1, "sysctl fmt %d %d %d", i, j, errno);
|
||||
|
||||
kind = *(u_int *)buf;
|
||||
|
||||
fmt = (char *)(buf + sizeof(u_int));
|
||||
|
||||
fmt = buf;
|
||||
oidfmt(oid, nlen, fmt, &kind);
|
||||
p = val;
|
||||
switch (*fmt) {
|
||||
case 'A':
|
||||
|
Loading…
Reference in New Issue
Block a user