Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Helper function for splitting a string into an argv-like array.
0004  */
0005 
0006 #include <stdlib.h>
0007 #include <linux/kernel.h>
0008 #include <linux/ctype.h>
0009 #include <linux/string.h>
0010 
0011 static const char *skip_arg(const char *cp)
0012 {
0013     while (*cp && !isspace(*cp))
0014         cp++;
0015 
0016     return cp;
0017 }
0018 
0019 static int count_argc(const char *str)
0020 {
0021     int count = 0;
0022 
0023     while (*str) {
0024         str = skip_spaces(str);
0025         if (*str) {
0026             count++;
0027             str = skip_arg(str);
0028         }
0029     }
0030 
0031     return count;
0032 }
0033 
0034 /**
0035  * argv_free - free an argv
0036  * @argv - the argument vector to be freed
0037  *
0038  * Frees an argv and the strings it points to.
0039  */
0040 void argv_free(char **argv)
0041 {
0042     char **p;
0043     for (p = argv; *p; p++) {
0044         free(*p);
0045         *p = NULL;
0046     }
0047 
0048     free(argv);
0049 }
0050 
0051 /**
0052  * argv_split - split a string at whitespace, returning an argv
0053  * @str: the string to be split
0054  * @argcp: returned argument count
0055  *
0056  * Returns an array of pointers to strings which are split out from
0057  * @str.  This is performed by strictly splitting on white-space; no
0058  * quote processing is performed.  Multiple whitespace characters are
0059  * considered to be a single argument separator.  The returned array
0060  * is always NULL-terminated.  Returns NULL on memory allocation
0061  * failure.
0062  */
0063 char **argv_split(const char *str, int *argcp)
0064 {
0065     int argc = count_argc(str);
0066     char **argv = calloc(argc + 1, sizeof(*argv));
0067     char **argvp;
0068 
0069     if (argv == NULL)
0070         goto out;
0071 
0072     if (argcp)
0073         *argcp = argc;
0074 
0075     argvp = argv;
0076 
0077     while (*str) {
0078         str = skip_spaces(str);
0079 
0080         if (*str) {
0081             const char *p = str;
0082             char *t;
0083 
0084             str = skip_arg(str);
0085 
0086             t = strndup(p, str-p);
0087             if (t == NULL)
0088                 goto fail;
0089             *argvp++ = t;
0090         }
0091     }
0092     *argvp = NULL;
0093 
0094 out:
0095     return argv;
0096 
0097 fail:
0098     argv_free(argv);
0099     return NULL;
0100 }