11#define PROCESS_UNIX_PRIVATE
42#if defined(HAVE_SYS_PRCTL_H) && defined(__linux__)
142 retval = tor_pipe_cloexec(stdin_pipe);
146 "Unable to create pipe for stdin "
147 "communication with process: %s",
154 retval = tor_pipe_cloexec(stdout_pipe);
158 "Unable to create pipe for stdout "
159 "communication with process: %s",
163 close(stdin_pipe[0]);
164 close(stdin_pipe[1]);
170 retval = tor_pipe_cloexec(stderr_pipe);
174 "Unable to create pipe for stderr "
175 "communication with process: %s",
179 close(stdin_pipe[0]);
180 close(stdin_pipe[1]);
183 close(stdout_pipe[0]);
184 close(stdout_pipe[1]);
194#if defined(HAVE_SYS_PRCTL_H) && defined(__linux__)
200 prctl(PR_SET_PDEATHSIG, SIGTERM);
204 retval = dup2(stdout_pipe[1], STDOUT_FILENO);
209 retval = dup2(stderr_pipe[1], STDERR_FILENO);
214 retval = dup2(stdin_pipe[0], STDIN_FILENO);
219 close(stderr_pipe[0]);
220 close(stderr_pipe[1]);
221 close(stdout_pipe[0]);
222 close(stdout_pipe[1]);
223 close(stdin_pipe[0]);
224 close(stdin_pipe[1]);
241 process_environment_free(env);
244 fprintf(stderr,
"Error from child process: %s", strerror(errno));
251 "Failed to create child process: %s", strerror(errno));
254 close(stdin_pipe[0]);
255 close(stdin_pipe[1]);
258 close(stdout_pipe[0]);
259 close(stdout_pipe[1]);
262 close(stderr_pipe[0]);
263 close(stderr_pipe[1]);
269 unix_process->
pid = pid;
272 unix_process->
waitpid = set_waitpid_callback(pid,
278 retval = close(stdout_pipe[1]);
281 log_warn(
LD_PROCESS,
"Failed to close write end of standard out pipe: %s",
287 retval = close(stderr_pipe[1]);
291 "Failed to close write end of standard error pipe: %s",
297 retval = close(stdin_pipe[0]);
300 log_warn(
LD_PROCESS,
"Failed to close read end of standard in pipe: %s",
336 if (BUG(unix_process->
waitpid == NULL))
344 ret = kill(unix_process->
pid, SIGTERM);
347 log_warn(
LD_PROCESS,
"Unable to terminate process: %s",
366 return (process_pid_t)unix_process->
pid;
490 if (event_add(handle->
event, NULL))
492 "Unable to add libevent event for handle.");
502 if (handle->
event == NULL)
505 if (event_del(handle->
event))
507 "Unable to delete libevent event for handle.");
517 if (event_add(handle->
event, NULL))
519 "Unable to add libevent event for handle.");
531 if (handle->
event == NULL)
534 if (event_del(handle->
event))
536 "Unable to delete libevent event for handle.");
572 event_callback_fn callback)
579 if (fcntl(handle->
fd, F_SETFL, O_NONBLOCK) < 0) {
580 log_warn(
LD_PROCESS,
"Unable mark Unix handle as non-blocking: %s",
615 "Unable to read data: %s", strerror(error));
649 log_warn(
LD_PROCESS,
"Unable to close standard in");
659 log_warn(
LD_PROCESS,
"Unable to close standard out");
669 log_warn(
LD_PROCESS,
"Unable to close standard error");
size_t buf_datalen(const buf_t *buf)
Header file for buffers.c.
int buf_read_from_pipe(buf_t *buf, int fd, size_t at_most, int *reached_eof, int *socket_error)
int buf_flush_to_pipe(buf_t *buf, int fd, size_t sz)
Header file for buffers_net.c.
Macro definitions for MIN, MAX, and CLAMP.
struct event_base * tor_libevent_get_base(void)
Header for compat_libevent.c.
void process_notify_event_stdout(process_t *process)
void process_notify_event_exit(process_t *process, process_exit_code_t exit_code)
void process_notify_event_stderr(process_t *process)
process_environment_t * process_get_environment(const process_t *process)
void process_notify_event_stdin(process_t *process)
char ** process_get_argv(const process_t *process)
process_unix_t * process_get_unix_process(const process_t *process)
#define PROCESS_MAX_WRITE
STATIC void stdin_write_callback(evutil_socket_t fd, short event, void *data)
int process_unix_write(process_t *process, buf_t *buffer)
bool process_unix_terminate(process_t *process)
STATIC void process_unix_setup_handle(process_t *process, process_unix_handle_t *handle, short flags, event_callback_fn callback)
int process_unix_read_stderr(process_t *process, buf_t *buffer)
process_pid_t process_unix_get_pid(process_t *process)
int process_unix_read_stdout(process_t *process, buf_t *buffer)
STATIC void stdout_read_callback(evutil_socket_t fd, short event, void *data)
STATIC void process_unix_start_writing(process_unix_handle_t *handle)
void process_unix_free_(process_unix_t *unix_process)
STATIC void process_unix_stop_reading(process_unix_handle_t *handle)
STATIC void stderr_read_callback(evutil_socket_t fd, short event, void *data)
STATIC void process_unix_waitpid_callback(int status, void *data)
STATIC void process_unix_start_reading(process_unix_handle_t *handle)
STATIC int process_unix_read_handle(process_t *process, process_unix_handle_t *handle, buf_t *buffer)
STATIC void process_unix_stop_writing(process_unix_handle_t *handle)
process_status_t process_unix_exec(process_t *process)
STATIC bool process_unix_close_file_descriptors(process_unix_t *unix_process)
process_unix_t * process_unix_new(void)
Header for process_unix.c.
char ** unixoid_environment_block
process_unix_handle_t stdin_handle
waitpid_callback_t * waitpid
process_unix_handle_t stderr_handle
process_unix_handle_t stdout_handle
Macros to manage assertions, fatal and non-fatal.
void clear_waitpid_callback(waitpid_callback_t *ent)