~arosales/test/oprofile

« back to all changes in this revision

Viewing changes to libutil++/child_reader.h

  • Committer: Antonio Rosales
  • Date: 2013-03-28 08:40:26 UTC
  • Revision ID: antonio.rosales@canonical.com-20130328084026-gpqns1mkqd7cnr05
Move files up one directory.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 */
 
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