Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src The new sysctl query interface returns the same information ...
details: https://anonhg.NetBSD.org/src/rev/d5716c03062b
branches: trunk
changeset: 559830:d5716c03062b
user: atatat <atatat%NetBSD.org@localhost>
date: Wed Mar 24 16:34:34 2004 +0000
description:
The new sysctl query interface returns the same information as the old
one, but you must pass in an empty node that indicates the version
you're using.
diffstat:
lib/libc/gen/sysctl.c | 63 ++++++++++++++++++---
sbin/sysctl/sysctlutil.c | 16 +++-
sys/kern/kern_sysctl.c | 139 +++++++++++++++++++++++++++++++++++-----------
3 files changed, 171 insertions(+), 47 deletions(-)
diffs (truncated from 422 to 300 lines):
diff -r 74e35663b105 -r d5716c03062b lib/libc/gen/sysctl.c
--- a/lib/libc/gen/sysctl.c Wed Mar 24 16:34:29 2004 +0000
+++ b/lib/libc/gen/sysctl.c Wed Mar 24 16:34:34 2004 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: sysctl.c,v 1.17 2004/03/24 16:29:10 atatat Exp $ */
+/* $NetBSD: sysctl.c,v 1.18 2004/03/24 16:34:34 atatat Exp $ */
/*-
* Copyright (c) 1993
@@ -34,7 +34,7 @@
#if 0
static char sccsid[] = "@(#)sysctl.c 8.2 (Berkeley) 1/4/94";
#else
-__RCSID("$NetBSD: sysctl.c,v 1.17 2004/03/24 16:29:10 atatat Exp $");
+__RCSID("$NetBSD: sysctl.c,v 1.18 2004/03/24 16:34:34 atatat Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@@ -58,6 +58,12 @@
*/
static int user_sysctl(int *, u_int, void *, size_t *, const void *, size_t);
+/*
+ * copies out individual nodes taking target version into account
+ */
+static size_t __cvt_node_out(uint, const struct sysctlnode *, void **,
+ size_t *);
+
#include <stdlib.h>
int
@@ -129,7 +135,7 @@
.sysctl_size = sizeof(_PATH_STDPATH),
.sysctl_name = "cs_path",
.sysctl_num = USER_CS_PATH,
- .sysctl_un = { .scu_data = _PATH_STDPATH, },
+ .sysctl_data = _PATH_STDPATH,
},
_INT("bc_base_max", USER_BC_BASE_MAX, BC_BASE_MAX),
_INT("bc_dim_max", USER_BC_DIM_MAX, BC_DIM_MAX),
@@ -198,20 +204,35 @@
/*
* none of these nodes are writable and they're all terminal (for now)
*/
- if (newp != NULL || newlen != 0)
- return (EPERM);
if (namelen != 1)
return (EINVAL);
l = *oldlenp;
if (name[0] == CTL_QUERY) {
- sz = clen * sizeof(struct sysctlnode);
- l = MIN(l, sz);
- if (oldp != NULL)
- memcpy(oldp, &sysctl_usermib[0], l);
+ uint v;
+ node = newp;
+ if (node == NULL) {
+ v = SYSCTL_VERS_0;
+ newlen = sizeof(struct sysctlnode);
+ }
+ else if (SYSCTL_VERS(node->sysctl_flags) == SYSCTL_VERS_0 &&
+ newlen == sizeof(struct sysctlnode))
+ v = SYSCTL_VERS_0;
+ else
+ return (EINVAL);
+
+ sz = 0;
+ for (ni = 0; ni < clen; ni++)
+ sz += __cvt_node_out(v, &sysctl_usermib[ni], &oldp, &l);
*oldlenp = sz;
return (0);
}
+
+ /*
+ * none of these nodes are writable
+ */
+ if (newp != NULL || newlen != 0)
+ return (EPERM);
node = &sysctl_usermib[0];
for (ni = 0; ni < clen; ni++)
@@ -243,3 +264,27 @@
return (0);
}
+
+static size_t
+__cvt_node_out(uint v, const struct sysctlnode *n, void **o, size_t *l)
+{
+ const void *src = n;
+ size_t sz;
+
+ switch (v) {
+ case SYSCTL_VERSION:
+ sz = sizeof(struct sysctlnode);
+ break;
+ default:
+ sz = 0;
+ break;
+ }
+
+ if (sz > 0 && *o != NULL && *l >= sz) {
+ memcpy(*o, src, sz);
+ *o = sz + (caddr_t)*o;
+ *l -= sz;
+ }
+
+ return(sz);
+}
diff -r 74e35663b105 -r d5716c03062b sbin/sysctl/sysctlutil.c
--- a/sbin/sysctl/sysctlutil.c Wed Mar 24 16:34:29 2004 +0000
+++ b/sbin/sysctl/sysctlutil.c Wed Mar 24 16:34:34 2004 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: sysctlutil.c,v 1.5 2004/03/24 15:34:56 atatat Exp $ */
+/* $NetBSD: sysctlutil.c,v 1.6 2004/03/24 16:34:34 atatat Exp $ */
#include <sys/param.h>
#define __USE_NEW_SYSCTL
@@ -59,6 +59,7 @@
int
learn_tree(int *name, u_int namelen, struct sysctlnode *pnode)
{
+ struct sysctlnode qnode;
int rc;
size_t sz;
@@ -82,7 +83,10 @@
name[namelen] = CTL_QUERY;
pnode->sysctl_clen = 0;
pnode->sysctl_csize = 0;
- rc = sysctl(name, namelen + 1, pnode->sysctl_child, &sz, NULL, 0);
+ memset(&qnode, 0, sizeof(qnode));
+ qnode.sysctl_flags = SYSCTL_VERSION;
+ rc = sysctl(name, namelen + 1, pnode->sysctl_child, &sz,
+ &qnode, sizeof(qnode));
if (sz == 0) {
free(pnode->sysctl_child);
pnode->sysctl_child = NULL;
@@ -103,7 +107,7 @@
return (-1);
rc = sysctl(name, namelen + 1, pnode->sysctl_child, &sz,
- NULL, 0);
+ &qnode, sizeof(qnode));
if (rc) {
free(pnode->sysctl_child);
pnode->sysctl_child = NULL;
@@ -178,7 +182,7 @@
static void
relearnhead(void)
{
- struct sysctlnode *h, *i, *o;
+ struct sysctlnode *h, *i, *o, qnode;
size_t si, so;
int rc, name, nlen, olen, ni, oi, t;
@@ -197,10 +201,12 @@
si = 0;
so = sysctl_mibroot.sysctl_clen * sizeof(struct sysctlnode);
name = CTL_QUERY;
+ memset(&qnode, 0, sizeof(qnode));
+ qnode.sysctl_flags = SYSCTL_VERSION;
do {
si = so;
h = malloc(si);
- rc = sysctl(&name, 1, h, &so, NULL, 0);
+ rc = sysctl(&name, 1, h, &so, &qnode, sizeof(qnode));
if (rc == -1 && errno != ENOMEM)
return;
if (si < so)
diff -r 74e35663b105 -r d5716c03062b sys/kern/kern_sysctl.c
--- a/sys/kern/kern_sysctl.c Wed Mar 24 16:34:29 2004 +0000
+++ b/sys/kern/kern_sysctl.c Wed Mar 24 16:34:34 2004 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_sysctl.c,v 1.161 2004/03/24 15:34:53 atatat Exp $ */
+/* $NetBSD: kern_sysctl.c,v 1.162 2004/03/24 16:34:34 atatat Exp $ */
/*-
* Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -75,7 +75,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_sysctl.c,v 1.161 2004/03/24 15:34:53 atatat Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_sysctl.c,v 1.162 2004/03/24 16:34:34 atatat Exp $");
#include "opt_defcorename.h"
#include "opt_insecure.h"
@@ -99,6 +99,11 @@
static int sysctl_alloc(struct sysctlnode *, int);
static int sysctl_realloc(struct sysctlnode *);
+static int sysctl_cvt_in(struct lwp *, int *, const void *, size_t,
+ struct sysctlnode *);
+static int sysctl_cvt_out(struct lwp *, int, const struct sysctlnode *,
+ void *, size_t, size_t *);
+
/*
* the "root" of the new sysctl tree
*/
@@ -565,17 +570,15 @@
int
sysctl_query(SYSCTLFN_ARGS)
{
- int error, ni, elim;
+ int error, ni, elim, v;
size_t out, left, t;
- struct sysctlnode *enode, *onode;
+ struct sysctlnode *enode, *onode, qnode;
if (SYSCTL_VERS(rnode->sysctl_flags) != SYSCTL_VERSION) {
printf("sysctl_query: rnode %p wrong version\n", rnode);
return (EINVAL);
}
- if (newp != NULL)
- return (EPERM);
if (SYSCTL_TYPE(rnode->sysctl_flags) != CTLTYPE_NODE)
return (ENOTDIR);
if (namelen != 1 || name[0] != CTL_QUERY)
@@ -588,6 +591,23 @@
enode = NULL;
/*
+ * translate the given request to a current node
+ */
+ error = sysctl_cvt_in(l, &v, newp, newlen, &qnode);
+ if (error)
+ return (error);
+
+ /*
+ * if the request specifies a version, check it
+ */
+ if (qnode.sysctl_ver != 0) {
+ enode = (struct sysctlnode *)rnode; /* discard const */
+ if (qnode.sysctl_ver != enode->sysctl_ver &&
+ qnode.sysctl_ver != sysctl_rootof(enode)->sysctl_ver)
+ return (EINVAL);
+ }
+
+ /*
* process has overlay tree
*/
if (l && l->l_proc->p_emul->e_sysctlovly) {
@@ -607,7 +627,6 @@
}
for (ni = 0; ni < rnode->sysctl_clen; ni++) {
- t = MIN(left, sizeof(struct sysctlnode));
onode = &rnode->sysctl_child[ni];
if (enode && enode->sysctl_num == onode->sysctl_num) {
if (SYSCTL_TYPE(enode->sysctl_flags) != CTLTYPE_NODE)
@@ -617,12 +636,13 @@
else
enode = NULL;
}
- if (oldp != NULL && t > 0)
- error = sysctl_copyout(l, onode, (char*)oldp + out, t);
+ error = sysctl_cvt_out(l, v, onode, oldp, left, &t);
if (error)
return (error);
- out += sizeof(struct sysctlnode);
- left -= t;
+ if (oldp != NULL)
+ oldp = (char*)oldp + t;
+ out += t;
+ left -= MIN(left, t);
}
/*
@@ -651,7 +671,7 @@
sysctl_create(SYSCTLFN_RWARGS)
{
struct sysctlnode nnode, *node, *pnode;
- int error, ni, at, nm, type, sz, flags, rw, anum;
+ int error, ni, at, nm, type, sz, flags, rw, anum, v;
void *own;
error = 0;
@@ -704,9 +724,9 @@
return (ENOTDIR);
pnode = rnode;
- if (newp == NULL || newlen != sizeof(struct sysctlnode))
+ if (newp == NULL)
return (EINVAL);
- error = sysctl_copyin(l, newp, &nnode, MIN(sizeof(nnode), newlen));
+ error = sysctl_cvt_in(l, &v, newp, newlen, &nnode);
if (error)
return (error);
@@ -775,15 +795,12 @@
for (ni = at = 0; ni < pnode->sysctl_clen; ni++) {
if (nm == node[ni].sysctl_num ||
strcmp(nnode.sysctl_name, node[ni].sysctl_name) == 0) {
- if (oldp != NULL) {
- /*
- * ignore error here, since we
- * are already fixed on EEXIST
Home |
Main Index |
Thread Index |
Old Index