Tor 0.4.9.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. */
36struct 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. */
70
71 /** Buffer to store data from stderr when it is read. */
73
74 /** Buffer to store data to stdin before it is written. */
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. */
91const 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. */
111const 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 **/
131void
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. */
140void
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. */
152void
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. */
165const 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 * */
179process_t *
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>. */
216void
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))
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. */
283bool
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>. */
302process_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. */
320void
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. */
335void
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. */
346void
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. */
355const char *
357{
358 tor_assert(process);
359 return process->command;
360}
361
362void
363process_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 * */
384void
385process_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. */
394void *
396{
397 tor_assert(process);
398 return process->data;
399}
400
401/** Set the status of a given process. */
402void
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. */
418void
419process_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. */
429const 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. */
438char **
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. */
469void
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. */
486void
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. */
518process_win32_t *
519process_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. */
529void
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. */
542void
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. */
560void
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. */
576void
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. */
593void
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. */
609void
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. */
622void
623process_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. */
648MOCK_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. */
663MOCK_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>. */
694STATIC 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. */
721STATIC 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. */
748STATIC 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}
buf_t * buf_new(void)
Definition: buffers.c:365
int buf_add(buf_t *buf, const char *string, size_t string_len)
Definition: buffers.c:527
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:2468
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:56
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 char * process_protocol_to_string(process_protocol_t protocol)
Definition: process.c:112
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 smartlist_t * process_get_arguments(const process_t *process)
Definition: process.c:430
void process_set_environment(process_t *process, const char *key, const char *value)
Definition: process.c:487
const smartlist_t * process_get_all_processes(void)
Definition: process.c:166
const char * process_status_to_string(process_status_t status)
Definition: process.c:92
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
const char * process_get_command(const process_t *process)
Definition: process.c:356
void * process_get_data(const process_t *process)
Definition: process.c:395
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
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
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_environment_t * process_get_environment(const process_t *process)
Definition: process.c:501
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_t * process_new(const char *command)
Definition: process.c:180
process_pid_t process_get_pid(process_t *process)
Definition: process.c:303
char ** process_get_argv(const process_t *process)
Definition: process.c:439
STATIC int process_read_stderr(process_t *process, buf_t *buffer)
Definition: process.c:663
process_unix_t * process_get_unix_process(const process_t *process)
Definition: process.c:510
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_status_t process_unix_exec(process_t *process)
Definition: process_unix.c:131
process_unix_t * process_unix_new(void)
Definition: process_unix.c:90
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:103