argv_split.c 1.8 KB

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