diff options
author | Hans Petter Selasky <hselasky@FreeBSD.org> | 2016-05-26 08:41:55 +0000 |
---|---|---|
committer | Hans Petter Selasky <hselasky@FreeBSD.org> | 2016-05-26 08:41:55 +0000 |
commit | 84e717c4cf7a88a51024de6636620bd4410cc6e1 (patch) | |
tree | cb243db106b02f1b384df6e20ed80b2006ca12f1 | |
parent | 6c6f602b53a7cfcc5ec9faea2f7e95f7aef72d52 (diff) |
Notes
-rw-r--r-- | sys/kern/kern_sysctl.c | 35 | ||||
-rw-r--r-- | sys/sys/sysctl.h | 19 |
2 files changed, 54 insertions, 0 deletions
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index 37dfff1419d8..5b8870f3b0f2 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -1181,6 +1181,41 @@ static SYSCTL_NODE(_sysctl, 5, oiddescr, CTLFLAG_RD|CTLFLAG_MPSAFE|CTLFLAG_CAPRD */ /* + * Handle a bool. + * Two cases: + * a variable: point arg1 at it. + * a constant: pass it in arg2. + */ + +int +sysctl_handle_bool(SYSCTL_HANDLER_ARGS) +{ + uint8_t temp; + int error; + + /* + * Attempt to get a coherent snapshot by making a copy of the data. + */ + if (arg1) + temp = *(bool *)arg1 ? 1 : 0; + else + temp = arg2 ? 1 : 0; + + error = SYSCTL_OUT(req, &temp, sizeof(temp)); + if (error || !req->newptr) + return (error); + + if (!arg1) + error = EPERM; + else { + error = SYSCTL_IN(req, &temp, sizeof(temp)); + if (!error) + *(bool *)arg1 = temp ? 1 : 0; + } + return (error); +} + +/* * Handle an int8_t, signed or unsigned. * Two cases: * a variable: point arg1 at it. diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h index 4590ef9f86e7..c7d8fdb11c0a 100644 --- a/sys/sys/sysctl.h +++ b/sys/sys/sysctl.h @@ -194,6 +194,7 @@ struct sysctl_oid { #define SYSCTL_OUT(r, p, l) (r->oldfunc)(r, p, l) #define SYSCTL_OUT_STR(r, p) (r->oldfunc)(r, p, strlen(p) + 1) +int sysctl_handle_bool(SYSCTL_HANDLER_ARGS); int sysctl_handle_8(SYSCTL_HANDLER_ARGS); int sysctl_handle_16(SYSCTL_HANDLER_ARGS); int sysctl_handle_32(SYSCTL_HANDLER_ARGS); @@ -329,6 +330,24 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry); __arg, len, sysctl_handle_string, "A", __DESCR(descr)); \ }) +/* Oid for a bool. If ptr is NULL, val is returned. */ +#define SYSCTL_NULL_BOOL_PTR ((bool *)NULL) +#define SYSCTL_BOOL(parent, nbr, name, access, ptr, val, descr) \ + SYSCTL_OID(parent, nbr, name, \ + CTLTYPE_U8 | CTLFLAG_MPSAFE | (access), \ + ptr, val, sysctl_handle_bool, "CU", descr); \ + CTASSERT(((access) & CTLTYPE) == 0 && \ + sizeof(bool) == sizeof(*(ptr))) + +#define SYSCTL_ADD_BOOL(ctx, parent, nbr, name, access, ptr, val, descr) \ +({ \ + bool *__ptr = (ptr); \ + CTASSERT(((access) & CTLTYPE) == 0); \ + sysctl_add_oid(ctx, parent, nbr, name, \ + CTLTYPE_U8 | CTLFLAG_MPSAFE | (access), \ + __ptr, val, sysctl_handle_bool, "CU", __DESCR(descr)); \ +}) + /* Oid for a signed 8-bit int. If ptr is NULL, val is returned. */ #define SYSCTL_NULL_S8_PTR ((int8_t *)NULL) #define SYSCTL_S8(parent, nbr, name, access, ptr, val, descr) \ |