Author: cem
Date: Thu Oct 22 23:03:06 2015
New Revision: 289773
URL: https://svnweb.freebsd.org/changeset/base/289773

Log:
  Sysctl: Add common support for U8, U16 types
  
  Sponsored by: EMC / Isilon Storage Division

Modified:
  head/sbin/sysctl/sysctl.c
  head/sys/kern/kern_sysctl.c
  head/sys/sys/sysctl.h

Modified: head/sbin/sysctl/sysctl.c
==============================================================================
--- head/sbin/sysctl/sysctl.c   Thu Oct 22 22:29:25 2015        (r289772)
+++ head/sbin/sysctl/sysctl.c   Thu Oct 22 23:03:06 2015        (r289773)
@@ -96,6 +96,8 @@ static int ctl_size[CTLTYPE+1] = {
        [CTLTYPE_ULONG] = sizeof(u_long),
        [CTLTYPE_S64] = sizeof(int64_t),
        [CTLTYPE_U64] = sizeof(uint64_t),
+       [CTLTYPE_U8] = sizeof(uint8_t),
+       [CTLTYPE_U16] = sizeof(uint16_t),
 };
 
 static const char *ctl_typename[CTLTYPE+1] = {
@@ -105,6 +107,8 @@ static const char *ctl_typename[CTLTYPE+
        [CTLTYPE_ULONG] = "unsigned long",
        [CTLTYPE_S64] = "int64_t",
        [CTLTYPE_U64] = "uint64_t",
+       [CTLTYPE_U8] = "uint8_t",
+       [CTLTYPE_U16] = "uint16_t",
 };
 
 static void
@@ -221,6 +225,8 @@ parse(const char *string, int lineno)
        int len, i, j;
        const void *newval;
        const char *newvalstr = NULL;
+       uint8_t u8val;
+       uint16_t u16val;
        int intval;
        unsigned int uintval;
        long longval;
@@ -322,6 +328,8 @@ parse(const char *string, int lineno)
                }
 
                switch (kind & CTLTYPE) {
+               case CTLTYPE_U8:
+               case CTLTYPE_U16:
                case CTLTYPE_INT:
                case CTLTYPE_UINT:
                case CTLTYPE_LONG:
@@ -345,6 +353,16 @@ parse(const char *string, int lineno)
                errno = 0;
 
                switch (kind & CTLTYPE) {
+                       case CTLTYPE_U8:
+                               u8val = (uint8_t)strtoul(newvalstr, &endptr, 0);
+                               newval = &u8val;
+                               newsize = sizeof(u8val);
+                               break;
+                       case CTLTYPE_U16:
+                               u16val = (uint16_t)strtoul(newvalstr, &endptr, 
0);
+                               newval = &u16val;
+                               newsize = sizeof(u16val);
+                               break;
                        case CTLTYPE_INT:
                                if (strncmp(fmt, "IK", 2) == 0)
                                        intval = strIKtoi(newvalstr, &endptr, 
fmt);
@@ -890,6 +908,8 @@ show_var(int *oid, int nlen)
                free(oval);
                return (0);
 
+       case CTLTYPE_U8:
+       case CTLTYPE_U16:
        case CTLTYPE_INT:
        case CTLTYPE_UINT:
        case CTLTYPE_LONG:
@@ -902,6 +922,14 @@ show_var(int *oid, int nlen)
                sep1 = "";
                while (len >= intlen) {
                        switch (kind & CTLTYPE) {
+                       case CTLTYPE_U8:
+                               umv = *(uint8_t *)p;
+                               mv = *(int8_t *)p;
+                               break;
+                       case CTLTYPE_U16:
+                               umv = *(uint16_t *)p;
+                               mv = *(int16_t *)p;
+                               break;
                        case CTLTYPE_INT:
                        case CTLTYPE_UINT:
                                umv = *(u_int *)p;

Modified: head/sys/kern/kern_sysctl.c
==============================================================================
--- head/sys/kern/kern_sysctl.c Thu Oct 22 22:29:25 2015        (r289772)
+++ head/sys/kern/kern_sysctl.c Thu Oct 22 23:03:06 2015        (r289773)
@@ -1128,6 +1128,70 @@ static SYSCTL_NODE(_sysctl, 5, oiddescr,
  */
 
 /*
+ * Handle an int8_t, signed or unsigned.
+ * Two cases:
+ *     a variable:  point arg1 at it.
+ *     a constant:  pass it in arg2.
+ */
+
+int
+sysctl_handle_8(SYSCTL_HANDLER_ARGS)
+{
+       int8_t tmpout;
+       int error = 0;
+
+       /*
+        * Attempt to get a coherent snapshot by making a copy of the data.
+        */
+       if (arg1)
+               tmpout = *(int8_t *)arg1;
+       else
+               tmpout = arg2;
+       error = SYSCTL_OUT(req, &tmpout, sizeof(tmpout));
+
+       if (error || !req->newptr)
+               return (error);
+
+       if (!arg1)
+               error = EPERM;
+       else
+               error = SYSCTL_IN(req, arg1, sizeof(tmpout));
+       return (error);
+}
+
+/*
+ * Handle an int16_t, signed or unsigned.
+ * Two cases:
+ *     a variable:  point arg1 at it.
+ *     a constant:  pass it in arg2.
+ */
+
+int
+sysctl_handle_16(SYSCTL_HANDLER_ARGS)
+{
+       int16_t tmpout;
+       int error = 0;
+
+       /*
+        * Attempt to get a coherent snapshot by making a copy of the data.
+        */
+       if (arg1)
+               tmpout = *(int16_t *)arg1;
+       else
+               tmpout = arg2;
+       error = SYSCTL_OUT(req, &tmpout, sizeof(tmpout));
+
+       if (error || !req->newptr)
+               return (error);
+
+       if (!arg1)
+               error = EPERM;
+       else
+               error = SYSCTL_IN(req, arg1, sizeof(tmpout));
+       return (error);
+}
+
+/*
  * Handle an int, signed or unsigned.
  * Two cases:
  *     a variable:  point arg1 at it.

Modified: head/sys/sys/sysctl.h
==============================================================================
--- head/sys/sys/sysctl.h       Thu Oct 22 22:29:25 2015        (r289772)
+++ head/sys/sys/sysctl.h       Thu Oct 22 23:03:06 2015        (r289773)
@@ -73,6 +73,8 @@ struct ctlname {
 #define        CTLTYPE_LONG    7       /* name describes a long */
 #define        CTLTYPE_ULONG   8       /* name describes an unsigned long */
 #define        CTLTYPE_U64     9       /* name describes an unsigned 64-bit 
number */
+#define        CTLTYPE_U8      0xa     /* name describes an unsigned 8-bit 
number */
+#define        CTLTYPE_U16     0xb     /* name describes an unsigned 16-bit 
number */
 
 #define        CTLFLAG_RD      0x80000000      /* Allow reads of variable */
 #define        CTLFLAG_WR      0x40000000      /* Allow writes to the variable 
*/
@@ -188,6 +190,8 @@ struct sysctl_oid {
 #define        SYSCTL_OUT(r, p, l)     (r->oldfunc)(r, p, l)
 #define        SYSCTL_OUT_STR(r, p)    (r->oldfunc)(r, p, strlen(p) + 1)
 
+int sysctl_handle_8(SYSCTL_HANDLER_ARGS);
+int sysctl_handle_16(SYSCTL_HANDLER_ARGS);
 int sysctl_handle_int(SYSCTL_HANDLER_ARGS);
 int sysctl_msec_to_ticks(SYSCTL_HANDLER_ARGS);
 int sysctl_handle_long(SYSCTL_HANDLER_ARGS);
@@ -319,6 +323,46 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_e
            __arg, len, sysctl_handle_string, "A", __DESCR(descr));     \
 })
 
+/* Oid for an unsigned 8-bit int.  If ptr is NULL, val is returned. */
+#define        SYSCTL_NULL_U8_PTR ((unsigned *)NULL)
+#define        SYSCTL_U8(parent, nbr, name, access, ptr, val, descr)   \
+       SYSCTL_OID(parent, nbr, name,                           \
+           CTLTYPE_U8 | CTLFLAG_MPSAFE | (access),             \
+           ptr, val, sysctl_handle_8, "CU", descr);            \
+       CTASSERT((((access) & CTLTYPE) == 0 ||                  \
+           ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_U8) && \
+           sizeof(uint8_t) == sizeof(*(ptr)))
+
+#define        SYSCTL_ADD_U8(ctx, parent, nbr, name, access, ptr, val, descr)  
\
+({                                                                     \
+       uint8_t *__ptr = (ptr);                                         \
+       CTASSERT(((access) & CTLTYPE) == 0 ||                           \
+           ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_U8);          \
+       sysctl_add_oid(ctx, parent, nbr, name,                          \
+           CTLTYPE_U8 | CTLFLAG_MPSAFE | (access),                     \
+           __ptr, val, sysctl_handle_8, "CU", __DESCR(descr)); \
+})
+
+/* Oid for an unsigned 16-bit int.  If ptr is NULL, val is returned. */
+#define        SYSCTL_NULL_U16_PTR ((unsigned *)NULL)
+#define        SYSCTL_U16(parent, nbr, name, access, ptr, val, descr)  \
+       SYSCTL_OID(parent, nbr, name,                           \
+           CTLTYPE_U16 | CTLFLAG_MPSAFE | (access),            \
+           ptr, val, sysctl_handle_16, "SU", descr);           \
+       CTASSERT((((access) & CTLTYPE) == 0 ||                  \
+           ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_U16) && \
+           sizeof(uint16_t) == sizeof(*(ptr)))
+
+#define        SYSCTL_ADD_U16(ctx, parent, nbr, name, access, ptr, val, descr) 
\
+({                                                                     \
+       uint16_t *__ptr = (ptr);                                                
\
+       CTASSERT(((access) & CTLTYPE) == 0 ||                           \
+           ((access) & SYSCTL_CT_ASSERT_MASK) == CTLTYPE_U16);         \
+       sysctl_add_oid(ctx, parent, nbr, name,                          \
+           CTLTYPE_U16 | CTLFLAG_MPSAFE | (access),                    \
+           __ptr, val, sysctl_handle_16, "SU", __DESCR(descr));        \
+})
+
 /* Oid for an int.  If ptr is SYSCTL_NULL_INT_PTR, val is returned. */
 #define        SYSCTL_NULL_INT_PTR ((int *)NULL)
 #define        SYSCTL_INT(parent, nbr, name, access, ptr, val, descr)  \
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to