/* * Helper function for splitting a string into an argv-like array. */ #include <linux/kernel.h> #include <linux/ctype.h> #include <linux/string.h> #include <linux/slab.h> #include <linux/export.h> static int count_argc(const char *str) { int count = 0; bool was_space; for (was_space = true; *str; str++) { if (isspace(*str)) { was_space = true; } else if (was_space) { was_space = false; count++; } } 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) { argv--; kfree(argv[0]); 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. * * 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. */ char **argv_split(gfp_t gfp, const char *str, int *argcp) { 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; } *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; } } *argv = NULL; if (argcp) *argcp = argc; return argv_ret; } EXPORT_SYMBOL(argv_split); f0b9d04674e325346c17de9a895425ca5e1'>diff</a></td><td class='form'><form class='right' method='get' action='/cgit.cgi/linux/net-next.git/log/include/sound/asequencer.h'> <input type='hidden' name='id' value='a971df0b9d04674e325346c17de9a895425ca5e1'/><input type='hidden' name='showmsg' value='1'/><select name='qt'> <option value='grep'>log msg</option> <option value='author'>author</option> <option value='committer'>committer</option> <option value='range'>range</option> </select> <input class='txt' type='search' size='10' name='q' value=''/> <input type='submit' value='search'/> </form> </td></tr></table> <div class='path'>path: <a href='/cgit.cgi/linux/net-next.git/log/?id=a971df0b9d04674e325346c17de9a895425ca5e1&showmsg=1'>root</a>/<a href='/cgit.cgi/linux/net-next.git/log/include?id=a971df0b9d04674e325346c17de9a895425ca5e1&showmsg=1'>include</a>/<a href='/cgit.cgi/linux/net-next.git/log/include/sound?id=a971df0b9d04674e325346c17de9a895425ca5e1&showmsg=1'>sound</a>/<a href='/cgit.cgi/linux/net-next.git/log/include/sound/asequencer.h?id=a971df0b9d04674e325346c17de9a895425ca5e1&showmsg=1'>asequencer.h</a></div><div class='content'><table class='list nowrap'><tr class='nohover'><th class='left'>Age</th><th class='left'>Commit message (<a href='/cgit.cgi/linux/net-next.git/log/include/sound/asequencer.h?id=a971df0b9d04674e325346c17de9a895425ca5e1'>Collapse</a>)</th><th class='left'>Author</th><th class='left'>Files</th><th class='left'>Lines</th></tr>