daemon.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  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 daemon.c
  7. * \brief Run the tor process in the background (unix only)
  8. **/
  9. #include "orconfig.h"
  10. #include "lib/process/daemon.h"
  11. #ifndef _WIN32
  12. #include "lib/fs/files.h"
  13. #include "lib/log/log.h"
  14. #include "lib/thread/threads.h"
  15. #ifdef HAVE_SYS_TYPES_H
  16. #include <sys/types.h>
  17. #endif
  18. #ifdef HAVE_UNISTD_H
  19. #include <unistd.h>
  20. #endif
  21. #ifdef HAVE_FCNTL_H
  22. #include <fcntl.h>
  23. #endif
  24. #include <errno.h>
  25. #include <stdlib.h>
  26. #include <string.h>
  27. /* Based on code contributed by christian grothoff */
  28. /** True iff we've called start_daemon(). */
  29. static int start_daemon_called = 0;
  30. /** True iff we've called finish_daemon(). */
  31. static int finish_daemon_called = 0;
  32. /** Socketpair used to communicate between parent and child process while
  33. * daemonizing. */
  34. static int daemon_filedes[2];
  35. /** Start putting the process into daemon mode: fork and drop all resources
  36. * except standard fds. The parent process never returns, but stays around
  37. * until finish_daemon is called. (Note: it's safe to call this more
  38. * than once: calls after the first are ignored.) Return true if we actually
  39. * forked and this is the child; false otherwise.
  40. */
  41. int
  42. start_daemon(void)
  43. {
  44. pid_t pid;
  45. if (start_daemon_called)
  46. return 0;
  47. start_daemon_called = 1;
  48. if (pipe(daemon_filedes)) {
  49. /* LCOV_EXCL_START */
  50. log_err(LD_GENERAL,"pipe failed; exiting. Error was %s", strerror(errno));
  51. exit(1); // exit ok: during daemonize, pipe failed.
  52. /* LCOV_EXCL_STOP */
  53. }
  54. pid = fork();
  55. if (pid < 0) {
  56. /* LCOV_EXCL_START */
  57. log_err(LD_GENERAL,"fork failed. Exiting.");
  58. exit(1); // exit ok: during daemonize, fork failed
  59. /* LCOV_EXCL_STOP */
  60. }
  61. if (pid) { /* Parent */
  62. int ok;
  63. char c;
  64. close(daemon_filedes[1]); /* we only read */
  65. ok = -1;
  66. while (0 < read(daemon_filedes[0], &c, sizeof(char))) {
  67. if (c == '.')
  68. ok = 1;
  69. }
  70. fflush(stdout);
  71. if (ok == 1)
  72. exit(0); // exit ok: during daemonize, daemonizing.
  73. else
  74. exit(1); /* child reported error. exit ok: daemonize failed. */
  75. return 0; // LCOV_EXCL_LINE unreachable
  76. } else { /* Child */
  77. close(daemon_filedes[0]); /* we only write */
  78. (void) setsid(); /* Detach from controlling terminal */
  79. /*
  80. * Fork one more time, so the parent (the session group leader) can exit.
  81. * This means that we, as a non-session group leader, can never regain a
  82. * controlling terminal. This part is recommended by Stevens's
  83. * _Advanced Programming in the Unix Environment_.
  84. */
  85. if (fork() != 0) {
  86. exit(0); // exit ok: during daemonize, fork failed (2)
  87. }
  88. set_main_thread(); /* We are now the main thread. */
  89. return 1;
  90. }
  91. }
  92. /** Finish putting the process into daemon mode: drop standard fds, and tell
  93. * the parent process to exit. (Note: it's safe to call this more than once:
  94. * calls after the first are ignored. Calls start_daemon first if it hasn't
  95. * been called already.) Return true if we actually did a fork; false if we
  96. * didn't.
  97. */
  98. int
  99. finish_daemon(const char *desired_cwd)
  100. {
  101. int nullfd;
  102. char c = '.';
  103. if (finish_daemon_called)
  104. return 0;
  105. if (!start_daemon_called)
  106. start_daemon();
  107. finish_daemon_called = 1;
  108. if (!desired_cwd)
  109. desired_cwd = "/";
  110. /* Don't hold the wrong FS mounted */
  111. if (chdir(desired_cwd) < 0) {
  112. log_err(LD_GENERAL,"chdir to \"%s\" failed. Exiting.",desired_cwd);
  113. exit(1); // exit ok: during daemonize, chdir failed.
  114. }
  115. nullfd = tor_open_cloexec("/dev/null", O_RDWR, 0);
  116. if (nullfd < 0) {
  117. /* LCOV_EXCL_START */
  118. log_err(LD_GENERAL,"/dev/null can't be opened. Exiting.");
  119. exit(1); // exit ok: during daemonize, couldn't open /dev/null
  120. /* LCOV_EXCL_STOP */
  121. }
  122. /* close fds linking to invoking terminal, but
  123. * close usual incoming fds, but redirect them somewhere
  124. * useful so the fds don't get reallocated elsewhere.
  125. */
  126. if (dup2(nullfd,0) < 0 ||
  127. dup2(nullfd,1) < 0 ||
  128. dup2(nullfd,2) < 0) {
  129. /* LCOV_EXCL_START */
  130. log_err(LD_GENERAL,"dup2 failed. Exiting.");
  131. exit(1); // exit ok: during daemonize, dup2 failed.
  132. /* LCOV_EXCL_STOP */
  133. }
  134. if (nullfd > 2)
  135. close(nullfd);
  136. /* signal success */
  137. if (write(daemon_filedes[1], &c, sizeof(char)) != sizeof(char)) {
  138. log_err(LD_GENERAL,"write failed. Exiting.");
  139. }
  140. close(daemon_filedes[1]);
  141. return 0;
  142. }
  143. #else /* !(!defined(_WIN32)) */
  144. /* defined(_WIN32) */
  145. int
  146. start_daemon(void)
  147. {
  148. return 0;
  149. }
  150. int
  151. finish_daemon(const char *cp)
  152. {
  153. (void)cp;
  154. return 0;
  155. }
  156. #endif /* !defined(_WIN32) */