Something went wrong. Try again.
Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101// SPDX-License-Identifier: GPL-2.0/* * Helper function for splitting a string into an argv-like array. */
#include <stdlib.h>#include <linux/kernel.h>#include <linux/ctype.h>#include <linux/string.h>
static const char *skip_arg(const char *cp){ while (*cp && !isspace(*cp)) cp++;
return cp;}
static int count_argc(const char *str){ int count = 0;
while (*str) { str = skip_spaces(str); if (*str) { count++; str = skip_arg(str); } }
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){ char **p; for (p = argv; *p; p++) { free(*p); *p = NULL; }
free(argv);}
/** * argv_split - split a string at whitespace, returning an argv * @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. */char **argv_split(const char *str, int *argcp){ int argc = count_argc(str); char **argv = calloc(argc + 1, sizeof(*argv)); char **argvp;
if (argv == NULL) goto out;
if (argcp) *argcp = argc;
argvp = argv;
while (*str) { str = skip_spaces(str);
if (*str) { const char *p = str; char *t;
str = skip_arg(str);
t = strndup(p, str-p); if (t == NULL) goto fail; *argvp++ = t; } } *argvp = NULL;
out: return argv;
fail: argv_free(argv); return NULL;}