xref: /aosp_15_r20/external/vboot_reference/host/lib/include/subprocess.h (revision 8617a60d3594060b7ecbd21bc622a7c14f3cf2bc)
1*8617a60dSAndroid Build Coastguard Worker /* Copyright 2019 The ChromiumOS Authors
2*8617a60dSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
3*8617a60dSAndroid Build Coastguard Worker  * found in the LICENSE file.
4*8617a60dSAndroid Build Coastguard Worker  *
5*8617a60dSAndroid Build Coastguard Worker  * Library for creating subprocesses in a high level manner.
6*8617a60dSAndroid Build Coastguard Worker  */
7*8617a60dSAndroid Build Coastguard Worker 
8*8617a60dSAndroid Build Coastguard Worker #ifndef VBOOT_REFERENCE_SUBPROCESS_H_
9*8617a60dSAndroid Build Coastguard Worker #define VBOOT_REFERENCE_SUBPROCESS_H_
10*8617a60dSAndroid Build Coastguard Worker 
11*8617a60dSAndroid Build Coastguard Worker #include <stdio.h>
12*8617a60dSAndroid Build Coastguard Worker #include <stdlib.h>
13*8617a60dSAndroid Build Coastguard Worker 
14*8617a60dSAndroid Build Coastguard Worker /**
15*8617a60dSAndroid Build Coastguard Worker  * subprocess_target is the "mini language" of the subprocess
16*8617a60dSAndroid Build Coastguard Worker  * library. It describes where to read or write data from the process.
17*8617a60dSAndroid Build Coastguard Worker  *
18*8617a60dSAndroid Build Coastguard Worker  * There are currently five target of targets:
19*8617a60dSAndroid Build Coastguard Worker  *
20*8617a60dSAndroid Build Coastguard Worker  * - TARGET_NULL: /dev/null, no need to describe any other fields.
21*8617a60dSAndroid Build Coastguard Worker  *
22*8617a60dSAndroid Build Coastguard Worker  * - TARGET_FD: file descriptor, put the fd in the fd field.
23*8617a60dSAndroid Build Coastguard Worker  *
24*8617a60dSAndroid Build Coastguard Worker  * - TARGET_FILE: FILE *, put the FILE pointer in the file field.
25*8617a60dSAndroid Build Coastguard Worker  *
26*8617a60dSAndroid Build Coastguard Worker  * - TARGET_BUFFER: read to, or write from, a buffer. Fields:
27*8617a60dSAndroid Build Coastguard Worker  *   - buffer->buf: the buffer
28*8617a60dSAndroid Build Coastguard Worker  *   - buffer->size: the size of that buffer
29*8617a60dSAndroid Build Coastguard Worker  *   - buffer->bytes_consumed: do not fill out this field.
30*8617a60dSAndroid Build Coastguard Worker  *     subprocess_run will set it to the number of bytes read from the
31*8617a60dSAndroid Build Coastguard Worker  *     process (if writing to a buffer). Goes unused when reading from
32*8617a60dSAndroid Build Coastguard Worker  *     a buffer.
33*8617a60dSAndroid Build Coastguard Worker  *
34*8617a60dSAndroid Build Coastguard Worker  * - TARGET_BUFFER_NULL_TERMINATED: when reading from a buffer, don't
35*8617a60dSAndroid Build Coastguard Worker  *   fill out the size field and subprocess_run will strlen for you.
36*8617a60dSAndroid Build Coastguard Worker  *   When writing to a buffer, subprocess_run will reserve one byte of
37*8617a60dSAndroid Build Coastguard Worker  *   the size for a null terminator and guarantee that the output is
38*8617a60dSAndroid Build Coastguard Worker  *   always NULL terminated.
39*8617a60dSAndroid Build Coastguard Worker  *
40*8617a60dSAndroid Build Coastguard Worker  * - TARGET_CALLBACK: when the target is provided as an input to a
41*8617a60dSAndroid Build Coastguard Worker  *   process, the callback will be called occasionally to provide
42*8617a60dSAndroid Build Coastguard Worker  *   input to the process. The callback should fill buf with up to
43*8617a60dSAndroid Build Coastguard Worker  *   buf_sz bytes of data, and return the number of bytes
44*8617a60dSAndroid Build Coastguard Worker  *   written, or negative values on error. When the target is provided
45*8617a60dSAndroid Build Coastguard Worker  *   as an output to a process, the callback will be called
46*8617a60dSAndroid Build Coastguard Worker  *   occasionally with buf_sz bytes of data from the output put into
47*8617a60dSAndroid Build Coastguard Worker  *   buf. In this case, the return value from the callback is
48*8617a60dSAndroid Build Coastguard Worker  *   ignored except for errors. The data field is for application use
49*8617a60dSAndroid Build Coastguard Worker  *   and will always be passed to the data parameter of the callback
50*8617a60dSAndroid Build Coastguard Worker  *   function.
51*8617a60dSAndroid Build Coastguard Worker  */
52*8617a60dSAndroid Build Coastguard Worker struct subprocess_target {
53*8617a60dSAndroid Build Coastguard Worker 	enum {
54*8617a60dSAndroid Build Coastguard Worker 		TARGET_NULL,
55*8617a60dSAndroid Build Coastguard Worker 		TARGET_FD,
56*8617a60dSAndroid Build Coastguard Worker 		TARGET_FILE,
57*8617a60dSAndroid Build Coastguard Worker 		TARGET_BUFFER,
58*8617a60dSAndroid Build Coastguard Worker 		TARGET_BUFFER_NULL_TERMINATED,
59*8617a60dSAndroid Build Coastguard Worker 		TARGET_CALLBACK,
60*8617a60dSAndroid Build Coastguard Worker 	} type;
61*8617a60dSAndroid Build Coastguard Worker 	union {
62*8617a60dSAndroid Build Coastguard Worker 		int fd;
63*8617a60dSAndroid Build Coastguard Worker 		FILE *file;
64*8617a60dSAndroid Build Coastguard Worker 		struct {
65*8617a60dSAndroid Build Coastguard Worker 			char *buf;
66*8617a60dSAndroid Build Coastguard Worker 			size_t size;
67*8617a60dSAndroid Build Coastguard Worker 
68*8617a60dSAndroid Build Coastguard Worker 			/*
69*8617a60dSAndroid Build Coastguard Worker 			 * This variable is the output of the number of bytes
70*8617a60dSAndroid Build Coastguard Worker 			 * read or written. It should be read by the caller, not
71*8617a60dSAndroid Build Coastguard Worker 			 * set.
72*8617a60dSAndroid Build Coastguard Worker 			 */
73*8617a60dSAndroid Build Coastguard Worker 			size_t bytes_consumed;
74*8617a60dSAndroid Build Coastguard Worker 		} buffer;
75*8617a60dSAndroid Build Coastguard Worker 		struct {
76*8617a60dSAndroid Build Coastguard Worker 			ssize_t (*cb)(char *buf, size_t buf_sz, void *data);
77*8617a60dSAndroid Build Coastguard Worker 			void *data;
78*8617a60dSAndroid Build Coastguard Worker 		} callback;
79*8617a60dSAndroid Build Coastguard Worker 	};
80*8617a60dSAndroid Build Coastguard Worker 	struct {
81*8617a60dSAndroid Build Coastguard Worker 		int pipefd[2];
82*8617a60dSAndroid Build Coastguard Worker 	} priv;
83*8617a60dSAndroid Build Coastguard Worker };
84*8617a60dSAndroid Build Coastguard Worker 
85*8617a60dSAndroid Build Coastguard Worker /**
86*8617a60dSAndroid Build Coastguard Worker  * A convenience subprocess target which uses TARGET_NULL.
87*8617a60dSAndroid Build Coastguard Worker  */
88*8617a60dSAndroid Build Coastguard Worker extern struct subprocess_target subprocess_null;
89*8617a60dSAndroid Build Coastguard Worker 
90*8617a60dSAndroid Build Coastguard Worker /**
91*8617a60dSAndroid Build Coastguard Worker  * A convenience subprocess target which uses TARGET_FD to STDIN_FILENO.
92*8617a60dSAndroid Build Coastguard Worker  */
93*8617a60dSAndroid Build Coastguard Worker extern struct subprocess_target subprocess_stdin;
94*8617a60dSAndroid Build Coastguard Worker 
95*8617a60dSAndroid Build Coastguard Worker /**
96*8617a60dSAndroid Build Coastguard Worker  * A convenience subprocess target which uses TARGET_FD to STDOUT_FILENO.
97*8617a60dSAndroid Build Coastguard Worker  */
98*8617a60dSAndroid Build Coastguard Worker extern struct subprocess_target subprocess_stdout;
99*8617a60dSAndroid Build Coastguard Worker 
100*8617a60dSAndroid Build Coastguard Worker /**
101*8617a60dSAndroid Build Coastguard Worker  * A convenience subprocess target which uses TARGET_FD to STDERR_FILENO.
102*8617a60dSAndroid Build Coastguard Worker  */
103*8617a60dSAndroid Build Coastguard Worker extern struct subprocess_target subprocess_stderr;
104*8617a60dSAndroid Build Coastguard Worker 
105*8617a60dSAndroid Build Coastguard Worker /**
106*8617a60dSAndroid Build Coastguard Worker  * Call a process and run until completion.
107*8617a60dSAndroid Build Coastguard Worker  *
108*8617a60dSAndroid Build Coastguard Worker  * @param argv          A NULL-terminated list of arguments describing
109*8617a60dSAndroid Build Coastguard Worker  *                      the program to run.
110*8617a60dSAndroid Build Coastguard Worker  * @param input         The subprocess_target connected to stdin.
111*8617a60dSAndroid Build Coastguard Worker  * @param output        The subprocess_target connected to stdout.
112*8617a60dSAndroid Build Coastguard Worker  * @param error         The subprocess_target connected to stderr.
113*8617a60dSAndroid Build Coastguard Worker  *
114*8617a60dSAndroid Build Coastguard Worker  * If either input, output, or error are set to NULL, they will be
115*8617a60dSAndroid Build Coastguard Worker  * &subprocess_stdin, &subprocess_stdout, or &subprocess_stderr
116*8617a60dSAndroid Build Coastguard Worker  * respectively.
117*8617a60dSAndroid Build Coastguard Worker  *
118*8617a60dSAndroid Build Coastguard Worker  * @return The exit status on success, or negative values on error.
119*8617a60dSAndroid Build Coastguard Worker  */
120*8617a60dSAndroid Build Coastguard Worker int subprocess_run(const char *const argv[],
121*8617a60dSAndroid Build Coastguard Worker 		   struct subprocess_target *input,
122*8617a60dSAndroid Build Coastguard Worker 		   struct subprocess_target *output,
123*8617a60dSAndroid Build Coastguard Worker 		   struct subprocess_target *error);
124*8617a60dSAndroid Build Coastguard Worker 
125*8617a60dSAndroid Build Coastguard Worker #endif  /* VBOOT_REFERENCE_SUBPROCESS_H_ */
126