On Sat, Jul 29, 2017 at 02:19:50PM +0200, Martin Natano wrote:
> On Sat, Jul 29, 2017 at 02:03:22PM +0200, Mark Kettenis wrote:
> > 
> > I don't think we want to add string parsing like this in the kernel.
> > Maybe the sysctl(8) frontend should do the mapping from strings to
> > numbers?
> 
> Ok, I'll try to come up with an alternative diff that does the parsing
> in sysctl(8). Let me fetch my rubber gloves...

Here's the alternative diff. Ok?


Index: etc/etc.amd64/sysctl.conf
===================================================================
RCS file: /cvs/src/etc/etc.amd64/sysctl.conf,v
retrieving revision 1.7
diff -u -p -r1.7 sysctl.conf
--- etc/etc.amd64/sysctl.conf   2 Mar 2017 10:38:09 -0000       1.7
+++ etc/etc.amd64/sysctl.conf   25 Jul 2017 18:40:31 -0000
@@ -1,3 +1,3 @@
 #machdep.allowaperture=2       # See xf86(4)
 #machdep.kbdreset=1            # permit console CTRL-ALT-DEL to do a nice halt
-#machdep.lidaction=0           # 1=suspend, 2=hibernate laptop upon lid closing
+#machdep.lidaction=none                # action upon lid closing: none, 
suspend or hibernate
Index: etc/etc.i386/sysctl.conf
===================================================================
RCS file: /cvs/src/etc/etc.i386/sysctl.conf,v
retrieving revision 1.21
diff -u -p -r1.21 sysctl.conf
--- etc/etc.i386/sysctl.conf    2 Mar 2017 10:38:09 -0000       1.21
+++ etc/etc.i386/sysctl.conf    25 Jul 2017 18:40:35 -0000
@@ -1,4 +1,4 @@
 #machdep.allowaperture=2       # See xf86(4)
 #machdep.apmhalt=1             # 1=powerdown hack, try if halt -p doesn't work
 #machdep.kbdreset=1            # permit console CTRL-ALT-DEL to do a nice halt
-#machdep.lidaction=0           # 1=suspend, 2=hibernate laptop upon lid closing
+#machdep.lidaction=none                # action upon lid closing: none, 
suspend or hibernate
Index: etc/etc.loongson/sysctl.conf
===================================================================
RCS file: /cvs/src/etc/etc.loongson/sysctl.conf,v
retrieving revision 1.4
diff -u -p -r1.4 sysctl.conf
--- etc/etc.loongson/sysctl.conf        2 Mar 2017 10:38:09 -0000       1.4
+++ etc/etc.loongson/sysctl.conf        25 Jul 2017 18:40:40 -0000
@@ -1 +1 @@
-#machdep.lidaction=0           # 1=suspend, 2=hibernate laptop upon lid closing
+#machdep.lidaction=none                # action upon lid closing: none, 
suspend or hibernate
Index: sbin/sysctl/sysctl.c
===================================================================
RCS file: /cvs/src/sbin/sysctl/sysctl.c,v
retrieving revision 1.228
diff -u -p -r1.228 sysctl.c
--- sbin/sysctl/sysctl.c        19 Jul 2017 06:30:54 -0000      1.228
+++ sbin/sysctl/sysctl.c        29 Jul 2017 16:57:13 -0000
@@ -158,6 +158,15 @@ struct list secondlevel[] = {
        { 0, 0 },                       /* CTL_VFS */
 };
 
+struct enum_vals {
+       int              size;
+       const char      **names;
+};
+#ifdef CPU_LIDACTION
+const char *cpu_lidaction_names[] = { "none", "suspend", "hibernate" };
+struct enum_vals cpu_lidaction_enum = { 3, cpu_lidaction_names };
+#endif
+
 int    Aflag, aflag, nflag, qflag;
 
 /*
@@ -167,10 +176,10 @@ int       Aflag, aflag, nflag, qflag;
 #define        BOOTTIME        0x00000002
 #define        CHRDEV          0x00000004
 #define        BLKDEV          0x00000008
+#define ENUM           0x00000010
 #define        BADDYNAMIC      0x00000020
 #define        BIOSGEO         0x00000040
 #define        BIOSDEV         0x00000080
-#define        MAJ2DEV         0x00000100
 #define        UNSIGNED        0x00000200
 #define        KMEMBUCKETS     0x00000400
 #define        LONGARRAY       0x00000800
@@ -211,6 +220,8 @@ void print_sensor(struct sensor *);
 int sysctl_chipset(char *, char **, int *, int, int *);
 #endif
 void vfsinit(void);
+int strtoenum(const char *, struct enum_vals *, const char **);
+const char *enumtostr(int, struct enum_vals *);
 
 char *equ = "=";
 
@@ -297,6 +308,7 @@ parse(char *string, int flags)
        int indx, type, state, intval, len;
        size_t size, newsize = 0;
        int lal = 0, special = 0;
+       struct enum_vals *enump;
        void *newval = NULL;
        int64_t quadval;
        struct list *lp;
@@ -615,6 +627,12 @@ parse(char *string, int flags)
                if (mib[1] == CPU_CPUFEATURE)
                        special |= HEX;
 #endif
+#ifdef CPU_LIDACTION
+               if (mib[1] == CPU_LIDACTION) {
+                       special |= ENUM;
+                       enump = &cpu_lidaction_enum;
+               }
+#endif
 #ifdef CPU_BLK2CHR
                if (mib[1] == CPU_BLK2CHR) {
                        if (bufp == NULL)
@@ -700,6 +718,8 @@ parse(char *string, int flags)
                case CTLTYPE_INT:
                        if (special & UNSIGNED)
                                intval = strtonum(newval, 0, UINT_MAX, &errstr);
+                       else if (special & ENUM)
+                               intval = strtoenum(newval, enump, &errstr);
                        else
                                intval = strtonum(newval, INT_MIN, INT_MAX,
                                    &errstr);
@@ -917,17 +937,31 @@ parse(char *string, int flags)
                                (void)printf("%s%s", string, equ);
                        if (special & HEX)
                                (void)printf("0x%x\n", *(int *)buf);
+                       else if (special & ENUM)
+                               (void)printf("%s\n",
+                                   enumtostr(*(int *)buf, enump));
                        else
                                (void)printf("%d\n", *(int *)buf);
                } else {
                        if (!qflag) {
-                               if (!nflag)
-                                       (void)printf("%s: %d -> ", string,
-                                           *(int *)buf);
-                               if (special & HEX)
+                               if (special & HEX) {
+                                       if (!nflag)
+                                               (void)printf("%s: 0x%x -> ",
+                                                   string, *(int *)buf);
                                        (void)printf("0x%x\n", *(int *)newval);
-                               else
+                               } else if (special & ENUM) {
+                                       if (!nflag)
+                                               (void)printf("%s: %s -> ",
+                                                   string,
+                                                   enumtostr(*(int *)buf, 
enump));
+                                       (void)printf("%s\n",
+                                           enumtostr(*(int *)newval, enump));
+                               } else {
+                                       if (!nflag)
+                                               (void)printf("%s: %d -> ",
+                                                   string, *(int *)buf);
                                        (void)printf("%d\n", *(int *)newval);
+                               }
                        }
                }
                return;
@@ -2635,4 +2669,28 @@ usage(void)
            "       sysctl [-n] name ...\n"
            "       sysctl [-nq] name=value ...\n");
        exit(1);
+}
+
+int
+strtoenum(const char *str, struct enum_vals *enump, const char **errstr)
+{
+       int i;
+
+       for (i = 0; i < enump->size; i++) {
+               if (strcmp(enump->names[i], str) == 0) {
+                       *errstr = NULL;
+                       return i;
+               }
+       }
+
+       *errstr = "invalid";
+       return -1;
+}
+
+const char *
+enumtostr(int val, struct enum_vals *enump)
+{
+       if (val < 0 || val >= enump->size)
+               return "unknown";
+       return enump->names[val];
 }

Reply via email to