Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/lib/argv_split.c
10811 views
1
/*
2
* Helper function for splitting a string into an argv-like array.
3
*/
4
5
#include <linux/kernel.h>
6
#include <linux/ctype.h>
7
#include <linux/string.h>
8
#include <linux/slab.h>
9
#include <linux/module.h>
10
11
static const char *skip_arg(const char *cp)
12
{
13
while (*cp && !isspace(*cp))
14
cp++;
15
16
return cp;
17
}
18
19
static int count_argc(const char *str)
20
{
21
int count = 0;
22
23
while (*str) {
24
str = skip_spaces(str);
25
if (*str) {
26
count++;
27
str = skip_arg(str);
28
}
29
}
30
31
return count;
32
}
33
34
/**
35
* argv_free - free an argv
36
* @argv - the argument vector to be freed
37
*
38
* Frees an argv and the strings it points to.
39
*/
40
void argv_free(char **argv)
41
{
42
char **p;
43
for (p = argv; *p; p++)
44
kfree(*p);
45
46
kfree(argv);
47
}
48
EXPORT_SYMBOL(argv_free);
49
50
/**
51
* argv_split - split a string at whitespace, returning an argv
52
* @gfp: the GFP mask used to allocate memory
53
* @str: the string to be split
54
* @argcp: returned argument count
55
*
56
* Returns an array of pointers to strings which are split out from
57
* @str. This is performed by strictly splitting on white-space; no
58
* quote processing is performed. Multiple whitespace characters are
59
* considered to be a single argument separator. The returned array
60
* is always NULL-terminated. Returns NULL on memory allocation
61
* failure.
62
*/
63
char **argv_split(gfp_t gfp, const char *str, int *argcp)
64
{
65
int argc = count_argc(str);
66
char **argv = kzalloc(sizeof(*argv) * (argc+1), gfp);
67
char **argvp;
68
69
if (argv == NULL)
70
goto out;
71
72
if (argcp)
73
*argcp = argc;
74
75
argvp = argv;
76
77
while (*str) {
78
str = skip_spaces(str);
79
80
if (*str) {
81
const char *p = str;
82
char *t;
83
84
str = skip_arg(str);
85
86
t = kstrndup(p, str-p, gfp);
87
if (t == NULL)
88
goto fail;
89
*argvp++ = t;
90
}
91
}
92
*argvp = NULL;
93
94
out:
95
return argv;
96
97
fail:
98
argv_free(argv);
99
return NULL;
100
}
101
EXPORT_SYMBOL(argv_split);
102
103