subprocess.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /* Copyright (c) 2003, Roger Dingledine
  2. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  3. * Copyright (c) 2007-2018, The Tor Project, Inc. */
  4. /* See LICENSE for licensing information */
  5. /**
  6. * \file subprocess.c
  7. * \brief Launch and monitor other processes.
  8. **/
  9. #define SUBPROCESS_PRIVATE
  10. #include "lib/process/subprocess.h"
  11. #include "lib/container/smartlist.h"
  12. #include "lib/err/torerr.h"
  13. #include "lib/log/log.h"
  14. #include "lib/log/util_bug.h"
  15. #include "lib/log/win32err.h"
  16. #include "lib/malloc/malloc.h"
  17. #include "lib/process/env.h"
  18. #include "lib/process/waitpid.h"
  19. #include "lib/string/compat_ctype.h"
  20. #ifdef HAVE_SYS_TYPES_H
  21. #include <sys/types.h>
  22. #endif
  23. #ifdef HAVE_SYS_PRCTL_H
  24. #include <sys/prctl.h>
  25. #endif
  26. #ifdef HAVE_UNISTD_H
  27. #include <unistd.h>
  28. #endif
  29. #ifdef HAVE_SIGNAL_H
  30. #include <signal.h>
  31. #endif
  32. #ifdef HAVE_FCNTL_H
  33. #include <fcntl.h>
  34. #endif
  35. #ifdef HAVE_SYS_WAIT_H
  36. #include <sys/wait.h>
  37. #endif
  38. #include <errno.h>
  39. #include <string.h>
  40. /** Format a single argument for being put on a Windows command line.
  41. * Returns a newly allocated string */
  42. static char *
  43. format_win_cmdline_argument(const char *arg)
  44. {
  45. char *formatted_arg;
  46. char need_quotes;
  47. const char *c;
  48. int i;
  49. int bs_counter = 0;
  50. /* Backslash we can point to when one is inserted into the string */
  51. const char backslash = '\\';
  52. /* Smartlist of *char */
  53. smartlist_t *arg_chars;
  54. arg_chars = smartlist_new();
  55. /* Quote string if it contains whitespace or is empty */
  56. need_quotes = (strchr(arg, ' ') || strchr(arg, '\t') || '\0' == arg[0]);
  57. /* Build up smartlist of *chars */
  58. for (c=arg; *c != '\0'; c++) {
  59. if ('"' == *c) {
  60. /* Double up backslashes preceding a quote */
  61. for (i=0; i<(bs_counter*2); i++)
  62. smartlist_add(arg_chars, (void*)&backslash);
  63. bs_counter = 0;
  64. /* Escape the quote */
  65. smartlist_add(arg_chars, (void*)&backslash);
  66. smartlist_add(arg_chars, (void*)c);
  67. } else if ('\\' == *c) {
  68. /* Count backslashes until we know whether to double up */
  69. bs_counter++;
  70. } else {
  71. /* Don't double up slashes preceding a non-quote */
  72. for (i=0; i<bs_counter; i++)
  73. smartlist_add(arg_chars, (void*)&backslash);
  74. bs_counter = 0;
  75. smartlist_add(arg_chars, (void*)c);
  76. }
  77. }
  78. /* Don't double up trailing backslashes */
  79. for (i=0; i<bs_counter; i++)
  80. smartlist_add(arg_chars, (void*)&backslash);
  81. /* Allocate space for argument, quotes (if needed), and terminator */
  82. const size_t formatted_arg_len = smartlist_len(arg_chars) +
  83. (need_quotes ? 2 : 0) + 1;
  84. formatted_arg = tor_malloc_zero(formatted_arg_len);
  85. /* Add leading quote */
  86. i=0;
  87. if (need_quotes)
  88. formatted_arg[i++] = '"';
  89. /* Add characters */
  90. SMARTLIST_FOREACH(arg_chars, char*, ch,
  91. {
  92. formatted_arg[i++] = *ch;
  93. });
  94. /* Add trailing quote */
  95. if (need_quotes)
  96. formatted_arg[i++] = '"';
  97. formatted_arg[i] = '\0';
  98. smartlist_free(arg_chars);
  99. return formatted_arg;
  100. }
  101. /** Format a command line for use on Windows, which takes the command as a
  102. * string rather than string array. Follows the rules from "Parsing C++
  103. * Command-Line Arguments" in MSDN. Algorithm based on list2cmdline in the
  104. * Python subprocess module. Returns a newly allocated string */
  105. char *
  106. tor_join_win_cmdline(const char *argv[])
  107. {
  108. smartlist_t *argv_list;
  109. char *joined_argv;
  110. int i;
  111. /* Format each argument and put the result in a smartlist */
  112. argv_list = smartlist_new();
  113. for (i=0; argv[i] != NULL; i++) {
  114. smartlist_add(argv_list, (void *)format_win_cmdline_argument(argv[i]));
  115. }
  116. /* Join the arguments with whitespace */
  117. joined_argv = smartlist_join_strings(argv_list, " ", 0, NULL);
  118. /* Free the newly allocated arguments, and the smartlist */
  119. SMARTLIST_FOREACH(argv_list, char *, arg,
  120. {
  121. tor_free(arg);
  122. });
  123. smartlist_free(argv_list);
  124. return joined_argv;
  125. }
  126. /**
  127. * Boolean. If true, then Tor may call execve or CreateProcess via
  128. * tor_spawn_background.
  129. **/
  130. static int may_spawn_background_process = 1;
  131. /**
  132. * Turn off may_spawn_background_process, so that all future calls to
  133. * tor_spawn_background are guaranteed to fail.
  134. **/
  135. void
  136. tor_disable_spawning_background_processes(void)
  137. {
  138. may_spawn_background_process = 0;
  139. }