Tor  0.4.7.0-alpha-dev
process.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-2021, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
5 
6 /**
7  * \file process.c
8  * \brief Module for working with other processes.
9  **/
10 
11 #define PROCESS_PRIVATE
12 #include "lib/buf/buffers.h"
13 #include "lib/net/buffers_net.h"
15 #include "lib/log/log.h"
16 #include "lib/log/util_bug.h"
17 #include "lib/process/process.h"
20 #include "lib/process/env.h"
21 
22 #ifdef HAVE_STDDEF_H
23 #include <stddef.h>
24 #endif
25 
26 /** A list of all <b>process_t</b> instances currently allocated. */
28 
29 /**
30  * Boolean. If true, then Tor may call execve or CreateProcess via
31  * tor_spawn_background.
32  **/
34 
35 /** Structure to represent a child process. */
36 struct process_t {
37  /** Process status. */
39 
40  /** Which protocol is the process using? */
42 
43  /** Which function to call when we have data ready from stdout? */
44  process_read_callback_t stdout_read_callback;
45 
46  /** Which function to call when we have data ready from stderr? */
47  process_read_callback_t stderr_read_callback;
48 
49  /** Which function call when our process terminated? */
50  process_exit_callback_t exit_callback;
51 
52  /** Our exit code when the process have terminated. */
53  process_exit_code_t exit_code;
54 
55  /** Name of the command we want to execute (for example: /bin/ls). */
56  char *command;
57 
58  /** The arguments used for the new process. The format here is one argument
59  * per element of the smartlist_t. On Windows these arguments are combined
60  * together using the <b>tor_join_win_cmdline</b> function. On Unix the
61  * process name (argv[0]) and the trailing NULL is added automatically before
62  * the process is executed. */
64 
65  /** The environment used for the new process. */
67 
68  /** Buffer to store data from stdout when it is read. */
69  buf_t *stdout_buffer;
70 
71  /** Buffer to store data from stderr when it is read. */
72  buf_t *stderr_buffer;
73 
74  /** Buffer to store data to stdin before it is written. */
75  buf_t *stdin_buffer;
76 
77  /** Do we need to store some custom data with the process? */
78  void *data;
79 
80 #ifndef _WIN32
81  /** Our Unix process handle. */
83 #else
84  /** Our Win32 process handle. */
85  process_win32_t *win32_process;
86 #endif /* !defined(_WIN32) */
87 };
88 
89 /** Convert a given process status in <b>status</b> to its string
90  * representation. */
91 const char *
93 {
94  switch (status) {
96  return "not running";
98  return "running";
100  return "error";
101  }
102 
103  /* LCOV_EXCL_START */
104  tor_assert_unreached();
105  return NULL;
106  /* LCOV_EXCL_STOP */
107 }
108 
109 /** Convert a given process protocol in <b>protocol</b> to its string
110  * representation. */
111 const char *
113 {
114  switch (protocol) {
116  return "Line";
118  return "Raw";
119  }
120 
121  /* LCOV_EXCL_START */
122  tor_assert_unreached();
123  return NULL;
124  /* LCOV_EXCL_STOP */
125 }
126 
127 /**
128  * Turn off may_spawn_background_process, so that all future calls to
129  * tor_spawn_background are guaranteed to fail.
130  **/
131 void
133 {
135 }
136 
137 /** Initialize the Process subsystem. This function initializes the Process
138  * subsystem's global state. For cleaning up, <b>process_free_all()</b> should
139  * be called. */
140 void
142 {
144 
145 #ifdef _WIN32
146  process_win32_init();
147 #endif
148 }
149 
150 /** Free up all resources that is handled by the Process subsystem. Note that
151  * this call does not terminate already running processes. */
152 void
154 {
155 #ifdef _WIN32
156  process_win32_deinit();
157 #endif
158 
159  SMARTLIST_FOREACH(processes, process_t *, x, process_free(x));
160  smartlist_free(processes);
161 }
162 
163 /** Get a list of all processes. This function returns a smartlist of
164  * <b>process_t</b> containing all the currently allocated processes. */
165 const smartlist_t *
167 {
168  return processes;
169 }
170 
171 /** Allocate and initialize a new process. This function returns a newly
172  * allocated and initialized process data, which can be used to configure and
173  * later run a subprocess of Tor. Use the various <b>process_set_*()</b>
174  * methods to configure it and run the process using <b>process_exec()</b>. Use
175  * <b>command</b> to specify the path to the command to run. You can either
176  * specify an absolute path to the command or relative where Tor will use the
177  * underlying operating system's functionality for finding the command to run.
178  * */
179 process_t *
180 process_new(const char *command)
181 {
183 
184  process_t *process;
185  process = tor_malloc_zero(sizeof(process_t));
186 
187  /* Set our command. */
188  process->command = tor_strdup(command);
189 
190  /* By default we are not running. */
192 
193  /* Prepare process environment. */
194  process->arguments = smartlist_new();
195  process->environment = smartlist_new();
196 
197  /* Prepare the buffers. */
198  process->stdout_buffer = buf_new();
199  process->stderr_buffer = buf_new();
200  process->stdin_buffer = buf_new();
201 
202 #ifndef _WIN32
203  /* Prepare our Unix process handle. */
204  process->unix_process = process_unix_new();
205 #else
206  /* Prepare our Win32 process handle. */
207  process->win32_process = process_win32_new();
208 #endif /* !defined(_WIN32) */
209 
210  smartlist_add(processes, process);
211 
212  return process;
213 }
214 
215 /** Deallocate the given process in <b>process</b>. */
216 void
218 {
219  if (! process)
220  return;
221 
222  /* Cleanup parameters. */
223  tor_free(process->command);
224 
225  /* Cleanup arguments and environment. */
226  SMARTLIST_FOREACH(process->arguments, char *, x, tor_free(x));
227  smartlist_free(process->arguments);
228 
229  SMARTLIST_FOREACH(process->environment, char *, x, tor_free(x));
230  smartlist_free(process->environment);
231 
232  /* Cleanup the buffers. */
233  buf_free(process->stdout_buffer);
234  buf_free(process->stderr_buffer);
235  buf_free(process->stdin_buffer);
236 
237 #ifndef _WIN32
238  /* Cleanup our Unix process handle. */
239  process_unix_free(process->unix_process);
240 #else
241  /* Cleanup our Win32 process handle. */
242  process_win32_free(process->win32_process);
243 #endif /* !defined(_WIN32) */
244 
245  smartlist_remove(processes, process);
246 
247  tor_free(process);
248 }
249 
250 /** Execute the given process. This function executes the given process as a
251  * subprocess of Tor. Returns <b>PROCESS_STATUS_RUNNING</b> upon success. */
254 {
255  tor_assert(process);
256 
257  if (BUG(may_spawn_background_process == 0))
258  return PROCESS_STATUS_ERROR;
259 
261 
262  log_info(LD_PROCESS, "Starting new process: %s", process->command);
263 
264 #ifndef _WIN32
265  status = process_unix_exec(process);
266 #else
267  status = process_win32_exec(process);
268 #endif
269 
270  /* Update our state. */
271  process_set_status(process, status);
272 
273  if (status != PROCESS_STATUS_RUNNING) {
274  log_warn(LD_PROCESS, "Failed to start process: %s",
275  process_get_command(process));
276  }
277 
278  return status;
279 }
280 
281 /** Terminate the given process. Returns true on success,
282  * otherwise false. */
283 bool
285 {
286  tor_assert(process);
287 
288  /* Terminating a non-running process isn't going to work. */
290  return false;
291 
292  log_debug(LD_PROCESS, "Terminating process");
293 
294 #ifndef _WIN32
295  return process_unix_terminate(process);
296 #else
297  return process_win32_terminate(process);
298 #endif
299 }
300 
301 /** Returns the unique process identifier for the given <b>process</b>. */
302 process_pid_t
304 {
305  tor_assert(process);
306 
307 #ifndef _WIN32
308  return process_unix_get_pid(process);
309 #else
310  return process_win32_get_pid(process);
311 #endif
312 }
313 
314 /** Set the callback function for output from the child process's standard out
315  * handle. This function sets the callback function which is called every time
316  * the child process have written output to its standard out file handle.
317  *
318  * Use <b>process_set_protocol(process, PROCESS_PROTOCOL_LINE)</b> if you want
319  * the callback to only contain complete "\n" or "\r\n" terminated lines. */
320 void
322  process_read_callback_t callback)
323 {
324  tor_assert(process);
325  process->stdout_read_callback = callback;
326 }
327 
328 /** Set the callback function for output from the child process's standard
329  * error handle. This function sets the callback function which is called
330  * every time the child process have written output to its standard error file
331  * handle.
332  *
333  * Use <b>process_set_protocol(process, PROCESS_PROTOCOL_LINE)</b> if you want
334  * the callback to only contain complete "\n" or "\r\n" terminated lines. */
335 void
337  process_read_callback_t callback)
338 {
339  tor_assert(process);
340  process->stderr_read_callback = callback;
341 }
342 
343 /** Set the callback function for process exit notification. The
344  * <b>callback</b> function will be called every time your child process have
345  * terminated. */
346 void
348  process_exit_callback_t callback)
349 {
350  tor_assert(process);
351  process->exit_callback = callback;
352 }
353 
354 /** Get the current command of the given process. */
355 const char *
357 {
358  tor_assert(process);
359  return process->command;
360 }
361 
362 void
363 process_set_protocol(process_t *process, process_protocol_t protocol)
364 {
365  tor_assert(process);
366  process->protocol = protocol;
367 }
368 
369 /** Get the currently used protocol of the given process. */
372 {
373  tor_assert(process);
374  return process->protocol;
375 }
376 
377 /** Set opaque pointer to data. This function allows you to store a pointer to
378  * your own data in the given process. Use <b>process_get_data()</b> in the
379  * various callback functions to retrieve the data again.
380  *
381  * Note that the given process does NOT take ownership of the data and you are
382  * responsible for freeing up any resources allocated by the given data.
383  * */
384 void
385 process_set_data(process_t *process, void *data)
386 {
387  tor_assert(process);
388  process->data = data;
389 }
390 
391 /** Get the opaque pointer to callback data from the given process. This
392  * function allows you get the data you stored with <b>process_set_data()</b>
393  * in the different callback functions. */
394 void *
396 {
397  tor_assert(process);
398  return process->data;
399 }
400 
401 /** Set the status of a given process. */
402 void
404 {
405  tor_assert(process);
406  process->status = status;
407 }
408 
409 /** Get the status of the given process. */
412 {
413  tor_assert(process);
414  return process->status;
415 }
416 
417 /** Append an argument to the list of arguments in the given process. */
418 void
419 process_append_argument(process_t *process, const char *argument)
420 {
421  tor_assert(process);
422  tor_assert(argument);
423 
424  smartlist_add(process->arguments, tor_strdup(argument));
425 }
426 
427 /** Returns a list of arguments (excluding the command itself) from the
428  * given process. */
429 const smartlist_t *
431 {
432  tor_assert(process);
433  return process->arguments;
434 }
435 
436 /** Returns a newly allocated Unix style argument vector. Use <b>tor_free()</b>
437  * to deallocate it after use. */
438 char **
440 {
441  tor_assert(process);
442 
443  /** Generate a Unix style process argument vector from our process's
444  * arguments smartlist_t. */
445  char **argv = NULL;
446 
447  char *filename = process->command;
448  const smartlist_t *arguments = process->arguments;
449  const size_t size = smartlist_len(arguments);
450 
451  /* Make space for the process filename as argv[0] and a trailing NULL. */
452  argv = tor_malloc_zero(sizeof(char *) * (size + 2));
453 
454  /* Set our filename as first argument. */
455  argv[0] = filename;
456 
457  /* Put in the rest of the values from arguments. */
458  SMARTLIST_FOREACH_BEGIN(arguments, char *, arg_val) {
459  tor_assert(arg_val != NULL);
460 
461  argv[arg_val_sl_idx + 1] = arg_val;
462  } SMARTLIST_FOREACH_END(arg_val);
463 
464  return argv;
465 }
466 
467 /** This function clears the internal environment and copies over every string
468  * from <b>env</b> as the new environment. */
469 void
471 {
472  tor_assert(process);
473  tor_assert(env);
474 
475  /* Cleanup old environment. */
476  SMARTLIST_FOREACH(process->environment, char *, x, tor_free(x));
477  smartlist_free(process->environment);
478  process->environment = smartlist_new();
479 
480  SMARTLIST_FOREACH(env, char *, x,
481  smartlist_add(process->environment, tor_strdup(x)));
482 }
483 
484 /** Set the given <b>key</b>/<b>value</b> pair as environment variable in the
485  * given process. */
486 void
488  const char *key,
489  const char *value)
490 {
491  tor_assert(process);
492  tor_assert(key);
493  tor_assert(value);
494 
495  smartlist_add_asprintf(process->environment, "%s=%s", key, value);
496 }
497 
498 /** Returns a newly allocated <b>process_environment_t</b> containing the
499  * environment variables for the given process. */
502 {
503  tor_assert(process);
504  return process_environment_make(process->environment);
505 }
506 
507 #ifndef _WIN32
508 /** Get the internal handle for the Unix backend. */
511 {
512  tor_assert(process);
513  tor_assert(process->unix_process);
514  return process->unix_process;
515 }
516 #else /* defined(_WIN32) */
517 /** Get the internal handle for Windows backend. */
518 process_win32_t *
519 process_get_win32_process(const process_t *process)
520 {
521  tor_assert(process);
522  tor_assert(process->win32_process);
523  return process->win32_process;
524 }
525 #endif /* !defined(_WIN32) */
526 
527 /** Write <b>size</b> bytes of <b>data</b> to the given process's standard
528  * input. */
529 void
531  const uint8_t *data, size_t size)
532 {
533  tor_assert(process);
534  tor_assert(data);
535 
536  buf_add(process->stdin_buffer, (char *)data, size);
537  process_write_stdin(process, process->stdin_buffer);
538 }
539 
540 /** As tor_vsnprintf(), but write the data to the given process's standard
541  * input. */
542 void
544  const char *format, va_list args)
545 {
546  tor_assert(process);
547  tor_assert(format);
548 
549  int size;
550  char *data;
551 
552  size = tor_vasprintf(&data, format, args);
553  tor_assert(data != NULL);
554  process_write(process, (uint8_t *)data, size);
555  tor_free(data);
556 }
557 
558 /** As tor_snprintf(), but write the data to the given process's standard
559  * input. */
560 void
562  const char *format, ...)
563 {
564  tor_assert(process);
565  tor_assert(format);
566 
567  va_list ap;
568  va_start(ap, format);
569  process_vprintf(process, format, ap);
570  va_end(ap);
571 }
572 
573 /** This function is called by the Process backend when a given process have
574  * data that is ready to be read from the child process's standard output
575  * handle. */
576 void
578 {
579  tor_assert(process);
580 
581  int ret;
582  ret = process_read_stdout(process, process->stdout_buffer);
583 
584  if (ret > 0)
585  process_read_data(process,
586  process->stdout_buffer,
587  process->stdout_read_callback);
588 }
589 
590 /** This function is called by the Process backend when a given process have
591  * data that is ready to be read from the child process's standard error
592  * handle. */
593 void
595 {
596  tor_assert(process);
597 
598  int ret;
599  ret = process_read_stderr(process, process->stderr_buffer);
600 
601  if (ret > 0)
602  process_read_data(process,
603  process->stderr_buffer,
604  process->stderr_read_callback);
605 }
606 
607 /** This function is called by the Process backend when a given process is
608  * allowed to begin writing data to the standard input of the child process. */
609 void
611 {
612  tor_assert(process);
613 
614  process_write_stdin(process, process->stdin_buffer);
615 }
616 
617 /** This function is called by the Process backend when a given process have
618  * terminated. The exit status code is passed in <b>exit_code</b>. We mark the
619  * process as no longer running and calls the <b>exit_callback</b> with
620  * information about the process termination. The given <b>process</b> is
621  * free'd iff the exit_callback returns true. */
622 void
623 process_notify_event_exit(process_t *process, process_exit_code_t exit_code)
624 {
625  tor_assert(process);
626 
627  log_debug(LD_PROCESS,
628  "Process terminated with exit code: %"PRIu64, exit_code);
629 
630  /* Update our state. */
632  process->exit_code = exit_code;
633 
634  /* Call our exit callback, if it exists. */
635  bool free_process_handle = false;
636 
637  /* The exit callback will tell us if we should process_free() our handle. */
638  if (process->exit_callback)
639  free_process_handle = process->exit_callback(process, exit_code);
640 
641  if (free_process_handle)
642  process_free(process);
643 }
644 
645 /** This function is called whenever the Process backend have notified us that
646  * there is data to be read from its standard out handle. Returns the number of
647  * bytes that have been put into the given buffer. */
648 MOCK_IMPL(STATIC int, process_read_stdout, (process_t *process, buf_t *buffer))
649 {
650  tor_assert(process);
651  tor_assert(buffer);
652 
653 #ifndef _WIN32
654  return process_unix_read_stdout(process, buffer);
655 #else
656  return process_win32_read_stdout(process, buffer);
657 #endif
658 }
659 
660 /** This function is called whenever the Process backend have notified us that
661  * there is data to be read from its standard error handle. Returns the number
662  * of bytes that have been put into the given buffer. */
663 MOCK_IMPL(STATIC int, process_read_stderr, (process_t *process, buf_t *buffer))
664 {
665  tor_assert(process);
666  tor_assert(buffer);
667 
668 #ifndef _WIN32
669  return process_unix_read_stderr(process, buffer);
670 #else
671  return process_win32_read_stderr(process, buffer);
672 #endif
673 }
674 
675 /** This function calls the backend function for the given process whenever
676  * there is data to be written to the backends' file handles. */
678  (process_t *process, buf_t *buffer))
679 {
680  tor_assert(process);
681  tor_assert(buffer);
682 
683 #ifndef _WIN32
684  process_unix_write(process, buffer);
685 #else
686  process_win32_write(process, buffer);
687 #endif
688 }
689 
690 /** This function calls the protocol handlers based on the value of
691  * <b>process_get_protocol(process)</b>. Currently we call
692  * <b>process_read_buffer()</b> for <b>PROCESS_PROTOCOL_RAW</b> and
693  * <b>process_read_lines()</b> for <b>PROCESS_PROTOCOL_LINE</b>. */
694 STATIC void
696  buf_t *buffer,
697  process_read_callback_t callback)
698 {
699  tor_assert(process);
700  tor_assert(buffer);
701 
702  switch (process_get_protocol(process)) {
704  process_read_buffer(process, buffer, callback);
705  break;
707  process_read_lines(process, buffer, callback);
708  break;
709  default:
710  /* LCOV_EXCL_START */
711  tor_assert_unreached();
712  return;
713  /* LCOV_EXCL_STOP */
714  }
715 }
716 
717 /** This function takes the content of the given <b>buffer</b> and passes it to
718  * the given <b>callback</b> function, but ensures that an additional zero byte
719  * is added to the end of the data such that the given callback implementation
720  * can threat the content as a ASCIIZ string. */
721 STATIC void
723  buf_t *buffer,
724  process_read_callback_t callback)
725 {
726  tor_assert(process);
727  tor_assert(buffer);
728 
729  const size_t size = buf_datalen(buffer);
730 
731  /* We allocate an extra byte for the zero byte in the end. */
732  char *data = tor_malloc_zero(size + 1);
733 
734  buf_get_bytes(buffer, data, size);
735  log_debug(LD_PROCESS, "Read data from process");
736 
737  if (callback)
738  callback(process, data, size);
739 
740  tor_free(data);
741 }
742 
743 /** This function tries to extract complete lines from the given <b>buffer</b>
744  * and calls the given <b>callback</b> function whenever it has a complete
745  * line. Before calling <b>callback</b> we remove the trailing "\n" or "\r\n"
746  * from the line. If we are unable to extract a complete line we leave the data
747  * in the buffer for next call. */
748 STATIC void
750  buf_t *buffer,
751  process_read_callback_t callback)
752 {
753  tor_assert(process);
754  tor_assert(buffer);
755 
756  const size_t size = buf_datalen(buffer) + 1;
757  size_t line_size = 0;
758  char *data = tor_malloc_zero(size);
759  int ret;
760 
761  while (true) {
762  line_size = size;
763  ret = buf_get_line(buffer, data, &line_size);
764 
765  /* A complete line should always be smaller than the size of our
766  * buffer. */
767  tor_assert(ret != -1);
768 
769  /* Remove \n from the end of the line. */
770  if (line_size >= 1 && data[line_size - 1] == '\n') {
771  data[line_size - 1] = '\0';
772  --line_size;
773  }
774 
775  /* Remove \r from the end of the line. */
776  if (line_size >= 1 && data[line_size - 1] == '\r') {
777  data[line_size - 1] = '\0';
778  --line_size;
779  }
780 
781  if (ret == 1) {
782  log_debug(LD_PROCESS, "Read line from process: \"%s\"", data);
783 
784  if (callback)
785  callback(process, data, line_size);
786 
787  /* We have read a whole line, let's see if there is more lines to read.
788  * */
789  continue;
790  }
791 
792  /* No complete line for us to read. We are done for now. */
793  tor_assert_nonfatal(ret == 0);
794  break;
795  }
796 
797  tor_free(data);
798 }
int buf_add(buf_t *buf, const char *string, size_t string_len)
Definition: buffers.c:527
buf_t * buf_new(void)
Definition: buffers.c:365
size_t buf_datalen(const buf_t *buf)
Definition: buffers.c:394
int buf_get_line(buf_t *buf, char *data_out, size_t *data_len)
Definition: buffers.c:874
int buf_get_bytes(buf_t *buf, char *string, size_t string_len)
Definition: buffers.c:637
Header file for buffers.c.
Header file for buffers_net.c.
tor_cmdline_mode_t command
Definition: config.c:2440
process_environment_t * process_environment_make(struct smartlist_t *env_vars)
Definition: env.c:101
Header for env.c.
Headers for log.c.
#define LD_PROCESS
Definition: log.h:115
#define tor_free(p)
Definition: malloc.h:52
int tor_vasprintf(char **strp, const char *fmt, va_list args)
Definition: printf.c:96
void process_set_stderr_read_callback(process_t *process, process_read_callback_t callback)
Definition: process.c:336
void process_notify_event_stdout(process_t *process)
Definition: process.c:577
void process_set_data(process_t *process, void *data)
Definition: process.c:385
void process_write(process_t *process, const uint8_t *data, size_t size)
Definition: process.c:530
STATIC void process_read_data(process_t *process, buf_t *buffer, process_read_callback_t callback)
Definition: process.c:695
static smartlist_t * processes
Definition: process.c:27
void process_notify_event_exit(process_t *process, process_exit_code_t exit_code)
Definition: process.c:623
const smartlist_t * process_get_all_processes(void)
Definition: process.c:166
void process_notify_event_stderr(process_t *process)
Definition: process.c:594
void process_free_(process_t *process)
Definition: process.c:217
void process_set_status(process_t *process, process_status_t status)
Definition: process.c:403
const char * process_status_to_string(process_status_t status)
Definition: process.c:92
void process_set_environment(process_t *process, const char *key, const char *value)
Definition: process.c:487
void process_append_argument(process_t *process, const char *argument)
Definition: process.c:419
STATIC void process_write_stdin(process_t *process, buf_t *buffer)
Definition: process.c:678
void process_set_exit_callback(process_t *process, process_exit_callback_t callback)
Definition: process.c:347
void * process_get_data(const process_t *process)
Definition: process.c:395
const char * process_get_command(const process_t *process)
Definition: process.c:356
process_t * process_new(const char *command)
Definition: process.c:180
process_environment_t * process_get_environment(const process_t *process)
Definition: process.c:501
void process_vprintf(process_t *process, const char *format, va_list args)
Definition: process.c:543
STATIC void process_read_lines(process_t *process, buf_t *buffer, process_read_callback_t callback)
Definition: process.c:749
const smartlist_t * process_get_arguments(const process_t *process)
Definition: process.c:430
void process_free_all(void)
Definition: process.c:153
void process_init(void)
Definition: process.c:141
process_protocol_t process_get_protocol(const process_t *process)
Definition: process.c:371
STATIC void process_read_buffer(process_t *process, buf_t *buffer, process_read_callback_t callback)
Definition: process.c:722
static int may_spawn_background_process
Definition: process.c:33
void tor_disable_spawning_background_processes(void)
Definition: process.c:132
void process_reset_environment(process_t *process, const smartlist_t *env)
Definition: process.c:470
const char * process_protocol_to_string(process_protocol_t protocol)
Definition: process.c:112
process_status_t process_get_status(const process_t *process)
Definition: process.c:411
void process_set_stdout_read_callback(process_t *process, process_read_callback_t callback)
Definition: process.c:321
STATIC int process_read_stdout(process_t *process, buf_t *buffer)
Definition: process.c:648
process_unix_t * process_get_unix_process(const process_t *process)
Definition: process.c:510
char ** process_get_argv(const process_t *process)
Definition: process.c:439
bool process_terminate(process_t *process)
Definition: process.c:284
void process_notify_event_stdin(process_t *process)
Definition: process.c:610
void process_printf(process_t *process, const char *format,...)
Definition: process.c:561
process_status_t process_exec(process_t *process)
Definition: process.c:253
process_pid_t process_get_pid(process_t *process)
Definition: process.c:303
STATIC int process_read_stderr(process_t *process, buf_t *buffer)
Definition: process.c:663
Header for process.c.
process_protocol_t
Definition: process.h:39
@ PROCESS_PROTOCOL_LINE
Definition: process.h:42
@ PROCESS_PROTOCOL_RAW
Definition: process.h:45
process_status_t
Definition: process.h:26
@ PROCESS_STATUS_NOT_RUNNING
Definition: process.h:28
@ PROCESS_STATUS_RUNNING
Definition: process.h:31
@ PROCESS_STATUS_ERROR
Definition: process.h:34
int process_unix_write(process_t *process, buf_t *buffer)
Definition: process_unix.c:391
bool process_unix_terminate(process_t *process)
Definition: process_unix.c:348
int process_unix_read_stderr(process_t *process, buf_t *buffer)
Definition: process_unix.c:442
process_pid_t process_unix_get_pid(process_t *process)
Definition: process_unix.c:380
int process_unix_read_stdout(process_t *process, buf_t *buffer)
Definition: process_unix.c:427
process_unix_t * process_unix_new(void)
Definition: process_unix.c:90
process_status_t process_unix_exec(process_t *process)
Definition: process_unix.c:131
Header for process_unix.c.
Header for process_win32.c.
void smartlist_add_asprintf(struct smartlist_t *sl, const char *pattern,...)
Definition: smartlist.c:36
Header for smartlist.c.
smartlist_t * smartlist_new(void)
void smartlist_add(smartlist_t *sl, void *element)
void smartlist_remove(smartlist_t *sl, const void *element)
#define SMARTLIST_FOREACH_BEGIN(sl, type, var)
#define SMARTLIST_FOREACH(sl, type, var, cmd)
process_exit_callback_t exit_callback
Definition: process.c:50
process_status_t status
Definition: process.c:38
buf_t * stdin_buffer
Definition: process.c:75
process_read_callback_t stdout_read_callback
Definition: process.c:44
void * data
Definition: process.c:78
smartlist_t * arguments
Definition: process.c:63
process_exit_code_t exit_code
Definition: process.c:53
process_unix_t * unix_process
Definition: process.c:82
buf_t * stderr_buffer
Definition: process.c:72
smartlist_t * environment
Definition: process.c:66
char * command
Definition: process.c:56
process_protocol_t protocol
Definition: process.c:41
buf_t * stdout_buffer
Definition: process.c:69
process_read_callback_t stderr_read_callback
Definition: process.c:47
#define STATIC
Definition: testsupport.h:32
#define MOCK_IMPL(rv, funcname, arglist)
Definition: testsupport.h:133
Macros to manage assertions, fatal and non-fatal.
#define tor_assert(expr)
Definition: util_bug.h:102