11#define PROCESS_UNIX_PRIVATE
42#if defined(HAVE_SYS_PRCTL_H) && defined(__linux__)
140 retval = pipe(stdin_pipe);
144 "Unable to create pipe for stdin "
145 "communication with process: %s",
152 retval = pipe(stdout_pipe);
156 "Unable to create pipe for stdout "
157 "communication with process: %s",
161 close(stdin_pipe[0]);
162 close(stdin_pipe[1]);
168 retval = pipe(stderr_pipe);
172 "Unable to create pipe for stderr "
173 "communication with process: %s",
177 close(stdin_pipe[0]);
178 close(stdin_pipe[1]);
181 close(stdout_pipe[0]);
182 close(stdout_pipe[1]);
192#if defined(HAVE_SYS_PRCTL_H) && defined(__linux__)
198 prctl(PR_SET_PDEATHSIG, SIGTERM);
202 retval = dup2(stdout_pipe[1], STDOUT_FILENO);
207 retval = dup2(stderr_pipe[1], STDERR_FILENO);
212 retval = dup2(stdin_pipe[0], STDIN_FILENO);
217 close(stderr_pipe[0]);
218 close(stderr_pipe[1]);
219 close(stdout_pipe[0]);
220 close(stdout_pipe[1]);
221 close(stdin_pipe[0]);
222 close(stdin_pipe[1]);
239 process_environment_free(env);
242 fprintf(stderr,
"Error from child process: %s", strerror(errno));
249 "Failed to create child process: %s", strerror(errno));
252 close(stdin_pipe[0]);
253 close(stdin_pipe[1]);
256 close(stdout_pipe[0]);
257 close(stdout_pipe[1]);
260 close(stderr_pipe[0]);
261 close(stderr_pipe[1]);
267 unix_process->
pid = pid;
270 unix_process->
waitpid = set_waitpid_callback(pid,
276 retval = close(stdout_pipe[1]);
279 log_warn(
LD_PROCESS,
"Failed to close write end of standard out pipe: %s",
285 retval = close(stderr_pipe[1]);
289 "Failed to close write end of standard error pipe: %s",
295 retval = close(stdin_pipe[0]);
298 log_warn(
LD_PROCESS,
"Failed to close read end of standard in pipe: %s",
334 if (BUG(unix_process->
waitpid == NULL))
342 ret = kill(unix_process->
pid, SIGTERM);
345 log_warn(
LD_PROCESS,
"Unable to terminate process: %s",
364 return (process_pid_t)unix_process->
pid;
488 if (event_add(handle->
event, NULL))
490 "Unable to add libevent event for handle.");
500 if (handle->
event == NULL)
503 if (event_del(handle->
event))
505 "Unable to delete libevent event for handle.");
515 if (event_add(handle->
event, NULL))
517 "Unable to add libevent event for handle.");
529 if (handle->
event == NULL)
532 if (event_del(handle->
event))
534 "Unable to delete libevent event for handle.");
570 event_callback_fn callback)
577 if (fcntl(handle->
fd, F_SETFL, O_NONBLOCK) < 0) {
578 log_warn(
LD_PROCESS,
"Unable mark Unix handle as non-blocking: %s",
613 "Unable to read data: %s", strerror(error));
647 log_warn(
LD_PROCESS,
"Unable to close standard in");
657 log_warn(
LD_PROCESS,
"Unable to close standard out");
667 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)