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/bug.h> 8 9 static const char *skip_sep(const char *cp) 10 { 11 while (*cp && isspace(*cp)) 12 cp++; 13 14 return cp; 15 } 16 17 static const char *skip_arg(const char *cp) 18 { 19 while (*cp && !isspace(*cp)) 20 cp++; 21 22 return cp; 23 } 24 25 static int count_argc(const char *str) 26 { 27 int count = 0; 28 29 while (*str) { 30 str = skip_sep(str); 31 if (*str) { 32 count++; 33 str = skip_arg(str); 34 } 35 } 36 37 return count; 38 } 39 40 /** 41 * argv_free - free an argv 42 * @argv - the argument vector to be freed 43 * 44 * Frees an argv and the strings it points to. 45 */ 46 void argv_free(char **argv) 47 { 48 char **p; 49 for (p = argv; *p; p++) 50 kfree(*p); 51 52 kfree(argv); 53 } 54 EXPORT_SYMBOL(argv_free); 55 56 /** 57 * argv_split - split a string at whitespace, returning an argv 58 * @gfp: the GFP mask used to allocate memory 59 * @str: the string to be split 60 * @argcp: returned argument count 61 * 62 * Returns an array of pointers to strings which are split out from 63 * @str. This is performed by strictly splitting on white-space; no 64 * quote processing is performed. Multiple whitespace characters are 65 * considered to be a single argument separator. The returned array 66 * is always NULL-terminated. Returns NULL on memory allocation 67 * failure. 68 */ 69 char **argv_split(gfp_t gfp, const char *str, int *argcp) 70 { 71 int argc = count_argc(str); 72 char **argv = kzalloc(sizeof(*argv) * (argc+1), gfp); 73 char **argvp; 74 75 if (argv == NULL) 76 goto out; 77 78 *argcp = argc; 79 argvp = argv; 80 81 while (*str) { 82 str = skip_sep(str); 83 84 if (*str) { 85 const char *p = str; 86 char *t; 87 88 str = skip_arg(str); 89 90 t = kstrndup(p, str-p, gfp); 91 if (t == NULL) 92 goto fail; 93 *argvp++ = t; 94 } 95 } 96 *argvp = NULL; 97 98 out: 99 return argv; 100 101 fail: 102 argv_free(argv); 103 return NULL; 104 } 105 EXPORT_SYMBOL(argv_split); 106