argv_split.c 1.8 KB

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