Version:  2.0.40 2.2.26 2.4.37 3.13 3.14 3.15 3.16 3.17 3.18 3.19 4.0 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 4.10

Linux/lib/argv_split.c

  1 /*
  2  * Helper function for splitting a string into an argv-like array.
  3  */
  4 
  5 #include <linux/kernel.h>
  6 #include <linux/ctype.h>
  7 #include <linux/string.h>
  8 #include <linux/slab.h>
  9 #include <linux/export.h>
 10 
 11 static int count_argc(const char *str)
 12 {
 13         int count = 0;
 14         bool was_space;
 15 
 16         for (was_space = true; *str; str++) {
 17                 if (isspace(*str)) {
 18                         was_space = true;
 19                 } else if (was_space) {
 20                         was_space = false;
 21                         count++;
 22                 }
 23         }
 24 
 25         return count;
 26 }
 27 
 28 /**
 29  * argv_free - free an argv
 30  * @argv - the argument vector to be freed
 31  *
 32  * Frees an argv and the strings it points to.
 33  */
 34 void argv_free(char **argv)
 35 {
 36         argv--;
 37         kfree(argv[0]);
 38         kfree(argv);
 39 }
 40 EXPORT_SYMBOL(argv_free);
 41 
 42 /**
 43  * argv_split - split a string at whitespace, returning an argv
 44  * @gfp: the GFP mask used to allocate memory
 45  * @str: the string to be split
 46  * @argcp: returned argument count
 47  *
 48  * Returns an array of pointers to strings which are split out from
 49  * @str.  This is performed by strictly splitting on white-space; no
 50  * quote processing is performed.  Multiple whitespace characters are
 51  * considered to be a single argument separator.  The returned array
 52  * is always NULL-terminated.  Returns NULL on memory allocation
 53  * failure.
 54  *
 55  * The source string at `str' may be undergoing concurrent alteration via
 56  * userspace sysctl activity (at least).  The argv_split() implementation
 57  * attempts to handle this gracefully by taking a local copy to work on.
 58  */
 59 char **argv_split(gfp_t gfp, const char *str, int *argcp)
 60 {
 61         char *argv_str;
 62         bool was_space;
 63         char **argv, **argv_ret;
 64         int argc;
 65 
 66         argv_str = kstrndup(str, KMALLOC_MAX_SIZE - 1, gfp);
 67         if (!argv_str)
 68                 return NULL;
 69 
 70         argc = count_argc(argv_str);
 71         argv = kmalloc(sizeof(*argv) * (argc + 2), gfp);
 72         if (!argv) {
 73                 kfree(argv_str);
 74                 return NULL;
 75         }
 76 
 77         *argv = argv_str;
 78         argv_ret = ++argv;
 79         for (was_space = true; *argv_str; argv_str++) {
 80                 if (isspace(*argv_str)) {
 81                         was_space = true;
 82                         *argv_str = 0;
 83                 } else if (was_space) {
 84                         was_space = false;
 85                         *argv++ = argv_str;
 86                 }
 87         }
 88         *argv = NULL;
 89 
 90         if (argcp)
 91                 *argcp = argc;
 92         return argv_ret;
 93 }
 94 EXPORT_SYMBOL(argv_split);
 95 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us