argv_split.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  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. *argcp = argc;
  66. argvp = argv;
  67. while (*str) {
  68. str = skip_sep(str);
  69. if (*str) {
  70. const char *p = str;
  71. char *t;
  72. str = skip_arg(str);
  73. t = kstrndup(p, str-p, gfp);
  74. if (t == NULL)
  75. goto fail;
  76. *argvp++ = t;
  77. }
  78. }
  79. *argvp = NULL;
  80. out:
  81. return argv;
  82. fail:
  83. argv_free(argv);
  84. return NULL;
  85. }
  86. EXPORT_SYMBOL(argv_split);