argv_split.c 1.8 KB

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