diff options
author | Nick Mathewson <nickm@torproject.org> | 2017-10-18 19:34:19 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2017-11-01 13:22:09 -0400 |
commit | e8682c85945b3283adb113f29f9fbd7977a052aa (patch) | |
tree | e7d327decb7696a5c896a66d66a8298d7fddfcc7 /src/tools | |
parent | fa02ea102e3ccc946d269788e88c6818e84ad6f8 (diff) | |
download | tor-e8682c85945b3283adb113f29f9fbd7977a052aa.tar.gz tor-e8682c85945b3283adb113f29f9fbd7977a052aa.zip |
Add a small library to emulate tor_run_main() with exec()
Diffstat (limited to 'src/tools')
-rw-r--r-- | src/tools/include.am | 5 | ||||
-rw-r--r-- | src/tools/tor_runner.c | 78 |
2 files changed, 83 insertions, 0 deletions
diff --git a/src/tools/include.am b/src/tools/include.am index 37936c742f..92cc3f10a2 100644 --- a/src/tools/include.am +++ b/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 diff --git a/src/tools/tor_runner.c b/src/tools/tor_runner.c new file mode 100644 index 0000000000..ee35b72df3 --- /dev/null +++ b/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 */ + } +} + |