// SPDX-License-Identifier: GPL-2.01/*2* Helper function for splitting a string into an argv-like array.3*/45#include <stdlib.h>6#include <linux/kernel.h>7#include <linux/ctype.h>8#include <linux/string.h>910static const char *skip_arg(const char *cp)11{12while (*cp && !isspace(*cp))13cp++;1415return cp;16}1718static int count_argc(const char *str)19{20int count = 0;2122while (*str) {23str = skip_spaces(str);24if (*str) {25count++;26str = skip_arg(str);27}28}2930return count;31}3233/**34* argv_free - free an argv35* @argv - the argument vector to be freed36*37* Frees an argv and the strings it points to.38*/39void argv_free(char **argv)40{41char **p;42for (p = argv; *p; p++) {43free(*p);44*p = NULL;45}4647free(argv);48}4950/**51* argv_split - split a string at whitespace, returning an argv52* @str: the string to be split53* @argcp: returned argument count54*55* Returns an array of pointers to strings which are split out from56* @str. This is performed by strictly splitting on white-space; no57* quote processing is performed. Multiple whitespace characters are58* considered to be a single argument separator. The returned array59* is always NULL-terminated. Returns NULL on memory allocation60* failure.61*/62char **argv_split(const char *str, int *argcp)63{64int argc = count_argc(str);65char **argv = calloc(argc + 1, sizeof(*argv));66char **argvp;6768if (argv == NULL)69goto out;7071if (argcp)72*argcp = argc;7374argvp = argv;7576while (*str) {77str = skip_spaces(str);7879if (*str) {80const char *p = str;81char *t;8283str = skip_arg(str);8485t = strndup(p, str-p);86if (t == NULL)87goto fail;88*argvp++ = t;89}90}91*argvp = NULL;9293out:94return argv;9596fail:97argv_free(argv);98return NULL;99}100101102