linux/lib/argv_split.c
<<
>>
Prefs
   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
  11static const char *skip_arg(const char *cp)
  12{
  13        while (*cp && !isspace(*cp))
  14                cp++;
  15
  16        return cp;
  17}
  18
  19static 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 */
  40void argv_free(char **argv)
  41{
  42        char **p;
  43        for (p = argv; *p; p++)
  44                kfree(*p);
  45
  46        kfree(argv);
  47}
  48EXPORT_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 */
  63char **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}
 101EXPORT_SYMBOL(argv_split);
 102