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