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