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