Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/lib/libc/gen Adapt userland sysctl goop to new world order, ...
details: https://anonhg.NetBSD.org/src/rev/ebae91d4a17e
branches: trunk
changeset: 555942:ebae91d4a17e
user: atatat <atatat%NetBSD.org@localhost>
date: Thu Dec 04 19:40:55 2003 +0000
description:
Adapt userland sysctl goop to new world order, permitting dynamic
discovery.
diffstat:
lib/libc/gen/sysctl.c | 275 +++++++++++++++++++++++++++++--------------------
1 files changed, 162 insertions(+), 113 deletions(-)
diffs (truncated from 331 to 300 lines):
diff -r f7d9f017dba5 -r ebae91d4a17e lib/libc/gen/sysctl.c
--- a/lib/libc/gen/sysctl.c Thu Dec 04 19:39:57 2003 +0000
+++ b/lib/libc/gen/sysctl.c Thu Dec 04 19:40:55 2003 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: sysctl.c,v 1.13 2003/08/07 16:42:57 agc Exp $ */
+/* $NetBSD: sysctl.c,v 1.14 2003/12/04 19:40:55 atatat Exp $ */
/*-
* Copyright (c) 1993
@@ -34,17 +34,16 @@
#if 0
static char sccsid[] = "@(#)sysctl.c 8.2 (Berkeley) 1/4/94";
#else
-__RCSID("$NetBSD: sysctl.c,v 1.13 2003/08/07 16:42:57 agc Exp $");
+__RCSID("$NetBSD: sysctl.c,v 1.14 2003/12/04 19:40:55 atatat Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
#include "namespace.h"
#include <sys/param.h>
+#define __USE_NEW_SYSCTL
#include <sys/sysctl.h>
-#include <assert.h>
#include <errno.h>
-#include <limits.h>
#include <paths.h>
#include <stdio.h>
#include <string.h>
@@ -55,6 +54,13 @@
__weak_alias(sysctl,_sysctl)
#endif
+/*
+ * handles requests off the user subtree
+ */
+static int user_sysctl(int *, u_int, void *, size_t *, const void *, size_t);
+
+#include <stdlib.h>
+
int
sysctl(name, namelen, oldp, oldlenp, newp, newlen)
int *name;
@@ -63,135 +69,178 @@
const void *newp;
size_t *oldlenp, newlen;
{
-
- _DIAGASSERT(name != NULL);
+ size_t oldlen, savelen;
+ int error;
if (name[0] != CTL_USER)
/* LINTED will fix when sysctl interface gets corrected */
+ /* XXX when will that be? */
return (__sysctl(name, namelen, oldp, oldlenp,
- (void *)newp, newlen));
+ (void *)newp, newlen));
- if (newp != NULL) {
- errno = EPERM;
- return (-1);
- }
- if (namelen != 2) {
- errno = EINVAL;
+ oldlen = (oldlenp == NULL) ? 0 : *oldlenp;
+ savelen = oldlen;
+ error = user_sysctl(name + 1, namelen - 1, oldp, &oldlen, newp, newlen);
+
+ if (error != 0) {
+ errno = error;
return (-1);
}
- switch (name[1]) {
- case USER_CS_PATH:
- if (oldp && *oldlenp < sizeof(_PATH_STDPATH))
- return (ENOMEM);
- *oldlenp = sizeof(_PATH_STDPATH);
- if (oldp != NULL)
- memmove(oldp, _PATH_STDPATH, sizeof(_PATH_STDPATH));
- return (0);
+ if (oldlenp != NULL) {
+ *oldlenp = oldlen;
+ if (oldp != NULL && oldlen > savelen) {
+ errno = ENOMEM;
+ return (-1);
+ }
}
- if (oldp && *oldlenp < sizeof(int))
- return (ENOMEM);
- *oldlenp = sizeof(int);
- if (oldp == NULL)
- return (0);
+ return (0);
+}
+
+static int
+user_sysctl(name, namelen, oldp, oldlenp, newp, newlen)
+ int *name;
+ unsigned int namelen;
+ void *oldp;
+ const void *newp;
+ size_t *oldlenp, newlen;
+{
+#define _INT(s, n, v) { \
+ .sysctl_flags = SYSCTL_IMMEDIATE|SYSCTL_PERMANENT|SYSCTL_READONLY| \
+ SYSCTL_TYPE(CTLTYPE_INT), \
+ .sysctl_size = sizeof(int), \
+ .sysctl_name = (s), \
+ .sysctl_num = (n), \
+ .sysctl_un = { .scu_idata = (v), }, }
- switch (name[1]) {
- case USER_BC_BASE_MAX:
- *(int *)oldp = BC_BASE_MAX;
- return (0);
- case USER_BC_DIM_MAX:
- *(int *)oldp = BC_DIM_MAX;
- return (0);
- case USER_BC_SCALE_MAX:
- *(int *)oldp = BC_SCALE_MAX;
- return (0);
- case USER_BC_STRING_MAX:
- *(int *)oldp = BC_STRING_MAX;
- return (0);
- case USER_COLL_WEIGHTS_MAX:
- *(int *)oldp = COLL_WEIGHTS_MAX;
- return (0);
- case USER_EXPR_NEST_MAX:
- *(int *)oldp = EXPR_NEST_MAX;
- return (0);
- case USER_LINE_MAX:
- *(int *)oldp = LINE_MAX;
- return (0);
- case USER_RE_DUP_MAX:
- *(int *)oldp = RE_DUP_MAX;
- return (0);
- case USER_POSIX2_VERSION:
- *(int *)oldp = _POSIX2_VERSION;
- return (0);
- case USER_POSIX2_C_BIND:
+ /*
+ * the nodes under the "user" node
+ */
+ static const struct sysctlnode sysctl_usermib[] = {
+#if defined(lint)
+ /*
+ * lint doesn't like my initializers
+ */
+ 0
+#else /* !lint */
+ {
+ .sysctl_flags = SYSCTL_READONLY|SYSCTL_PERMANENT|
+ SYSCTL_TYPE(CTLTYPE_STRING),
+ .sysctl_size = sizeof(_PATH_STDPATH),
+ .sysctl_name = "cs_path",
+ .sysctl_num = USER_CS_PATH,
+ .sysctl_un = { .scu_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),
+ _INT("bc_scale_max", USER_BC_SCALE_MAX, BC_SCALE_MAX),
+ _INT("bc_string_max", USER_BC_STRING_MAX, BC_STRING_MAX),
+ _INT("coll_weights_max", USER_COLL_WEIGHTS_MAX,
+ COLL_WEIGHTS_MAX),
+ _INT("expr_nest_max", USER_EXPR_NEST_MAX, EXPR_NEST_MAX),
+ _INT("line_max", USER_LINE_MAX, LINE_MAX),
+ _INT("re_dup_max", USER_RE_DUP_MAX, RE_DUP_MAX),
+ _INT("posix2_version", USER_POSIX2_VERSION, _POSIX2_VERSION),
#ifdef POSIX2_C_BIND
- *(int *)oldp = 1;
+ _INT("posix2_c_bind", USER_POSIX2_C_BIND, 1),
#else
- *(int *)oldp = 0;
+ _INT("posix2_c_bind", USER_POSIX2_C_BIND, 0),
+#endif
+#ifdef POSIX2_C_DEV
+ _INT("posix2_c_dev", USER_POSIX2_C_DEV, 1),
+#else
+ _INT("posix2_c_dev", USER_POSIX2_C_DEV, 0),
#endif
- return (0);
- case USER_POSIX2_C_DEV:
-#ifdef POSIX2_C_DEV
- *(int *)oldp = 1;
+#ifdef POSIX2_CHAR_TERM
+ _INT("posix2_char_term", USER_POSIX2_CHAR_TERM, 1),
+#else
+ _INT("posix2_char_term", USER_POSIX2_CHAR_TERM, 0),
+#endif
+#ifdef POSIX2_FORT_DEV
+ _INT("posix2_fort_dev", USER_POSIX2_FORT_DEV, 1),
#else
- *(int *)oldp = 0;
+ _INT("posix2_fort_dev", USER_POSIX2_FORT_DEV, 0),
#endif
- return (0);
- case USER_POSIX2_CHAR_TERM:
-#ifdef POSIX2_CHAR_TERM
- *(int *)oldp = 1;
+#ifdef POSIX2_FORT_RUN
+ _INT("posix2_fort_run", USER_POSIX2_FORT_RUN, 1),
+#else
+ _INT("posix2_fort_run", USER_POSIX2_FORT_RUN, 0),
+#endif
+#ifdef POSIX2_LOCALEDEF
+ _INT("posix2_localedef", USER_POSIX2_LOCALEDEF, 1),
#else
- *(int *)oldp = 0;
+ _INT("posix2_localedef", USER_POSIX2_LOCALEDEF, 0),
#endif
- return (0);
- case USER_POSIX2_FORT_DEV:
-#ifdef POSIX2_FORT_DEV
- *(int *)oldp = 1;
+#ifdef POSIX2_SW_DEV
+ _INT("posix2_sw_dev", USER_POSIX2_SW_DEV, 1),
#else
- *(int *)oldp = 0;
+ _INT("posix2_sw_dev", USER_POSIX2_SW_DEV, 0),
+#endif
+#ifdef POSIX2_UPE
+ _INT("posix2_upe", USER_POSIX2_UPE, 1),
+#else
+ _INT("posix2_upe", USER_POSIX2_UPE, 0),
#endif
- return (0);
- case USER_POSIX2_FORT_RUN:
-#ifdef POSIX2_FORT_RUN
- *(int *)oldp = 1;
-#else
- *(int *)oldp = 0;
-#endif
- return (0);
- case USER_POSIX2_LOCALEDEF:
-#ifdef POSIX2_LOCALEDEF
- *(int *)oldp = 1;
-#else
- *(int *)oldp = 0;
-#endif
+ _INT("stream_max", USER_STREAM_MAX, FOPEN_MAX),
+ _INT("tzname_max", USER_TZNAME_MAX, NAME_MAX),
+ _INT("atexit_max", USER_ATEXIT_MAX, -1),
+#endif /* !lint */
+ };
+#undef _INT
+
+ static const int clen = sizeof(sysctl_usermib) /
+ sizeof(sysctl_usermib[0]);
+
+ const struct sysctlnode *node;
+ int ni;
+ size_t l, sz;
+
+ /*
+ * 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);
+ *oldlenp = sz;
return (0);
- case USER_POSIX2_SW_DEV:
-#ifdef POSIX2_SW_DEV
- *(int *)oldp = 1;
-#else
- *(int *)oldp = 0;
-#endif
- return (0);
- case USER_POSIX2_UPE:
-#ifdef POSIX2_UPE
- *(int *)oldp = 1;
-#else
- *(int *)oldp = 0;
-#endif
- return (0);
- case USER_STREAM_MAX:
- *(int *)oldp = FOPEN_MAX;
- return (0);
- case USER_TZNAME_MAX:
- *(int *)oldp = NAME_MAX;
- return (0);
- case USER_ATEXIT_MAX:
- *(int *)oldp = -1; /* ANSI C minimum provided; not limited */
- return (0);
- default:
- errno = EINVAL;
- return (-1);
}
- /* NOTREACHED */
Home |
Main Index |
Thread Index |
Old Index