tor  0.4.2.0-alpha-dev
process_unix.c
Go to the documentation of this file.
1 /* Copyright (c) 2003, Roger Dingledine
2  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3  * Copyright (c) 2007-2019, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
5 
11 #define PROCESS_UNIX_PRIVATE
12 #include "lib/intmath/cmp.h"
13 #include "lib/buf/buffers.h"
14 #include "lib/net/buffers_net.h"
17 #include "lib/log/log.h"
18 #include "lib/log/util_bug.h"
19 #include "lib/process/process.h"
21 #include "lib/process/waitpid.h"
22 #include "lib/process/env.h"
23 
24 #include <stdio.h>
25 
26 #ifdef HAVE_STRING_H
27 #include <string.h>
28 #endif
29 
30 #ifdef HAVE_ERRNO_H
31 #include <errno.h>
32 #endif
33 
34 #ifdef HAVE_UNISTD_H
35 #include <unistd.h>
36 #endif
37 
38 #ifdef HAVE_FCNTL_H
39 #include <fcntl.h>
40 #endif
41 
42 #if defined(HAVE_SYS_PRCTL_H) && defined(__linux__)
43 #include <sys/prctl.h>
44 #endif
45 
46 #if HAVE_SIGNAL_H
47 #include <signal.h>
48 #endif
49 
50 #ifndef _WIN32
51 
53 #define DEFAULT_MAX_FD 256
54 
58  int fd;
59 
62 
64  struct event *event;
65 
67  bool is_writing;
68 };
69 
74 
77 
80 
82  pid_t pid;
83 
86 };
87 
91 {
92  process_unix_t *unix_process;
93  unix_process = tor_malloc_zero(sizeof(process_unix_t));
94 
95  unix_process->stdin_handle.fd = -1;
96  unix_process->stderr_handle.fd = -1;
97  unix_process->stdout_handle.fd = -1;
98 
99  return unix_process;
100 }
101 
103 void
105 {
106  if (! unix_process)
107  return;
108 
109  /* Clean up our waitpid callback. */
110  clear_waitpid_callback(unix_process->waitpid);
111 
112  /* FIXME(ahf): Refactor waitpid code? */
113  unix_process->waitpid = NULL;
114 
115  /* Close all our file descriptors. */
117 
118  tor_event_free(unix_process->stdout_handle.event);
119  tor_event_free(unix_process->stderr_handle.event);
120  tor_event_free(unix_process->stdin_handle.event);
121 
122  tor_free(unix_process);
123 }
124 
132 {
133  static int max_fd = -1;
134 
135  process_unix_t *unix_process;
136  pid_t pid;
137  int stdin_pipe[2];
138  int stdout_pipe[2];
139  int stderr_pipe[2];
140  int retval, fd;
141 
142  unix_process = process_get_unix_process(process);
143 
144  /* Create standard in pipe. */
145  retval = pipe(stdin_pipe);
146 
147  if (-1 == retval) {
148  log_warn(LD_PROCESS,
149  "Unable to create pipe for stdin "
150  "communication with process: %s",
151  strerror(errno));
152 
153  return PROCESS_STATUS_ERROR;
154  }
155 
156  /* Create standard out pipe. */
157  retval = pipe(stdout_pipe);
158 
159  if (-1 == retval) {
160  log_warn(LD_PROCESS,
161  "Unable to create pipe for stdout "
162  "communication with process: %s",
163  strerror(errno));
164 
166  close(stdin_pipe[0]);
167  close(stdin_pipe[1]);
168 
169  return PROCESS_STATUS_ERROR;
170  }
171 
172  /* Create standard error pipe. */
173  retval = pipe(stderr_pipe);
174 
175  if (-1 == retval) {
176  log_warn(LD_PROCESS,
177  "Unable to create pipe for stderr "
178  "communication with process: %s",
179  strerror(errno));
180 
182  close(stdin_pipe[0]);
183  close(stdin_pipe[1]);
184 
186  close(stdout_pipe[0]);
187  close(stdout_pipe[1]);
188 
189  return PROCESS_STATUS_ERROR;
190  }
191 
192 #ifdef _SC_OPEN_MAX
193  if (-1 == max_fd) {
194  max_fd = (int)sysconf(_SC_OPEN_MAX);
195 
196  if (max_fd == -1) {
197  max_fd = DEFAULT_MAX_FD;
198  log_warn(LD_PROCESS,
199  "Cannot find maximum file descriptor, assuming: %d", max_fd);
200  }
201  }
202 #else /* !(defined(_SC_OPEN_MAX)) */
203  max_fd = DEFAULT_MAX_FD;
204 #endif /* defined(_SC_OPEN_MAX) */
205 
206  pid = fork();
207 
208  if (0 == pid) {
209  /* This code is running in the child process context. */
210 
211 #if defined(HAVE_SYS_PRCTL_H) && defined(__linux__)
212  /* Attempt to have the kernel issue a SIGTERM if the parent
213  * goes away. Certain attributes of the binary being execve()ed
214  * will clear this during the execve() call, but it's better
215  * than nothing.
216  */
217  prctl(PR_SET_PDEATHSIG, SIGTERM);
218 #endif /* defined(HAVE_SYS_PRCTL_H) && defined(__linux__) */
219 
220  /* Link process stdout to the write end of the pipe. */
221  retval = dup2(stdout_pipe[1], STDOUT_FILENO);
222  if (-1 == retval)
223  goto error;
224 
225  /* Link process stderr to the write end of the pipe. */
226  retval = dup2(stderr_pipe[1], STDERR_FILENO);
227  if (-1 == retval)
228  goto error;
229 
230  /* Link process stdin to the read end of the pipe */
231  retval = dup2(stdin_pipe[0], STDIN_FILENO);
232  if (-1 == retval)
233  goto error;
234 
235  /* Close our pipes now after they have been dup2()'ed. */
236  close(stderr_pipe[0]);
237  close(stderr_pipe[1]);
238  close(stdout_pipe[0]);
239  close(stdout_pipe[1]);
240  close(stdin_pipe[0]);
241  close(stdin_pipe[1]);
242 
243  /* Close all other fds, including the read end of the pipe. XXX: We should
244  * now be doing enough FD_CLOEXEC setting to make this needless.
245  */
246  for (fd = STDERR_FILENO + 1; fd < max_fd; fd++)
247  close(fd);
248 
249  /* Create the argv value for our new process. */
250  char **argv = process_get_argv(process);
251 
252  /* Create the env value for our new process. */
254 
255  /* Call the requested program. */
256  retval = execve(argv[0], argv, env->unixoid_environment_block);
257 
258  /* If we made it here it is because execve failed :-( */
259  if (-1 == retval)
260  fprintf(stderr, "Call to execve() failed: %s", strerror(errno));
261 
262  tor_free(argv);
263  process_environment_free(env);
264 
265  tor_assert_unreached();
266 
267  error:
268  /* LCOV_EXCL_START */
269  fprintf(stderr, "Error from child process: %s", strerror(errno));
270  _exit(1);
271  /* LCOV_EXCL_STOP */
272  }
273 
274  /* We are in the parent process. */
275  if (-1 == pid) {
276  log_warn(LD_PROCESS,
277  "Failed to create child process: %s", strerror(errno));
278 
280  close(stdin_pipe[0]);
281  close(stdin_pipe[1]);
282 
284  close(stdout_pipe[0]);
285  close(stdout_pipe[1]);
286 
288  close(stderr_pipe[0]);
289  close(stderr_pipe[1]);
290 
291  return PROCESS_STATUS_ERROR;
292  }
293 
294  /* Register our PID. */
295  unix_process->pid = pid;
296 
297  /* Setup waitpid callbacks. */
298  unix_process->waitpid = set_waitpid_callback(pid,
300  process);
301 
302  /* Handle standard out. */
303  unix_process->stdout_handle.fd = stdout_pipe[0];
304  retval = close(stdout_pipe[1]);
305 
306  if (-1 == retval) {
307  log_warn(LD_PROCESS, "Failed to close write end of standard out pipe: %s",
308  strerror(errno));
309  }
310 
311  /* Handle standard error. */
312  unix_process->stderr_handle.fd = stderr_pipe[0];
313  retval = close(stderr_pipe[1]);
314 
315  if (-1 == retval) {
316  log_warn(LD_PROCESS,
317  "Failed to close write end of standard error pipe: %s",
318  strerror(errno));
319  }
320 
321  /* Handle standard in. */
322  unix_process->stdin_handle.fd = stdin_pipe[1];
323  retval = close(stdin_pipe[0]);
324 
325  if (-1 == retval) {
326  log_warn(LD_PROCESS, "Failed to close read end of standard in pipe: %s",
327  strerror(errno));
328  }
329 
330  /* Setup our handles. */
332  &unix_process->stdout_handle,
333  EV_READ|EV_PERSIST,
335 
337  &unix_process->stderr_handle,
338  EV_READ|EV_PERSIST,
340 
342  &unix_process->stdin_handle,
343  EV_WRITE|EV_PERSIST,
345 
346  /* Start reading from standard out and standard error. */
349 
350  return PROCESS_STATUS_RUNNING;
351 }
352 
354 bool
356 {
357  tor_assert(process);
358 
359  process_unix_t *unix_process = process_get_unix_process(process);
360 
361  /* All running processes should have a waitpid. */
362  if (BUG(unix_process->waitpid == NULL))
363  return false;
364 
365  bool success = true;
366 
367  /* Send a SIGTERM to our child process. */
368  int ret;
369 
370  ret = kill(unix_process->pid, SIGTERM);
371 
372  if (ret == -1) {
373  log_warn(LD_PROCESS, "Unable to terminate process: %s",
374  strerror(errno));
375  success = false;
376  }
377 
378  /* Close all our FD's. */
379  if (! process_unix_close_file_descriptors(unix_process))
380  success = false;
381 
382  return success;
383 }
384 
386 process_pid_t
388 {
389  tor_assert(process);
390 
391  process_unix_t *unix_process = process_get_unix_process(process);
392  return (process_pid_t)unix_process->pid;
393 }
394 
397 int
398 process_unix_write(process_t *process, buf_t *buffer)
399 {
400  tor_assert(process);
401  tor_assert(buffer);
402 
403  process_unix_t *unix_process = process_get_unix_process(process);
404 
405  size_t buffer_flush_len = buf_datalen(buffer);
406  const size_t max_to_write = MIN(PROCESS_MAX_WRITE, buffer_flush_len);
407 
408  /* If we have data to write (when buffer_flush_len > 0) and we are not
409  * currently getting file descriptor events from the kernel, we tell the
410  * kernel to start notifying us about when we can write to our file
411  * descriptor and return. */
412  if (buffer_flush_len > 0 && ! unix_process->stdin_handle.is_writing) {
414  return 0;
415  }
416 
417  /* We don't have any data to write, but the kernel is currently notifying us
418  * about whether we are able to write or not. Tell the kernel to stop
419  * notifying us until we have data to write. */
420  if (buffer_flush_len == 0 && unix_process->stdin_handle.is_writing) {
421  process_unix_stop_writing(&unix_process->stdin_handle);
422  return 0;
423  }
424 
425  /* We have data to write and the kernel have told us to write it. */
426  return buf_flush_to_pipe(buffer,
427  process_get_unix_process(process)->stdin_handle.fd,
428  max_to_write, &buffer_flush_len);
429 }
430 
433 int
434 process_unix_read_stdout(process_t *process, buf_t *buffer)
435 {
436  tor_assert(process);
437  tor_assert(buffer);
438 
439  process_unix_t *unix_process = process_get_unix_process(process);
440 
441  return process_unix_read_handle(process,
442  &unix_process->stdout_handle,
443  buffer);
444 }
445 
448 int
449 process_unix_read_stderr(process_t *process, buf_t *buffer)
450 {
451  tor_assert(process);
452  tor_assert(buffer);
453 
454  process_unix_t *unix_process = process_get_unix_process(process);
455 
456  return process_unix_read_handle(process,
457  &unix_process->stderr_handle,
458  buffer);
459 }
460 
465 STATIC void
466 stdout_read_callback(evutil_socket_t fd, short event, void *data)
467 {
468  (void)fd;
469  (void)event;
470 
471  process_t *process = data;
472  tor_assert(process);
473 
475 }
476 
481 STATIC void
482 stderr_read_callback(evutil_socket_t fd, short event, void *data)
483 {
484  (void)fd;
485  (void)event;
486 
487  process_t *process = data;
488  tor_assert(process);
489 
491 }
492 
497 STATIC void
498 stdin_write_callback(evutil_socket_t fd, short event, void *data)
499 {
500  (void)fd;
501  (void)event;
502 
503  process_t *process = data;
504  tor_assert(process);
505 
507 }
508 
511 STATIC void
513 {
514  tor_assert(handle);
515 
516  if (event_add(handle->event, NULL))
517  log_warn(LD_PROCESS,
518  "Unable to add libevent event for handle.");
519 }
520 
523 STATIC void
525 {
526  tor_assert(handle);
527 
528  if (handle->event == NULL)
529  return;
530 
531  if (event_del(handle->event))
532  log_warn(LD_PROCESS,
533  "Unable to delete libevent event for handle.");
534 }
535 
538 STATIC void
540 {
541  tor_assert(handle);
542 
543  if (event_add(handle->event, NULL))
544  log_warn(LD_PROCESS,
545  "Unable to add libevent event for handle.");
546 
547  handle->is_writing = true;
548 }
549 
552 STATIC void
554 {
555  tor_assert(handle);
556 
557  if (handle->event == NULL)
558  return;
559 
560  if (event_del(handle->event))
561  log_warn(LD_PROCESS,
562  "Unable to delete libevent event for handle.");
563 
564  handle->is_writing = false;
565 }
566 
570 STATIC void
571 process_unix_waitpid_callback(int status, void *data)
572 {
573  tor_assert(data);
574 
575  process_t *process = data;
576  process_unix_t *unix_process = process_get_unix_process(process);
577 
578  /* Remove our waitpid callback. */
579  clear_waitpid_callback(unix_process->waitpid);
580  unix_process->waitpid = NULL;
581 
582  /* Notify our process. */
583  process_notify_event_exit(process, status);
584 
585  /* Make sure you don't modify the process after we have called
586  * process_notify_event_exit() on it, to allow users to process_free() it in
587  * the exit callback. */
588 }
589 
594 STATIC void
596  process_unix_handle_t *handle,
597  short flags,
598  event_callback_fn callback)
599 {
600  tor_assert(process);
601  tor_assert(handle);
602  tor_assert(callback);
603 
604  /* Put our file descriptor into non-blocking mode. */
605  if (fcntl(handle->fd, F_SETFL, O_NONBLOCK) < 0) {
606  log_warn(LD_PROCESS, "Unable mark Unix handle as non-blocking: %s",
607  strerror(errno));
608  }
609 
610  /* Setup libevent event. */
611  handle->event = tor_event_new(tor_libevent_get_base(),
612  handle->fd,
613  flags,
614  callback,
615  process);
616 }
617 
620 STATIC int
622  process_unix_handle_t *handle,
623  buf_t *buffer)
624 {
625  tor_assert(process);
626  tor_assert(handle);
627  tor_assert(buffer);
628 
629  int ret = 0;
630  int eof = 0;
631  int error = 0;
632 
633  ret = buf_read_from_pipe(buffer,
634  handle->fd,
636  &eof,
637  &error);
638 
639  if (error)
640  log_warn(LD_PROCESS,
641  "Unable to read data: %s", strerror(error));
642 
643  if (eof) {
644  handle->reached_eof = true;
646  }
647 
648  return ret;
649 }
650 
653 STATIC bool
655 {
656  tor_assert(unix_process);
657 
658  int ret;
659  bool success = true;
660 
661  /* Stop reading and writing before we close() our
662  * file descriptors. */
663  if (! unix_process->stdout_handle.reached_eof)
665 
666  if (! unix_process->stderr_handle.reached_eof)
668 
669  if (unix_process->stdin_handle.is_writing)
670  process_unix_stop_writing(&unix_process->stdin_handle);
671 
672  if (unix_process->stdin_handle.fd != -1) {
673  ret = close(unix_process->stdin_handle.fd);
674  if (ret == -1) {
675  log_warn(LD_PROCESS, "Unable to close standard in");
676  success = false;
677  }
678 
679  unix_process->stdin_handle.fd = -1;
680  }
681 
682  if (unix_process->stdout_handle.fd != -1) {
683  ret = close(unix_process->stdout_handle.fd);
684  if (ret == -1) {
685  log_warn(LD_PROCESS, "Unable to close standard out");
686  success = false;
687  }
688 
689  unix_process->stdout_handle.fd = -1;
690  }
691 
692  if (unix_process->stderr_handle.fd != -1) {
693  ret = close(unix_process->stderr_handle.fd);
694  if (ret == -1) {
695  log_warn(LD_PROCESS, "Unable to close standard error");
696  success = false;
697  }
698 
699  unix_process->stderr_handle.fd = -1;
700  }
701 
702  return success;
703 }
704 
705 #endif /* !defined(_WIN32) */
Header for process_unix.c.
STATIC void process_unix_start_reading(process_unix_handle_t *handle)
Definition: process_unix.c:512
int process_unix_write(process_t *process, buf_t *buffer)
Definition: process_unix.c:398
process_unix_t * process_unix_new(void)
Definition: process_unix.c:90
STATIC void stderr_read_callback(evutil_socket_t fd, short event, void *data)
Definition: process_unix.c:482
waitpid_callback_t * waitpid
Definition: process_unix.c:85
Header for smartlist.c.
#define PROCESS_MAX_READ
Definition: process.h:22
Headers for waitpid.c.
process_unix_handle_t stderr_handle
Definition: process_unix.c:79
Macro definitions for MIN, MAX, and CLAMP.
int buf_flush_to_pipe(buf_t *buf, int fd, size_t sz, size_t *buf_flushlen)
Definition: buffers_net.c:257
STATIC void process_unix_start_writing(process_unix_handle_t *handle)
Definition: process_unix.c:539
void clear_waitpid_callback(waitpid_callback_t *ent)
Definition: waitpid.c:98
#define tor_free(p)
Definition: malloc.h:52
Header for env.c.
void process_notify_event_stderr(process_t *process)
Definition: process.c:593
STATIC void stdout_read_callback(evutil_socket_t fd, short event, void *data)
Definition: process_unix.c:466
void process_notify_event_stdin(process_t *process)
Definition: process.c:609
#define DEFAULT_MAX_FD
Definition: process_unix.c:53
char ** unixoid_environment_block
Definition: env.h:27
tor_assert(buffer)
bool process_unix_terminate(process_t *process)
Definition: process_unix.c:355
char ** process_get_argv(const process_t *process)
Definition: process.c:439
void process_notify_event_stdout(process_t *process)
Definition: process.c:576
#define LD_PROCESS
Definition: log.h:113
int process_unix_read_stderr(process_t *process, buf_t *buffer)
Definition: process_unix.c:449
Header file for buffers_net.c.
int buf_read_from_pipe(buf_t *buf, int fd, size_t at_most, int *reached_eof, int *socket_error)
Definition: buffers_net.c:269
Header for process.c.
STATIC bool process_unix_close_file_descriptors(process_unix_t *unix_process)
Definition: process_unix.c:654
process_status_t
Definition: process.h:24
int process_unix_read_stdout(process_t *process, buf_t *buffer)
Definition: process_unix.c:434
process_unix_handle_t stdout_handle
Definition: process_unix.c:76
void process_unix_free_(process_unix_t *unix_process)
Definition: process_unix.c:104
STATIC void stdin_write_callback(evutil_socket_t fd, short event, void *data)
Definition: process_unix.c:498
process_unix_t * process_get_unix_process(const process_t *process)
Definition: process.c:510
process_status_t process_unix_exec(process_t *process)
Definition: process_unix.c:131
process_environment_t * process_get_environment(const process_t *process)
Definition: process.c:501
struct event * event
Definition: process_unix.c:64
STATIC void process_unix_stop_writing(process_unix_handle_t *handle)
Definition: process_unix.c:553
Header file for buffers.c.
STATIC int process_unix_read_handle(process_t *process, process_unix_handle_t *handle, buf_t *buffer)
Definition: process_unix.c:621
STATIC void process_unix_waitpid_callback(int status, void *data)
Definition: process_unix.c:571
Headers for log.c.
STATIC void process_unix_setup_handle(process_t *process, process_unix_handle_t *handle, short flags, event_callback_fn callback)
Definition: process_unix.c:595
Header for compat_libevent.c.
void process_notify_event_exit(process_t *process, process_exit_code_t exit_code)
Definition: process.c:622
Macros to manage assertions, fatal and non-fatal.
STATIC void process_unix_stop_reading(process_unix_handle_t *handle)
Definition: process_unix.c:524
process_pid_t process_unix_get_pid(process_t *process)
Definition: process_unix.c:387
process_unix_handle_t stdin_handle
Definition: process_unix.c:73
#define PROCESS_MAX_WRITE
Definition: process.h:19