Browse Source

Add a small library to emulate tor_run_main() with exec()

Nick Mathewson 6 years ago
parent
commit
e8682c8594
4 changed files with 85 additions and 0 deletions
  1. 1 0
      .gitignore
  2. 1 0
      configure.ac
  3. 5 0
      src/tools/include.am
  4. 78 0
      src/tools/tor_runner.c

+ 1 - 0
.gitignore

@@ -211,6 +211,7 @@ uptime-*.json
 /src/test/fuzz/lf-fuzz-*
 
 # /src/tools/
+/src/tools/libtorrunner.a
 /src/tools/tor-checkkey
 /src/tools/tor-resolve
 /src/tools/tor-cov-resolve

+ 1 - 0
configure.ac

@@ -375,6 +375,7 @@ AH_BOTTOM([
 
 
 AM_CONDITIONAL(BUILD_NT_SERVICES, test "x$bwin32" = "xtrue")
+AM_CONDITIONAL(BUILD_LIBTORRUNNER, test "x$bwin32" != "xtrue")
 
 dnl Enable C99 when compiling with MIPSpro
 AC_MSG_CHECKING([for MIPSpro compiler])

+ 5 - 0
src/tools/include.am

@@ -45,3 +45,8 @@ src_tools_tor_cov_gencert_LDADD = src/common/libor-testing.a \
 endif
 
 EXTRA_DIST += src/tools/tor-fw-helper/README
+
+if BUILD_LIBTORRUNNER
+noinst_LIBRARIES += src/tools/libtorrunner.a
+src_tools_libtorrunner_a_SOURCES = src/tools/tor_runner.c src/or/tor_api.c
+endif

+ 78 - 0
src/tools/tor_runner.c

@@ -0,0 +1,78 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "tor_api.h"
+#include "tor_api_internal.h"
+
+#include "orconfig.h"
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef __GNUC__
+#define __attribute__(x)
+#endif
+
+static void child(const tor_main_configuration_t *cfg)
+  __attribute__((noreturn));
+
+int
+tor_run_main(const tor_main_configuration_t *cfg)
+{
+  pid_t pid = fork();
+  if (pid == 0) {
+    child(cfg);
+    exit(0); /* Unreachable */
+  }
+
+  pid_t stopped_pid;
+  int status = 0;
+  do {
+    stopped_pid = waitpid(pid, &status, 0);
+  } while (stopped_pid == -1);
+
+  /* Note: these return values are not documented.  No return value is
+   * documented! */
+
+  if (stopped_pid != pid) {
+    return -99999;
+  }
+  if (WIFSTOPPED(status)) {
+    return WEXITSTATUS(status);
+  }
+  if (WIFSIGNALED(status)) {
+    return -WTERMSIG(status);
+  }
+
+  return -999988;
+}
+
+static void
+child(const tor_main_configuration_t *cfg)
+{
+  /* XXXX Close unused file descriptors. */
+
+  char **args = calloc(cfg->argc+1, sizeof(char *));
+  memcpy(args, cfg->argv, cfg->argc * sizeof(char *));
+  args[cfg->argc] = NULL;
+
+  int rv = execv(BINDIR "/tor", args);
+
+  if (rv < 0) {
+    exit(254);
+  } else {
+    abort(); /* Unreachable */
+  }
+}
+