Line data Source code
1 : // Copyright (c) 2013-2021 Made to Order Software Corp. All Rights Reserved
2 : //
3 : // https://snapwebsites.org/project/eventdispatcher
4 : // contact@m2osw.com
5 : //
6 : // This program is free software; you can redistribute it and/or modify
7 : // it under the terms of the GNU General Public License as published by
8 : // the Free Software Foundation; either version 2 of the License, or
9 : // (at your option) any later version.
10 : //
11 : // This program is distributed in the hope that it will be useful,
12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : // GNU General Public License for more details.
15 : //
16 : // You should have received a copy of the GNU General Public License along
17 : // with this program; if not, write to the Free Software Foundation, Inc.,
18 : // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 : #pragma once
20 :
21 : // eventdispatcher lib
22 : //
23 : #include <eventdispatcher/communicator.h>
24 : #include <eventdispatcher/pipe_connection.h>
25 : #include <eventdispatcher/signal_child.h>
26 :
27 :
28 : // snapdev lib
29 : //
30 : #include <snapdev/glob_to_list.h>
31 :
32 :
33 : // C++ lib
34 : //
35 : #include <list>
36 : #include <map>
37 : #include <memory>
38 :
39 :
40 :
41 : namespace cppprocess
42 : {
43 :
44 :
45 :
46 : typedef std::vector<std::uint8_t> buffer_t;
47 :
48 :
49 :
50 8 : class process
51 : {
52 : public:
53 : typedef std::shared_ptr<process> pointer_t;
54 : typedef std::list<pointer_t> list_t;
55 : typedef std::map<std::string, std::string> environment_map_t;
56 : typedef std::list<std::string> string_list_t;
57 : typedef snap::glob_to_list<string_list_t> argument_list_t;
58 : typedef std::function<void(ed::child_status status)>
59 : process_done_t;
60 : typedef std::function<void(std::string const & capture)>
61 : capture_done_t;
62 :
63 : process(std::string const & name);
64 : process(process const & rhs) = delete;
65 : process & operator = (process const & rhs) = delete;
66 :
67 : std::string const & get_name() const;
68 :
69 : // setup the process
70 : //
71 : void set_forced_environment(bool forced = true);
72 : bool get_forced_environment() const;
73 :
74 : void set_command(std::string const & name);
75 : std::string const & get_command() const;
76 : bool add_argument(std::string const & arg, bool expand = false);
77 : argument_list_t & get_arguments();
78 : argument_list_t const & get_arguments() const;
79 : void add_environ(std::string const & name, std::string const & value);
80 : environment_map_t const & get_environ() const;
81 :
82 : // what is sent to the command stdin
83 : //
84 : void set_input_filename(std::string const & filename);
85 : std::string const & get_input_filename() const;
86 : void add_input(std::string const & input);
87 : void add_input(buffer_t const & input);
88 : std::string get_input(bool reset = false) const;
89 : buffer_t get_binary_input(bool reset = false) const;
90 : void set_input_pipe(ed::pipe_connection::pointer_t pipe);
91 : ed::pipe_connection::pointer_t get_input_pipe() const;
92 :
93 : // what is received from the command stdout
94 : //
95 : void set_output_filename(std::string const & filename);
96 : std::string const & get_output_filename() const;
97 : void set_capture_output(bool capture = true);
98 : bool get_capture_output() const;
99 : void set_output_capture_done(capture_done_t callback);
100 : std::string get_output(bool reset = false) const;
101 : std::string get_trimmed_output(bool inside = false, bool reset = false) const;
102 : buffer_t get_binary_output(bool reset = false) const;
103 : void set_output_pipe(ed::pipe_connection::pointer_t pipe);
104 : ed::pipe_connection::pointer_t get_output_pipe() const;
105 : void add_next_process(pointer_t next);
106 : void clear_next_process();
107 : list_t get_next_processes() const;
108 :
109 : // what is received from the command stderr
110 : //
111 : void set_error_filename(std::string const & filename);
112 : std::string const & get_error_filename() const;
113 : void set_capture_error(bool capture = true);
114 : bool get_capture_error() const;
115 : void set_error_capture_done(capture_done_t callback);
116 : std::string get_error(bool reset = false) const;
117 : buffer_t get_binary_error(bool reset = false) const;
118 : void set_error_pipe(ed::pipe_connection::pointer_t pipe);
119 : ed::pipe_connection::pointer_t get_error_pipe() const;
120 :
121 : // start/stop the process(es)
122 : //
123 : int start();
124 : int wait();
125 : int kill(int sig);
126 : void set_process_done(process_done_t callback);
127 :
128 : // these are internal functions called by an internal pipe
129 : // once the capture is over
130 : //
131 : void input_pipe_done();
132 : void output_pipe_done(ed::pipe_connection * p);
133 :
134 : private:
135 : int start_process(
136 : ed::pipe_connection::pointer_t output_fifo
137 : , int output_index
138 : , ed::pipe_connection::pointer_t input_fifo);
139 : void child_done(ed::child_status status);
140 : void execute_command(
141 : ed::pipe_connection::pointer_t output_fifo
142 : , int output_index
143 : , ed::pipe_connection::pointer_t input_fifo);
144 : void prepare_input(ed::pipe_connection::pointer_t output_fifo);
145 : void prepare_output();
146 : void prepare_error();
147 :
148 : ed::communicator::pointer_t f_communicator = ed::communicator::pointer_t();
149 : std::string const f_name = std::string();
150 : std::string f_command = std::string();
151 : argument_list_t f_arguments = argument_list_t();
152 : environment_map_t f_environment = environment_map_t();
153 : process_done_t f_process_done = process_done_t();
154 : bool f_forced_environment = false;
155 : bool f_running = false;
156 : bool f_capture_output = false;
157 : bool f_capture_error = false;
158 : buffer_t f_input = buffer_t();
159 : buffer_t f_output = buffer_t();
160 : buffer_t f_error = buffer_t();
161 : std::string f_input_filename = std::string();
162 : snap::raii_fd_t f_input_file = snap::raii_fd_t();
163 : ed::pipe_connection::pointer_t f_input_pipe = ed::pipe_connection::pointer_t();
164 : ed::pipe_connection::pointer_t f_internal_input_pipe = ed::pipe_connection::pointer_t();
165 : int f_prepared_input = -1;
166 : std::string f_output_filename = std::string();
167 : snap::raii_fd_t f_output_file = snap::raii_fd_t();
168 : ed::pipe_connection::pointer_t f_output_pipe = ed::pipe_connection::pointer_t();
169 : ed::pipe_connection::pointer_t f_intermediate_output_pipe = ed::pipe_connection::pointer_t();
170 : std::vector<int> f_prepared_output = {};
171 : capture_done_t f_output_done_callback = capture_done_t();
172 : std::string f_error_filename = std::string();
173 : snap::raii_fd_t f_error_file = snap::raii_fd_t();
174 : ed::pipe_connection::pointer_t f_error_pipe = ed::pipe_connection::pointer_t();
175 : ed::pipe_connection::pointer_t f_internal_error_pipe = ed::pipe_connection::pointer_t();
176 : int f_prepared_error = -1;
177 : capture_done_t f_error_done_callback = capture_done_t();
178 : list_t f_next = list_t();
179 : pid_t f_child = -1;
180 : int f_exit_code = -1;
181 : };
182 :
183 :
184 :
185 : } // namespace cppprocess
186 : // vim: ts=4 sw=4 et
|