modprobe-small: make string buffer code robust; fix help text
authorDenys Vlasenko <vda.linux@googlemail.com>
Mon, 7 Sep 2009 00:38:26 +0000 (02:38 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Mon, 7 Sep 2009 00:38:26 +0000 (02:38 +0200)
together with previous one-liner:

function                                             old     new   delta
append                                                70      99     +29
parse_module                                         295     311     +16
copy_stringbuf                                        35      36      +1
packed_usage                                       26545   26540      -5
appendc                                               27       -     -27
------------------------------------------------------------------------------
(add/remove: 0/1 grow/shrink: 3/1 up/down: 46/-32)             Total: 14 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
include/usage.h
modutils/modprobe-small.c

index e571d2b..036cf9d 100644 (file)
        "-rw-------    1 andersen andersen        0 Apr 25 17:10 /tmp/temp.mWiLjM\n"
 
 #define modprobe_trivial_usage \
-       "[-knqrsv] MODULE [symbol=value...]"
+       IF_MODPROBE_SMALL("[-qfwrsv] MODULE [symbol=value...]") \
+       IF_NOT_MODPROBE_SMALL("[-" \
+               IF_FEATURE_2_4_MODULES("k")"nqrsv" \
+               IF_FEATURE_MODPROBE_BLACKLIST("b")"] MODULE [symbol=value...]")
 #define modprobe_full_usage "\n\n" \
        "Options:" \
+       IF_MODPROBE_SMALL( \
+     "\n       -q      Quiet" \
+     "\n       -f      Force" \
+     "\n       -w      Wait for unload" \
+     "\n       -r      Remove module (stacks) or do autoclean" \
+     "\n       -s      Report via syslog instead of stderr" \
+     "\n       -v      Verbose" \
+       ) \
+       IF_NOT_MODPROBE_SMALL( \
        IF_FEATURE_2_4_MODULES( \
      "\n       -k      Make module autoclean-able" \
        ) \
      "\n       -v      Verbose" \
        IF_FEATURE_MODPROBE_BLACKLIST( \
      "\n       -b      Apply blacklist to module names too" \
-        )
+       ) \
+       )
 
 #define modprobe_notes_usage \
 "modprobe can (un)load a stack of modules, passing each module options (when\n" \
index bc80723..e2359d0 100644 (file)
@@ -44,11 +44,13 @@ struct globals {
        char *module_load_options;
        smallint dep_bb_seen;
        smallint wrote_dep_bb_ok;
-       int module_count;
+       unsigned module_count;
        int module_found_idx;
-       int stringbuf_idx;
-       char stringbuf[32 * 1024]; /* some modules have lots of stuff */
+       unsigned stringbuf_idx;
+       unsigned stringbuf_size;
+       char *stringbuf; /* some modules have lots of stuff */
        /* for example, drivers/media/video/saa7134/saa7134.ko */
+       /* therefore having a fixed biggish buffer is not wise */
 };
 #define G (*ptr_to_globals)
 #define modinfo             (G.modinfo            )
@@ -58,16 +60,29 @@ struct globals {
 #define module_found_idx    (G.module_found_idx   )
 #define module_load_options (G.module_load_options)
 #define stringbuf_idx       (G.stringbuf_idx      )
+#define stringbuf_size      (G.stringbuf_size     )
 #define stringbuf           (G.stringbuf          )
 #define INIT_G() do { \
        SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
 } while (0)
 
+static void append(const char *s)
+{
+       unsigned len = strlen(s);
+       if (stringbuf_idx + len + 15 > stringbuf_size) {
+               stringbuf_size = stringbuf_idx + len + 127;
+               dbg2_error_msg("grow stringbuf to %u", stringbuf_size);
+               stringbuf = xrealloc(stringbuf, stringbuf_size);
+       }
+       memcpy(stringbuf + stringbuf_idx, s, len);
+       stringbuf_idx += len;
+}
 
 static void appendc(char c)
 {
-       if (stringbuf_idx < sizeof(stringbuf))
-               stringbuf[stringbuf_idx++] = c;
+       /* We appendc() only after append(), + 15 trick in append()
+        * makes it unnecessary to check for overflow here */
+       stringbuf[stringbuf_idx++] = c;
 }
 
 static void bksp(void)
@@ -76,15 +91,6 @@ static void bksp(void)
                stringbuf_idx--;
 }
 
-static void append(const char *s)
-{
-       size_t len = strlen(s);
-       if (stringbuf_idx + len < sizeof(stringbuf)) {
-               memcpy(stringbuf + stringbuf_idx, s, len);
-               stringbuf_idx += len;
-       }
-}
-
 static void reset_stringbuf(void)
 {
        stringbuf_idx = 0;
@@ -92,7 +98,7 @@ static void reset_stringbuf(void)
 
 static char* copy_stringbuf(void)
 {
-       char *copy = xmalloc(stringbuf_idx);
+       char *copy = xzalloc(stringbuf_idx + 1); /* terminating NUL */
        return memcpy(copy, stringbuf, stringbuf_idx);
 }
 
@@ -216,7 +222,6 @@ static void parse_module(module_info *info, const char *pathname)
                pos = (ptr - module_image);
        }
        bksp(); /* remove last ' ' */
-       appendc('\0');
        info->aliases = copy_stringbuf();
        replace(info->aliases, '-', '_');
 
@@ -229,7 +234,6 @@ static void parse_module(module_info *info, const char *pathname)
                dbg2_error_msg("dep:'%s'", ptr);
                append(ptr);
        }
-       appendc('\0');
        info->deps = copy_stringbuf();
 
        free(module_image);