summaryrefslogtreecommitdiff
path: root/host/lib/include/subprocess.h
blob: cddcf05c74bbeabb0e027a84e68ddd0010bdcba7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/* Copyright 2019 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

/* Library for creating subprocesses in a high level manner. */

#ifndef VBOOT_REFERENCE_SUBPROCESS_H_
#define VBOOT_REFERENCE_SUBPROCESS_H_

#include <stdio.h>
#include <stdlib.h>

/**
 * subprocess_target is the "mini language" of the subprocess
 * library. It describes where to read or write data from the process.
 *
 * There are currently five target of targets:
 *
 * - TARGET_NULL: /dev/null, no need to describe any other fields.
 *
 * - TARGET_FD: file descriptor, put the fd in the fd field.
 *
 * - TARGET_FILE: FILE *, put the FILE pointer in the file field.
 *
 * - TARGET_BUFFER: read to, or write from, a buffer. Fields:
 *   - buffer->buf: the buffer
 *   - buffer->size: the size of that buffer
 *   - buffer->bytes_consumed: do not fill out this field.
 *     subprocess_run will set it to the number of bytes read from the
 *     process (if writing to a buffer). Goes unused when reading from
 *     a buffer.
 *
 * - TARGET_BUFFER_NULL_TERMINATED: when reading from a buffer, don't
 *   fill out the size field and subprocess_run will strlen for you.
 *   When writing to a buffer, subprocess_run will reserve one byte of
 *   the size for a null terminator and guarantee that the output is
 *   always NULL terminated.
 */
struct subprocess_target {
	enum {
		TARGET_NULL,
		TARGET_FD,
		TARGET_FILE,
		TARGET_BUFFER,
		TARGET_BUFFER_NULL_TERMINATED,
	} type;
	union {
		int fd;
		FILE *file;
		struct {
			char *buf;
			size_t size;

			/* This variable is used internally by "run" and
			 * shouldn't be operated on by the caller.
			 */
			int _pipefd[2];

			/* This variable is the output of the number of bytes
			 * read or written. It should be read by the caller, not
			 * set.
			 */
			size_t bytes_consumed;
		} buffer;
	};
};

/**
 * A convenience subprocess target which uses TARGET_NULL.
 */
struct subprocess_target subprocess_null;

/**
 * A convenience subprocess target which uses TARGET_FD to
 * STDIN_FILENO.
 */
struct subprocess_target subprocess_stdin;

/**
 * A convenience subprocess target which uses TARGET_FD to
 * STDOUT_FILENO.
 */
struct subprocess_target subprocess_stdout;

/**
 * A convenience subprocess target which uses TARGET_FD to
 * STDERR_FILENO.
 */
struct subprocess_target subprocess_stderr;

/**
 * Call a process described by argv and run until completion. Provide
 * input from the subprocess target input, output to the subprocess
 * target output, and error to the subprocess target error.
 *
 * If either input, output, or error are set to NULL, the will be
 * &subprocess_stdin, &subprocess_stdout, or &subprocess_stderr
 * respectively.
 *
 * Returns the exit status on success, or negative values on error.
 */
int subprocess_run(const char *const argv[],
		   struct subprocess_target *input,
		   struct subprocess_target *output,
		   struct subprocess_target *error);

#endif  /* VBOOT_REFERENCE_SUBPROCESS_H_ */