libc/sysctl: Fix the user.* branch.
authorSascha Wildner <saw@online.de>
Thu, 24 Sep 2015 12:54:00 +0000 (14:54 +0200)
committerSascha Wildner <saw@online.de>
Thu, 24 Sep 2015 12:54:00 +0000 (14:54 +0200)
This is a combination of FreeBSD's r285188 and more work by myself.
After r285188, FreeBSD still has issues with most user.posix2_* values
(due to a leading _ missing in the define names; they also need to be
checked for being > 0).

Partially-taken-from: FreeBSD

lib/libc/gen/sysctl.c
sys/sys/sysctl.h

index c96f4a9..0397e4b 100644 (file)
@@ -48,9 +48,21 @@ sysctl(const int *name, u_int namelen, void *oldp, size_t *oldlenp,
     const void *newp, size_t newlen)
 {
        int retval;
+       size_t orig_oldlen;
 
+       orig_oldlen = oldlenp ? *oldlenp : 0;
        retval = __sysctl(name, namelen, oldp, oldlenp, newp, newlen);
-       if (retval != -1 || errno != ENOENT || name[0] != CTL_USER)
+       /*
+        * All valid names under CTL_USER have a dummy entry in the sysctl
+        * tree (to support name lookups and enumerations) with an
+        * empty/zero value, and the true value is supplied by this routine.
+        * For all such names, __sysctl() is used solely to validate the
+        * name.
+        *
+        * Return here unless there was a successful lookup for a CTL_USER
+        * name.
+        */
+       if (retval || name[0] != CTL_USER)
                return (retval);
 
        if (newp != NULL) {
@@ -64,7 +76,7 @@ sysctl(const int *name, u_int namelen, void *oldp, size_t *oldlenp,
 
        switch (name[1]) {
        case USER_CS_PATH:
-               if (oldp && *oldlenp < sizeof(_PATH_STDPATH)) {
+               if (oldp && orig_oldlen < sizeof(_PATH_STDPATH)) {
                        errno = ENOMEM;
                        return -1;
                }
@@ -111,56 +123,56 @@ sysctl(const int *name, u_int namelen, void *oldp, size_t *oldlenp,
                *(int *)oldp = _POSIX2_VERSION;
                return (0);
        case USER_POSIX2_C_BIND:
-#ifdef POSIX2_C_BIND
+#if _POSIX2_C_BIND > 0
                *(int *)oldp = 1;
 #else
                *(int *)oldp = 0;
 #endif
                return (0);
        case USER_POSIX2_C_DEV:
-#ifdef POSIX2_C_DEV
+#if _POSIX2_C_DEV > 0
                *(int *)oldp = 1;
 #else
                *(int *)oldp = 0;
 #endif
                return (0);
        case USER_POSIX2_CHAR_TERM:
-#ifdef POSIX2_CHAR_TERM
+#if _POSIX2_CHAR_TERM > 0
                *(int *)oldp = 1;
 #else
                *(int *)oldp = 0;
 #endif
                return (0);
        case USER_POSIX2_FORT_DEV:
-#ifdef POSIX2_FORT_DEV
+#if _POSIX2_FORT_DEV > 0
                *(int *)oldp = 1;
 #else
                *(int *)oldp = 0;
 #endif
                return (0);
        case USER_POSIX2_FORT_RUN:
-#ifdef POSIX2_FORT_RUN
+#if _POSIX2_FORT_RUN > 0
                *(int *)oldp = 1;
 #else
                *(int *)oldp = 0;
 #endif
                return (0);
        case USER_POSIX2_LOCALEDEF:
-#ifdef POSIX2_LOCALEDEF
+#if _POSIX2_LOCALEDEF > 0
                *(int *)oldp = 1;
 #else
                *(int *)oldp = 0;
 #endif
                return (0);
        case USER_POSIX2_SW_DEV:
-#ifdef POSIX2_SW_DEV
+#if _POSIX2_SW_DEV > 0
                *(int *)oldp = 1;
 #else
                *(int *)oldp = 0;
 #endif
                return (0);
        case USER_POSIX2_UPE:
-#ifdef POSIX2_UPE
+#if _POSIX2_UPE > 0
                *(int *)oldp = 1;
 #else
                *(int *)oldp = 0;
index e1b09b4..ff9064d 100644 (file)
@@ -533,17 +533,17 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry);
 #define        USER_EXPR_NEST_MAX       7      /* int: EXPR_NEST_MAX */
 #define        USER_LINE_MAX            8      /* int: LINE_MAX */
 #define        USER_RE_DUP_MAX          9      /* int: RE_DUP_MAX */
-#define        USER_POSIX2_VERSION     10      /* int: POSIX2_VERSION */
-#define        USER_POSIX2_C_BIND      11      /* int: POSIX2_C_BIND */
-#define        USER_POSIX2_C_DEV       12      /* int: POSIX2_C_DEV */
-#define        USER_POSIX2_CHAR_TERM   13      /* int: POSIX2_CHAR_TERM */
-#define        USER_POSIX2_FORT_DEV    14      /* int: POSIX2_FORT_DEV */
-#define        USER_POSIX2_FORT_RUN    15      /* int: POSIX2_FORT_RUN */
-#define        USER_POSIX2_LOCALEDEF   16      /* int: POSIX2_LOCALEDEF */
-#define        USER_POSIX2_SW_DEV      17      /* int: POSIX2_SW_DEV */
-#define        USER_POSIX2_UPE         18      /* int: POSIX2_UPE */
-#define        USER_STREAM_MAX         19      /* int: POSIX2_STREAM_MAX */
-#define        USER_TZNAME_MAX         20      /* int: POSIX2_TZNAME_MAX */
+#define        USER_POSIX2_VERSION     10      /* int: _POSIX2_VERSION */
+#define        USER_POSIX2_C_BIND      11      /* int: _POSIX2_C_BIND */
+#define        USER_POSIX2_C_DEV       12      /* int: _POSIX2_C_DEV */
+#define        USER_POSIX2_CHAR_TERM   13      /* int: _POSIX2_CHAR_TERM */
+#define        USER_POSIX2_FORT_DEV    14      /* int: _POSIX2_FORT_DEV */
+#define        USER_POSIX2_FORT_RUN    15      /* int: _POSIX2_FORT_RUN */
+#define        USER_POSIX2_LOCALEDEF   16      /* int: _POSIX2_LOCALEDEF */
+#define        USER_POSIX2_SW_DEV      17      /* int: _POSIX2_SW_DEV */
+#define        USER_POSIX2_UPE         18      /* int: _POSIX2_UPE */
+#define        USER_STREAM_MAX         19      /* int: _POSIX2_STREAM_MAX */
+#define        USER_TZNAME_MAX         20      /* int: _POSIX2_TZNAME_MAX */
 #define        USER_MAXID              21      /* number of valid user ids */
 
 #define        CTL_USER_NAMES { \