argv_split.c 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Helper function for splitting a string into an argv-like array.
  4. */
  5. #include <stdlib.h>
  6. #include <linux/kernel.h>
  7. #include <linux/ctype.h>
  8. #include <linux/string.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. free(*p);
  38. *p = NULL;
  39. }
  40. free(argv);
  41. }
  42. /**
  43. * argv_split - split a string at whitespace, returning an argv
  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(const char *str, int *argcp)
  55. {
  56. int argc = count_argc(str);
  57. char **argv = calloc(argc + 1, sizeof(*argv));
  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 = strndup(p, str-p);
  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. }