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