! * Option to specify the error channel for the child * process. It can be: * 1. An already open file descriptor. * 2. A file name. * 3. IOTYPE. Usually a PIPE or STDOUT * */
| 975 | * |
| 976 | */ |
| 977 | struct error |
| 978 | { |
| 979 | explicit error(int fd): wr_ch_(fd) {} |
| 980 | |
| 981 | explicit error(FILE* fp):error(subprocess_fileno(fp)) { assert(fp); } |
| 982 | |
| 983 | explicit error(const char* filename) { |
| 984 | int fd = subprocess_open(filename, O_APPEND | O_CREAT | O_RDWR, 0640); |
| 985 | if (fd == -1) throw OSError("File not found: ", errno); |
| 986 | wr_ch_ = fd; |
| 987 | } |
| 988 | explicit error(IOTYPE typ) { |
| 989 | assert ((typ == PIPE || typ == STDOUT) && "STDERR not allowed"); |
| 990 | if (typ == PIPE) { |
| 991 | #ifndef __USING_WINDOWS__ |
| 992 | std::tie(rd_ch_, wr_ch_) = util::pipe_cloexec(); |
| 993 | #endif |
| 994 | } else { |
| 995 | // Need to defer it till we have checked all arguments |
| 996 | deferred_ = true; |
| 997 | } |
| 998 | } |
| 999 | |
| 1000 | bool deferred_ = false; |
| 1001 | int rd_ch_ = -1; |
| 1002 | int wr_ch_ = -1; |
| 1003 | }; |
| 1004 | |
| 1005 | // Impoverished, meager, needy, truly needy |
| 1006 | // version of type erasure to store function pointers |