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