tor_runner.c 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. /* Copyright (c) 2001 Matej Pfajfar.
  2. * Copyright (c) 2001-2004, Roger Dingledine.
  3. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  4. * Copyright (c) 2007-2017, The Tor Project, Inc. */
  5. /* See LICENSE for licensing information */
  6. #include "tor_api.h"
  7. #include "tor_api_internal.h"
  8. #include "orconfig.h"
  9. #ifdef HAVE_UNISTD_H
  10. #include <unistd.h>
  11. #endif
  12. #ifdef HAVE_SYS_WAIT_H
  13. #include <sys/wait.h>
  14. #endif
  15. #ifdef HAVE_SYS_SOCKET_H
  16. #include <sys/socket.h>
  17. #endif
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #ifndef __GNUC__
  21. #define __attribute__(x)
  22. #endif
  23. static void child(const tor_main_configuration_t *cfg)
  24. __attribute__((noreturn));
  25. int
  26. tor_run_main(const tor_main_configuration_t *cfg)
  27. {
  28. pid_t pid = fork();
  29. if (pid == 0) {
  30. child(cfg);
  31. exit(0); /* Unreachable */
  32. }
  33. pid_t stopped_pid;
  34. int status = 0;
  35. do {
  36. stopped_pid = waitpid(pid, &status, 0);
  37. } while (stopped_pid == -1);
  38. /* Note: these return values are not documented. No return value is
  39. * documented! */
  40. if (stopped_pid != pid) {
  41. return -99999;
  42. }
  43. if (WIFSTOPPED(status)) {
  44. return WEXITSTATUS(status);
  45. }
  46. if (WIFSIGNALED(status)) {
  47. return -WTERMSIG(status);
  48. }
  49. return -999988;
  50. }
  51. static void
  52. child(const tor_main_configuration_t *cfg)
  53. {
  54. /* XXXX Close unused file descriptors. */
  55. char **args = calloc(cfg->argc+1, sizeof(char *));
  56. memcpy(args, cfg->argv, cfg->argc * sizeof(char *));
  57. args[cfg->argc] = NULL;
  58. int rv = execv(BINDIR "/tor", args);
  59. if (rv < 0) {
  60. exit(254);
  61. } else {
  62. abort(); /* Unreachable */
  63. }
  64. }