123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- /*
- * 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/module.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++)
- kfree(*p);
- 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.
- */
- char **argv_split(gfp_t gfp, const char *str, int *argcp)
- {
- int argc = count_argc(str);
- char **argv = kzalloc(sizeof(*argv) * (argc+1), gfp);
- 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 = kstrndup(p, str-p, gfp);
- if (t == NULL)
- goto fail;
- *argvp++ = t;
- }
- }
- *argvp = NULL;
- out:
- return argv;
- fail:
- argv_free(argv);
- return NULL;
- }
- EXPORT_SYMBOL(argv_split);
|