diff options
author | mdf <mdf@FreeBSD.org> | 2010-09-09 18:33:46 +0000 |
---|---|---|
committer | mdf <mdf@FreeBSD.org> | 2010-09-09 18:33:46 +0000 |
commit | bc5468425338dbee3cd3da7d6bc2a1290ba8d2ce (patch) | |
tree | fb245e2e8ce30565e64963b84e00c3b93d9bc280 /sys/kern/kern_sysctl.c | |
parent | a7b4070f1f143143442a97cffdf24fc59814851f (diff) | |
download | FreeBSD-src-bc5468425338dbee3cd3da7d6bc2a1290ba8d2ce.zip FreeBSD-src-bc5468425338dbee3cd3da7d6bc2a1290ba8d2ce.tar.gz |
Add a drain function for struct sysctl_req, and use it for a variety of
handlers, some of which had to do awkward things to get a large enough
FIXEDLEN buffer.
Note that some sysctl handlers were explicitly outputting a trailing NUL
byte. This behaviour was preserved, though it should not be necessary.
Reviewed by: phk
Diffstat (limited to 'sys/kern/kern_sysctl.c')
-rw-r--r-- | sys/kern/kern_sysctl.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index b83502c..49ccc50 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$"); #include <sys/jail.h> #include <sys/lock.h> #include <sys/mutex.h> +#include <sys/sbuf.h> #include <sys/sx.h> #include <sys/sysproto.h> #include <sys/uio.h> @@ -1544,3 +1545,30 @@ userland_sysctl(struct thread *td, int *name, u_int namelen, void *old, } return (error); } + +/* + * Drain into a sysctl struct. The user buffer must be wired. + */ +static int +sbuf_sysctl_drain(void *arg, const char *data, int len) +{ + struct sysctl_req *req = arg; + int error; + + error = SYSCTL_OUT(req, data, len); + KASSERT(error >= 0, ("Got unexpected negative value %d", error)); + return (error == 0 ? len : -error); +} + +struct sbuf * +sbuf_new_for_sysctl(struct sbuf *s, char *buf, int length, + struct sysctl_req *req) +{ + + /* Wire the user buffer, so we can write without blocking. */ + sysctl_wire_old_buffer(req, 0); + + s = sbuf_new(s, buf, length, SBUF_FIXEDLEN); + sbuf_set_drain(s, sbuf_sysctl_drain, req); + return (s); +} |