20
There are two ways to detect when the command exits:
22
1. Add a callback to signal_exited.
24
2. Manually poll stopped_cleanup_needed() (from the same thread).
26
In both cases, stopped_cleanup() must be called afterwards
27
(from the main thread).
33
// inheriting from sigc::trackable automatically disconnects this class's
34
// slots upon destruction.
20
/// There are two ways to detect when the command exits:
21
/// 1. Add a callback to signal_exited.
22
/// 2. Manually poll stopped_cleanup_needed() (from the same thread).
23
/// In both cases, stopped_cleanup() must be called afterwards
24
/// (from the main thread).
35
25
class Cmdex : public hz::ErrorHolder<hz::SyncPolicyNone> {
39
using hz::ErrorHolder<hz::SyncPolicyNone>::ptr_error_list_t; // auto-deleting container
40
using hz::ErrorHolder<hz::SyncPolicyNone>::error_list_t;
28
using hz::ErrorHolder<hz::SyncPolicyNone>::ptr_error_list_t; ///< Auto-deleting pointer container
29
using hz::ErrorHolder<hz::SyncPolicyNone>::error_list_t; ///< Error list type
31
/// A function that translates the exit error code into a readable string
42
32
typedef std::string (*exit_status_translator_func_t)(int, void*);
34
/// A function that is called whenever a process exits.
43
35
typedef void (*exited_callback_func_t)(void*);
47
// exit_status_translator_func_t translator_func,
48
exited_callback_func_t exited_cb = NULL, void* exited_cb_data = NULL
50
: running_(false), kill_signal_sent_(0), child_watch_handler_called_(false),
51
pid_(0), waitpid_status_(0),
52
timer_(g_timer_new()),
53
event_source_id_term(0), event_source_id_kill(0),
54
fd_stdout_(0), fd_stderr_(0), channel_stdout_(0), channel_stderr_(0),
55
channel_stdout_buffer_size_(100 * 1024), channel_stderr_buffer_size_(10 * 1024), // 100K and 10K
56
event_source_id_stdout_(0), event_source_id_stderr_(0),
57
translator_func_(0), translator_func_data_(0),
58
exited_callback_(exited_cb), exited_callback_data_(exited_cb_data)
39
Cmdex(exited_callback_func_t exited_cb = NULL, void* exited_cb_data = NULL)
40
: running_(false), kill_signal_sent_(0), child_watch_handler_called_(false),
41
pid_(0), waitpid_status_(0),
42
timer_(g_timer_new()),
43
event_source_id_term(0), event_source_id_kill(0),
44
fd_stdout_(0), fd_stderr_(0), channel_stdout_(0), channel_stderr_(0),
45
channel_stdout_buffer_size_(100 * 1024), channel_stderr_buffer_size_(10 * 1024), // 100K and 10K
46
event_source_id_stdout_(0), event_source_id_stderr_(0),
47
translator_func_(0), translator_func_data_(0),
48
exited_callback_(exited_cb), exited_callback_data_(exited_cb_data)
63
// Please don't destroy this object unless the child has exited. It will leak stuff
64
// and possibly crash, etc... .
53
/// Destructor. Don't destroy this object unless the child has exited. It will leak stuff
54
/// and possibly crash, etc... .
67
57
// This will help if object is destroyed after the command has exited, but before
78
// Call before execute.
79
// Note: The command and the arguments _must_ be shell-escaped.
80
// Use g_shell_quote() or Glib::shell_quote(). Note that each argument
81
// must be escaped separately.
68
/// Set the command to execute. Call before execute().
69
/// Note: The command and the arguments _must_ be shell-escaped.
70
/// Use g_shell_quote() or Glib::shell_quote(). Note that each argument
71
/// must be escaped separately.
82
72
void set_command(const std::string& command_exec, const std::string& command_args)
84
74
command_exec_ = command_exec;
89
// launch the command.
79
/// Launch the command.
93
// send SIGTERM(15) (terminate).
94
// use after execute(). using it after the command has exited has no effect.
83
/// Send SIGTERM(15) (terminate) to the child process.
84
/// Use only after execute(). Using it after the command has exited has no effect.
95
85
bool try_stop(hz::signal_t sig = hz::SIGNAL_SIGTERM);
98
// Send SIGKILL(9) (kill). This signal cannot be overridden in child process.
99
// use after execute(). using it after the command has exited has no effect.
102
return try_stop(hz::SIGNAL_SIGKILL);
106
// set a timeout (since call to this function) to terminate, kill or both (use 0 to ignore the parameter).
107
// the timeouts will be unset automatically when the command exits.
108
// This has an effect only if the command is running (after execute()).
88
/// Send SIGKILL(9) (kill) to the child process. Same as
89
/// try_stop(hz::SIGNAL_SIGKILL).
90
/// Note that SIGKILL cannot be overridden in child process.
94
/// Set a timeout (since call to this function) to terminate the child process,
95
/// kill it or both (use 0 to ignore the parameter).
96
/// The timeouts will be unset automatically when the command exits.
97
/// This has an effect only if the command is running (after execute()).
109
98
void set_stop_timeouts(int term_timeout_msec = 0, int kill_timeout_msec = 0);
111
// Unset timeouts. This will stop the timeout counters.
112
// This has an effect only if the command is running (after execute()).
100
/// Unset the terminate / kill timeouts. This will stop the timeout counters.
101
/// This has an effect only if the command is running (after execute()).
113
102
void unset_stop_timeouts();
116
// If stopped_cleanup_needed() returned true, call this. The command
117
// should be exited by this time. Must be called before the next execute().
105
/// If stopped_cleanup_needed() returned true, call this. The command
106
/// should be exited by this time. Must be called before the next execute().
118
107
void stopped_cleanup();
121
// Returns true if command has stopped.
122
// Call repeatedly in a waiting function, after execute(). When returns true, call stopped_cleanup().
110
/// Returns true if command has stopped.
111
/// Call repeatedly in a waiting function, after execute().
112
/// When it returns true, call stopped_cleanup().
123
113
bool stopped_cleanup_needed()
125
115
return (child_watch_handler_called_);
129
// The process is running. Note that if this returns false, it doesn't mean that
130
// the io channels have been closed or that the data may be read safely. Poll
131
// stopped_cleanup_needed() instead.
119
/// Check if the process is running. Note that if this returns false, it doesn't mean that
120
/// the io channels have been closed or that the data may be read safely. Poll
121
/// stopped_cleanup_needed() instead.
132
122
bool is_running() const
139
// Call this before execution. There is a race-like condition - when the command
140
// outputs something, the io channel reads it from fd to its buffer and the event
141
// source callback is called. If the command dies, the io channel callback reads
142
// the remaining data to the channel buffer.
143
// Since the event source callbacks (which read from the buffer and empty it)
144
// happen rather sporadically (from the glib loop), the buffer may not get read and
145
// emptied at all (before the command exits). This is why it's necessary to have
146
// a buffer size which potentially can hold _all_ the command output.
147
// A way to fight this is to increase event source priority (which may not help).
148
// Another way is to delay the command exit so that the event source callback
149
// catches on and reads the buffer.
151
// Use 0 to ignore the parameter. Call before execute().
129
/// Call this before execution. There is a race-like condition - when the command
130
/// outputs something, the io channel reads it from fd to its buffer and the event
131
/// source callback is called. If the command dies, the io channel callback reads
132
/// the remaining data to the channel buffer.
133
/// Since the event source callbacks (which read from the buffer and empty it)
134
/// happen rather sporadically (from the glib loop), the buffer may not get read and
135
/// emptied at all (before the command exits). This is why it's necessary to have
136
/// a buffer size which potentially can hold _all_ the command output.
137
/// A way to fight this is to increase event source priority (which may not help).
138
/// Another way is to delay the command exit so that the event source callback
139
/// catches on and reads the buffer.
140
// Use 0 to ignore the parameter. Call this before execute().
152
141
void set_buffer_sizes(int stdout_buffer_size = 0, int stderr_buffer_size = 0)
154
143
if (stdout_buffer_size)
162
// If stdout_make_str_as_available_ is false, call this after stopped_cleanup(),
163
// before next execute(). If it's true, you may call this before the command has
164
// stopped, but it will decrease performance significantly.
151
/// If stdout_make_str_as_available_ is false, call this after stopped_cleanup(),
152
/// before next execute(). If it's true, you may call this before the command has
153
/// stopped, but it will decrease performance significantly.
165
154
std::string get_stdout_str(bool clear_existing = false)
167
156
// debug_out_dump("app", str_stdout_);
259
253
// default command and its args. std::strings, not ustrings.
260
std::string command_exec_; // binary name. NOT affected by cleanup().
261
std::string command_args_; // args that always go with binary. NOT affected by cleanup().
264
bool running_; // child process is running now. NOT affected by cleanup().
265
int kill_signal_sent_; // command has been sent this signal to terminate
266
bool child_watch_handler_called_; // true after child_watch_handler callback, before stopped_cleanup().
268
GPid pid_; // int in Unix, pointer in win32
269
int waitpid_status_; // after the command is stopped, before cleanup, this will be available.
272
GTimer* timer_; // keep track of elapsed time since command execution. not used by this class, but may be handy.
274
int event_source_id_term;
275
int event_source_id_kill;
281
GIOChannel* channel_stdout_;
282
GIOChannel* channel_stderr_;
284
int channel_stdout_buffer_size_; // NOT affected by cleanup().
285
int channel_stderr_buffer_size_; // NOT affected by cleanup().
287
int event_source_id_stdout_;
288
int event_source_id_stderr_;
290
std::string str_stdout_; // NOT affected by cleanup().
291
std::string str_stderr_; // NOT affected by cleanup().
254
std::string command_exec_; /// Binary name to execute. NOT affected by cleanup_members().
255
std::string command_args_; /// Arguments that always go with the binary. NOT affected by cleanup_members().
258
bool running_; ///< If true, the child process is running now. NOT affected by cleanup_members().
259
int kill_signal_sent_; ///< If non-zero, the process has been sent this signal to terminate
260
bool child_watch_handler_called_; ///< true after child_watch_handler callback, before stopped_cleanup().
262
GPid pid_; ///< Process ID. int in Unix, pointer in win32
263
int waitpid_status_; ///< After the command is stopped, before cleanup, this will be available (waitpid() status).
266
GTimer* timer_; ///< Keeps track of elapsed time since command execution. Value is not used by this class, but may be handy.
268
int event_source_id_term; ///< Timeout event source ID for SIGTERM.
269
int event_source_id_kill; ///< Timeout event source ID for SIGKILL.
272
int fd_stdout_; ///< stdout file descriptor
273
int fd_stderr_; ///< stderr file descriptor
275
GIOChannel* channel_stdout_; ///< stdout channel
276
GIOChannel* channel_stderr_; ///< stderr channel
278
int channel_stdout_buffer_size_; ///< stdout channel buffer size. NOT affected by cleanup_members().
279
int channel_stderr_buffer_size_; ///< stderr channel buffer size. NOT affected by cleanup_members().
281
int event_source_id_stdout_; ///< IO watcher event source ID for stdout
282
int event_source_id_stderr_; ///< IO watcher event source ID for stderr
284
std::string str_stdout_; ///< stdout data read during execution. NOT affected by cleanup_members().
285
std::string str_stderr_; ///< stderr data read during execution. NOT affected by cleanup_members().
296
290
// convert command exit status to message string
297
exit_status_translator_func_t translator_func_; // NOT affected by cleanup().
298
void* translator_func_data_;
291
exit_status_translator_func_t translator_func_; ///< Exit status translator function. NOT affected by cleanup_members().
292
void* translator_func_data_; ///< Data to supply to the exit status translator function.
300
294
// "command exited" signal callback.
301
exited_callback_func_t exited_callback_; // NOT affected by cleanup().
302
void* exited_callback_data_;
295
exited_callback_func_t exited_callback_; ///< Exit notifier function. NOT affected by cleanup_members().
296
void* exited_callback_data_; ///< Data to supply to the exit notifier function.