1 /** 2 * @file child_reader.h 3 * Facility for reading from child processes 4 * 5 * @remark Copyright 2002 OProfile authors 6 * @remark Read the file COPYING 7 * 8 * @author Philippe Elie 9 * @author John Levon 10 */ 11 12 #ifndef CHILD_READER_H 13 #define CHILD_READER_H 14 15 #include <sys/types.h> 16 17 #include <vector> 18 #include <string> 19 20 /** 21 * a class to read stdout / stderr from a child process. 22 * 23 * two interfaces are provided. read line by line: getline() or read all data 24 * in one : get_data(). In all case get_data() must be called once to flush the 25 * stderr child output 26 */ 27 /* 28 * FIXME: code review is needed: 29 * - check the getline()/get_data()/block_read() interface. 30 * the expected behavior is: 31 * caller can call getline until nothing is available from the stdout of the 32 * child. in this case child stderr is acumulated in buf2 and can be read 33 * through get_data(). get_data() is blocking until the child close stderr / 34 * stdout (even if the child die by a signal ?). The following corner case must 35 * work but I'm unsure if the code reflect this behavior: the last line of the 36 * child stdout have not necessarilly a LF terminator. the child can output any 37 * size of data in stderr. 38 */ 39 class child_reader { 40 public: 41 /** fork a process. use error() to get error code. Do not try to 42 * use other public member interface if error() return non-zero */ 43 child_reader(std::string const & cmd, 44 std::vector<std::string> const & args); 45 46 /** wait for the termination of the child process if this have not 47 * already occur. In this case return code of the child process is not 48 * available. */ 49 ~child_reader(); 50 51 /** fill result from on line of stdout of the child process. 52 * must be used as: 53 * child_reader reader(...); 54 * while (reader.getline(line)) .... */ 55 bool getline(std::string & result); 56 57 /** fill out / err with the stdout / stderr of the child process. 58 * You can call this after calling one or more time getline(...). This 59 * call is blocking until the child die and so on all subsequent 60 * call will fail */ 61 bool get_data(std::ostream & out, std::ostream & err); 62 63 /** rather to rely on dtor to wait for the termination of the child you 64 * can use terminate_process() to get the return code of the child 65 * process */ 66 int terminate_process(); 67 68 /** return the status of the first error encoutered 69 * != 0 : something feel wrong, use error_str() to get an error 70 * message */ error()71 int error() const { return first_error; } 72 73 /** 74 * return an error message if appropriate, if the process has 75 * been successfully exec'ed and is not terminate the error message 76 * is always empty. Error message is also empty if the child process 77 * terminate successfully. Else three type of error message exist: 78 * - "unable to fork" followed by sterror(errno) 79 * - "process_name return xxx" xxx is return code 80 * - "process_name terminated by signal xxx" xxx is signal number 81 */ 82 std::string error_str() const; 83 84 private: 85 // ctor helper: create the child process. 86 void exec_command(std::string const & cmd, 87 std::vector<std::string> const & args); 88 // return false when eof condition is reached on fd1. fd2 can have 89 // already input in the pipe buffer or in buf2. 90 bool block_read(); 91 92 int fd1; 93 int fd2; 94 ssize_t pos1; 95 ssize_t end1; 96 ssize_t pos2; 97 ssize_t end2; 98 pid_t pid; 99 int first_error; 100 // child stderr is handled especially, we need to retain data even 101 // if caller read only stdout of the child. 102 char * buf2; 103 ssize_t sz_buf2; 104 char * buf1; 105 std::string process_name; 106 bool is_terminated; 107 bool terminate_on_exception; 108 bool forked; 109 }; 110 111 #endif // CHILD_READER_H 112