Tor 0.4.9.0-alpha-dev
tor_runner.c
Go to the documentation of this file.
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-2021, The Tor Project, Inc. */
5/* See LICENSE for licensing information */
6
7/**
8 * @file tor_runner.c
9 * @brief Experimental module to emulate tor_run_main() API with fork+exec
10 *
11 * The functions here are meant to allow the application developer to
12 * use the tor_run_main() API without having to care whether Tor is
13 * running in-process or out-of-process. For in-process usage, the
14 * developer can link Tor as a library and call tor_run_main(); for
15 * out-of-process usage, the developer can link this library instead.
16 *
17 * This interface is EXPERIMENTAL; please let us know if you would like
18 * to depend on it. We don't know yet whether it will be reliable in
19 * practice.
20 */
21
22/* NOTE: This module is supposed to work without the standard Tor utility
23 * functions. Don't add more dependencies!
24 */
25
26#include "feature/api/tor_api.h"
28
29#include "orconfig.h"
30#ifdef HAVE_UNISTD_H
31#include <unistd.h>
32#endif
33#ifdef HAVE_SYS_WAIT_H
34#include <sys/wait.h>
35#endif
36#ifdef HAVE_SYS_SOCKET_H
37#include <sys/socket.h>
38#endif
39#include <stdlib.h>
40#include <string.h>
41
42#ifndef __GNUC__
43#define __attribute__(x)
44#endif
45
46static void child(const tor_main_configuration_t *cfg)
47 __attribute__((noreturn));
48
49const char *
51{
52 return "libtorrunner " VERSION;
53}
54
55int
57{
58 pid_t pid = fork();
59 if (pid == 0) {
60 child(cfg);
61 exit(0); /* Unreachable */
62 }
63
64 pid_t stopped_pid;
65 int status = 0;
66 do {
67 stopped_pid = waitpid(pid, &status, 0);
68 } while (stopped_pid == -1);
69
70 /* Note: these return values are not documented. No return value is
71 * documented! */
72
73 if (stopped_pid != pid) {
74 return -99999;
75 }
76 if (WIFSTOPPED(status)) {
77 return WEXITSTATUS(status);
78 }
79 if (WIFSIGNALED(status)) {
80 return -WTERMSIG(status);
81 }
82
83 return -999988;
84}
85
86/* circumlocution to avoid getting warned about calling calloc instead of
87 * tor_calloc. */
88#define real_calloc calloc
89#define real_free free
90
91static void
92child(const tor_main_configuration_t *cfg)
93{
94 /* XXXX Close unused file descriptors. */
95
96 char **args = real_calloc(cfg->argc + cfg->argc_owned+1, sizeof(char *));
97 memcpy(args, cfg->argv, cfg->argc * sizeof(char *));
98 if (cfg->argc_owned)
99 memcpy(args + cfg->argc, cfg->argv_owned,
100 cfg->argc_owned * sizeof(char *));
101
102 args[cfg->argc + cfg->argc_owned] = NULL;
103
104 int rv = execv(BINDIR "/tor", args);
105
106 if (rv < 0) {
107 real_free(args);
108 exit(254);
109 } else {
110 abort(); /* Unreachable */
111 }
112}
Public C API for the Tor network service.
Internal declarations for in-process Tor API.
const char * tor_api_get_provider_version(void)
Definition: tor_runner.c:50
int tor_run_main(const tor_main_configuration_t *cfg)
Definition: tor_runner.c:56