Line data Source code
1 : // Snap Websites Server -- advanced handling of Unix processes
2 : // Copyright (c) 2013-2019 Made to Order Software Corp. All Rights Reserved
3 : //
4 : // https://snapwebsites.org/
5 : // contact@m2osw.com
6 : //
7 : // This program is free software; you can redistribute it and/or modify
8 : // it under the terms of the GNU General Public License as published by
9 : // the Free Software Foundation; either version 2 of the License, or
10 : // (at your option) any later version.
11 : //
12 : // This program is distributed in the hope that it will be useful,
13 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : // GNU General Public License for more details.
16 : //
17 : // You should have received a copy of the GNU General Public License
18 : // along with this program; if not, write to the Free Software
19 : // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 : #pragma once
21 :
22 : // ourselves
23 : //
24 : #include "snapwebsites/snap_thread.h"
25 : #include "snapwebsites/snap_string_list.h"
26 :
27 : // Qt lib
28 : //
29 : #include <QVector>
30 :
31 : // C++ lib
32 : //
33 : #include <map>
34 : #include <memory>
35 :
36 :
37 : // forward declarations to avoid including the readproc.h file in the header
38 : //#include <proc/readproc.h>
39 : extern "C" typedef struct proc_t proc_t;
40 : extern "C" typedef struct PROCTAB PROCTAB;
41 :
42 : namespace snap
43 : {
44 :
45 0 : class snap_process_exception : public snap_exception
46 : {
47 : public:
48 0 : explicit snap_process_exception(const char * whatmsg) : snap_exception("snap_process", whatmsg) {}
49 : explicit snap_process_exception(const std::string & whatmsg) : snap_exception("snap_process", whatmsg) {}
50 0 : explicit snap_process_exception(const QString & whatmsg) : snap_exception("snap_process", whatmsg) {}
51 : };
52 :
53 0 : class snap_process_exception_invalid_mode_error : public snap_process_exception
54 : {
55 : public:
56 0 : explicit snap_process_exception_invalid_mode_error(const char * whatmsg) : snap_process_exception(whatmsg) {}
57 : explicit snap_process_exception_invalid_mode_error(const std::string & whatmsg) : snap_process_exception(whatmsg) {}
58 : explicit snap_process_exception_invalid_mode_error(const QString & whatmsg) : snap_process_exception(whatmsg) {}
59 : };
60 :
61 0 : class snap_process_exception_already_initialized : public snap_process_exception
62 : {
63 : public:
64 0 : explicit snap_process_exception_already_initialized(const char * whatmsg) : snap_process_exception(whatmsg) {}
65 : explicit snap_process_exception_already_initialized(const std::string & whatmsg) : snap_process_exception(whatmsg) {}
66 : explicit snap_process_exception_already_initialized(const QString & whatmsg) : snap_process_exception(whatmsg) {}
67 : };
68 :
69 0 : class snap_process_exception_unknown_flag : public snap_process_exception
70 : {
71 : public:
72 0 : explicit snap_process_exception_unknown_flag(const char * whatmsg) : snap_process_exception(whatmsg) {}
73 : explicit snap_process_exception_unknown_flag(const std::string & whatmsg) : snap_process_exception(whatmsg) {}
74 : explicit snap_process_exception_unknown_flag(const QString & whatmsg) : snap_process_exception(whatmsg) {}
75 : };
76 :
77 0 : class snap_process_exception_openproc : public snap_process_exception
78 : {
79 : public:
80 0 : explicit snap_process_exception_openproc(const char * whatmsg) : snap_process_exception(whatmsg) {}
81 : explicit snap_process_exception_openproc(const std::string & whatmsg) : snap_process_exception(whatmsg) {}
82 : explicit snap_process_exception_openproc(const QString & whatmsg) : snap_process_exception(whatmsg) {}
83 : };
84 :
85 0 : class snap_process_exception_data_not_available : public snap_process_exception
86 : {
87 : public:
88 0 : explicit snap_process_exception_data_not_available(const char * whatmsg) : snap_process_exception(whatmsg) {}
89 : explicit snap_process_exception_data_not_available(const std::string & whatmsg) : snap_process_exception(whatmsg) {}
90 0 : explicit snap_process_exception_data_not_available(const QString & whatmsg) : snap_process_exception(whatmsg) {}
91 : };
92 :
93 0 : class snap_process_exception_initialization_failed : public snap_process_exception
94 : {
95 : public:
96 0 : explicit snap_process_exception_initialization_failed(const char * whatmsg) : snap_process_exception(whatmsg) {}
97 : explicit snap_process_exception_initialization_failed(const std::string & whatmsg) : snap_process_exception(whatmsg) {}
98 : explicit snap_process_exception_initialization_failed(const QString & whatmsg) : snap_process_exception(whatmsg) {}
99 : };
100 :
101 :
102 :
103 :
104 0 : class process
105 : {
106 : public:
107 : typedef std::map<std::string, std::string> environment_map_t;
108 :
109 : enum class mode_t
110 : {
111 : PROCESS_MODE_COMMAND,
112 : PROCESS_MODE_INPUT,
113 : PROCESS_MODE_OUTPUT,
114 : PROCESS_MODE_INOUT,
115 : PROCESS_MODE_INOUT_INTERACTIVE,
116 : PROCESS_MODE_INOUTERR
117 : };
118 :
119 : class process_output_callback
120 : {
121 : public:
122 : virtual ~process_output_callback() {}
123 :
124 : virtual bool output_available(process * p, QByteArray const & output) = 0;
125 : virtual bool error_available(process * p, QByteArray const & error);
126 : };
127 :
128 : process(QString const & name);
129 :
130 : QString const & get_name() const;
131 :
132 : // setup the process
133 : //
134 : void set_mode(mode_t mode);
135 : void set_forced_environment(bool forced = true);
136 :
137 : void set_command(QString const & name);
138 : void set_command(std::string const & name);
139 : void set_command(char const * name);
140 : void add_argument(QString const & arg);
141 : void add_argument(std::string const & arg);
142 : void add_argument(char const * arg);
143 : void add_environ(QString const & name, QString const & value);
144 :
145 : int run();
146 :
147 : // what is sent to the command stdin
148 : //
149 : void set_input(QString const & input);
150 : void set_input(QByteArray const & input);
151 :
152 : // what is received from the command stdout
153 : //
154 : QString get_output(bool reset = false);
155 : QByteArray get_binary_output(bool reset = false);
156 : void set_output_callback(process_output_callback * callback);
157 :
158 : // what is received from the command stderr
159 : //
160 : QString get_error(bool reset = false);
161 : QByteArray get_binary_error(bool reset = false);
162 :
163 : static void set_process_name(QString const & name);
164 : static void set_process_name(std::string const & name);
165 : static void set_process_name(char const * name);
166 : static pid_t get_pid_max();
167 :
168 : private:
169 : // prevent copies
170 : process(process const & rhs) = delete;
171 : process & operator = (process const & rhs) = delete;
172 :
173 : QString const f_name = QString();
174 : mode_t f_mode = mode_t::PROCESS_MODE_COMMAND;
175 : QString f_command = QString();
176 : snap_string_list f_arguments = snap_string_list();
177 : environment_map_t f_environment = environment_map_t();
178 : QByteArray f_input = QByteArray();
179 : QByteArray f_output = QByteArray();
180 : QByteArray f_error = QByteArray();
181 : bool f_forced_environment = false;
182 : process_output_callback * f_output_callback = nullptr;
183 : snap_thread::snap_mutex f_mutex = snap_thread::snap_mutex();
184 : };
185 :
186 :
187 : class process_list
188 : {
189 : public:
190 : typedef int flags_t;
191 :
192 : enum class field_t
193 : {
194 : // current status
195 : MEMORY,
196 : STATUS,
197 : STATISTICS,
198 :
199 : // info on startup
200 : COMMAND_LINE,
201 : ENVIRON,
202 :
203 : // user/group info
204 : USER_NAME,
205 : GROUP_NAME,
206 : CGROUP,
207 : SUPPLEMENTARY_GROUP,
208 :
209 : // other
210 : OOM,
211 : WAIT_CHANNEL,
212 : NAMESPACE
213 : };
214 :
215 0 : class proc_info
216 : {
217 : public:
218 : typedef std::shared_ptr<proc_info> pointer_t;
219 :
220 : pid_t get_pid() const;
221 : pid_t get_ppid() const;
222 : void get_page_faults(unsigned long & major, unsigned long & minor) const;
223 : unsigned get_pcpu() const;
224 : char get_status() const;
225 : void get_times(unsigned long long & utime, unsigned long long & stime, unsigned long long & cutime, unsigned long long & cstime) const;
226 : long get_priority() const;
227 : long get_nice() const;
228 : long get_total_size() const;
229 : long get_resident_size() const;
230 : std::string get_process_name() const;
231 : std::string get_process_basename() const;
232 : int get_args_size() const;
233 : std::string get_arg(int index) const;
234 : int get_tty() const;
235 :
236 : private:
237 : friend class process_list;
238 :
239 : proc_info(std::shared_ptr<proc_t> p, flags_t flags);
240 : proc_info(proc_info const &) = delete;
241 : proc_info& operator = (proc_info const &) = delete;
242 :
243 : std::shared_ptr<proc_t> f_proc = std::shared_ptr<proc_t>();
244 : flags_t f_flags = 0;
245 : mutable int32_t f_count = -1;
246 : };
247 :
248 : bool get_field(field_t fld) const;
249 : void set_field(field_t fld);
250 : void clear_field(field_t fld);
251 :
252 : void rewind();
253 : proc_info::pointer_t next();
254 :
255 : private:
256 : int field_to_flag(field_t fld) const;
257 :
258 : std::shared_ptr<PROCTAB> f_proctab = std::shared_ptr<PROCTAB>();
259 : flags_t f_flags = 0;
260 : };
261 :
262 :
263 : } // namespace snap
264 : // vim: ts=4 sw=4 et
|