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 */
9 * @brief Experimental module to emulate tor_run_main() API with fork+exec
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.
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
22 /* NOTE: This module is supposed to work without the standard Tor utility
23 * functions. Don't add more dependencies!
26 #include "feature/api/tor_api.h"
27 #include "feature/api/tor_api_internal.h"
33 #ifdef HAVE_SYS_WAIT_H
36 #ifdef HAVE_SYS_SOCKET_H
37 #include <sys/socket.h>
43 #define __attribute__(x)
46 static void child(const tor_main_configuration_t
*cfg
)
47 __attribute__((noreturn
));
50 tor_api_get_provider_version(void)
52 return "libtorrunner " VERSION
;
56 tor_run_main(const tor_main_configuration_t
*cfg
)
61 exit(0); /* Unreachable */
67 stopped_pid
= waitpid(pid
, &status
, 0);
68 } while (stopped_pid
== -1);
70 /* Note: these return values are not documented. No return value is
73 if (stopped_pid
!= pid
) {
76 if (WIFSTOPPED(status
)) {
77 return WEXITSTATUS(status
);
79 if (WIFSIGNALED(status
)) {
80 return -WTERMSIG(status
);
86 /* circumlocution to avoid getting warned about calling calloc instead of
88 #define real_calloc calloc
89 #define real_free free
92 child(const tor_main_configuration_t
*cfg
)
94 /* XXXX Close unused file descriptors. */
96 char **args
= real_calloc(cfg
->argc
+ cfg
->argc_owned
+1, sizeof(char *));
97 memcpy(args
, cfg
->argv
, cfg
->argc
* sizeof(char *));
99 memcpy(args
+ cfg
->argc
, cfg
->argv_owned
,
100 cfg
->argc_owned
* sizeof(char *));
102 args
[cfg
->argc
+ cfg
->argc_owned
] = NULL
;
104 int rv
= execv(BINDIR
"/tor", args
);
110 abort(); /* Unreachable */