Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sbin/sysctl PR/44864: Paul Ripke: Compile regular expression...



details:   https://anonhg.NetBSD.org/src/rev/815705e0ca19
branches:  trunk
changeset: 764319:815705e0ca19
user:      christos <christos%NetBSD.org@localhost>
date:      Sat Apr 16 01:15:54 2011 +0000

description:
PR/44864: Paul Ripke: Compile regular expressions on demand and only once.

diffstat:

 sbin/sysctl/sysctl.c |  77 +++++++++++++++++++++++++++++----------------------
 1 files changed, 44 insertions(+), 33 deletions(-)

diffs (215 lines):

diff -r 6025cdd5ad06 -r 815705e0ca19 sbin/sysctl/sysctl.c
--- a/sbin/sysctl/sysctl.c      Fri Apr 15 22:57:05 2011 +0000
+++ b/sbin/sysctl/sysctl.c      Sat Apr 16 01:15:54 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: sysctl.c,v 1.133 2010/12/13 17:47:40 pooka Exp $ */
+/*     $NetBSD: sysctl.c,v 1.134 2011/04/16 01:15:54 christos Exp $ */
 
 /*-
  * Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -68,7 +68,7 @@
 #if 0
 static char sccsid[] = "@(#)sysctl.c   8.1 (Berkeley) 6/6/93";
 #else
-__RCSID("$NetBSD: sysctl.c,v 1.133 2010/12/13 17:47:40 pooka Exp $");
+__RCSID("$NetBSD: sysctl.c,v 1.134 2011/04/16 01:15:54 christos Exp $");
 #endif
 #endif /* not lint */
 
@@ -123,10 +123,12 @@
 /*
  * generic routines
  */
-static const struct handlespec *findhandler(const char *, int);
+static const struct handlespec *findhandler(const char *, int, regex_t *,
+    size_t *);
 static void canonicalize(const char *, char *);
 static void purge_tree(struct sysctlnode *);
-static void print_tree(int *, u_int, struct sysctlnode *, u_int, int);
+static void print_tree(int *, u_int, struct sysctlnode *, u_int, int, regex_t *,
+    size_t *);
 static void write_number(int *, u_int, struct sysctlnode *, char *);
 static void write_string(int *, u_int, struct sysctlnode *, char *);
 static void display_number(const struct sysctlnode *, const char *,
@@ -137,7 +139,7 @@
                           const void *, size_t, int);
 static void hex_dump(const unsigned char *, size_t);
 static void usage(void);
-static void parse(char *);
+static void parse(char *, regex_t *, size_t *);
 static void parse_create(char *);
 static void parse_destroy(char *);
 static void parse_describe(char *);
@@ -270,7 +272,10 @@
 {
        int name[CTL_MAXNAME];
        int ch;
+       size_t lastcompiled = 0;
+       regex_t *re;
 
+       setprogname(argv[0]);
        while ((ch = getopt(argc, argv, "Aabdef:Mnqrwx")) != -1) {
                switch (ch) {
                case 'A':
@@ -334,8 +339,12 @@
                warnfp = stdout;
        stale = req = 0;
 
+       if ((re = malloc(sizeof(*re) * __arraycount(handlers))) == NULL)
+               err(1, "malloc regex");
+
        if (aflag) {
-               print_tree(&name[0], 0, NULL, CTLTYPE_NODE, 1);
+               print_tree(&name[0], 0, NULL, CTLTYPE_NODE, 1,
+                   re, &lastcompiled);
                /* if (argc == 0) */
                return (0);
        }
@@ -352,7 +361,7 @@
                        while ((l = fparseln(fp, NULL, &nr, NULL, 0)) != NULL)
                        {
                                if (*l) {
-                                       parse(l);
+                                       parse(l, re, &lastcompiled);
                                        free(l);
                                }
                        }
@@ -365,7 +374,7 @@
                usage();
 
        while (argc-- > 0)
-               parse(*argv++);
+               parse(*argv++, re, &lastcompiled);
 
        return errs ? 1 : 0;
 }
@@ -377,38 +386,38 @@
  * ********************************************************************
  */
 static const struct handlespec *
-findhandler(const char *s, int w)
+findhandler(const char *s, int w, regex_t *re, size_t *lastcompiled)
 {
        const struct handlespec *p;
-       regex_t re;
-       int i, j, l;
+       size_t i, l;
+       int j;
        char eb[64];
-       regmatch_t match[1];
+       regmatch_t match;
 
        p = &handlers[0];
        l = strlen(s);
        for (i = 0; p[i].ps_re != NULL; i++) {
-               j = regcomp(&re, p[i].ps_re, REG_EXTENDED);
-               if (j != 0) {
-                       regerror(j, &re, eb, sizeof(eb));
-                       errx(1, "regcomp: %s: %s", p[i].ps_re, eb);
+               if (i >= *lastcompiled) {
+                       j = regcomp(&re[i], p[i].ps_re, REG_EXTENDED);
+                       if (j != 0) {
+                               regerror(j, &re[i], eb, sizeof(eb));
+                               errx(1, "regcomp: %s: %s", p[i].ps_re, eb);
+                       }
+                       *lastcompiled = i + 1;
                }
-               j = regexec(&re, s, 1, match, 0);
+               j = regexec(&re[i], s, 1, &match, 0);
                if (j == 0) {
-                       if (match[0].rm_so == 0 && match[0].rm_eo == l &&
-                           (w ? p[i].ps_w : p[i].ps_p) != NULL) {
-                               regfree(&re);
-                               return (&p[i]);
-                       }
+                       if (match.rm_so == 0 && match.rm_eo == (int)l &&
+                           (w ? p[i].ps_w : p[i].ps_p) != NULL)
+                               return &p[i];
                }
                else if (j != REG_NOMATCH) {
-                       regerror(j, &re, eb, sizeof(eb));
+                       regerror(j, &re[i], eb, sizeof(eb));
                        errx(1, "regexec: %s: %s", p[i].ps_re, eb);
                }
-               regfree(&re);
        }
 
-       return (NULL);
+       return NULL;
 }
 
 /*
@@ -552,7 +561,7 @@
  */
 static void
 print_tree(int *name, u_int namelen, struct sysctlnode *pnode, u_int type,
-          int add)
+   int add, regex_t *re, size_t *lastcompiled)
 {
        struct sysctlnode *node;
        int rc;
@@ -651,7 +660,7 @@
        }
 
        canonicalize(gsname, canonname);
-       p = findhandler(canonname, 0);
+       p = findhandler(canonname, 0, re, lastcompiled);
        if (type != CTLTYPE_NODE && p != NULL) {
                (*p->ps_p)(gsname, gdname, NULL, name, namelen, pnode, type,
                           __UNCONST(p->ps_d));
@@ -704,7 +713,7 @@
                                        continue;
                                print_tree(name, namelen + 1, &node[ni],
                                           SYSCTL_TYPE(node[ni].sysctl_flags),
-                                          1);
+                                          1, re, lastcompiled);
                        }
                }
                break;
@@ -797,7 +806,7 @@
  * ********************************************************************
  */
 static void
-parse(char *l)
+parse(char *l, regex_t *re, size_t *lastcompiled)
 {
        struct sysctlnode *node;
        const struct handlespec *w;
@@ -870,7 +879,7 @@
        if (value == NULL) {
                if (dodesc)
                        dflag = 1;
-               print_tree(&name[0], namelen, node, type, 0);
+               print_tree(&name[0], namelen, node, type, 0, re, lastcompiled);
                if (dodesc)
                        dflag = 0;
                gsname[0] = '\0';
@@ -886,7 +895,8 @@
        }
 
        canonicalize(gsname, canonname);
-       if (type != CTLTYPE_NODE && (w = findhandler(canonname, 1)) != NULL) {
+       if (type != CTLTYPE_NODE && (w = findhandler(canonname, 1, re,
+           lastcompiled)) != NULL) {
                (*w->ps_w)(gsname, gdname, value, name, namelen, node, type,
                           __UNCONST(w->ps_d));
                gsname[0] = '\0';
@@ -898,7 +908,8 @@
                /*
                 * XXX old behavior is to print.  should we error instead?
                 */
-               print_tree(&name[0], namelen, node, CTLTYPE_NODE, 1);
+               print_tree(&name[0], namelen, node, CTLTYPE_NODE, 1, re,
+                   lastcompiled);
                break;
        case CTLTYPE_INT:
        case CTLTYPE_BOOL:
@@ -913,7 +924,7 @@
                 * XXX old behavior is to print.  should we error instead?
                 */
                /* fprintf(warnfp, "you can't write to %s\n", gsname); */
-               print_tree(&name[0], namelen, node, type, 0);
+               print_tree(&name[0], namelen, node, type, 0, re, lastcompiled);
                break;
        }
 }



Home | Main Index | Thread Index | Old Index