8 #ifdef HAVE_SYS_TYPES_H
11 #ifdef HAVE_SYS_WAIT_H
20 #ifdef HAVE_SYS_SELECT_H
21 #include <sys/select.h>
68 throw(
ERROR(0,
"Tried to write to a read-only pipe"));
76 throw(
ERROR(errno,
"Could not catch SIGPIPIE signal"));
78 throw(
ERROR(errno,
"Could not create pipe for in"));
80 throw(
ERROR(errno,
"Could not create pipe for out"));
82 throw(
ERROR(errno,
"Could not create pipe for err"));
84 throw(
ERROR(errno,
"Could not fork"));
143 if (
m_fd1[0] != STDIN_FILENO) {
144 if (dup2(
m_fd1[0], STDIN_FILENO) != STDIN_FILENO) {
146 std::cerr << e << std::endl;
151 if (
m_fd2[1] != STDOUT_FILENO) {
152 if (dup2(
m_fd2[1], STDOUT_FILENO) != STDOUT_FILENO) {
154 std::cerr << e << std::endl;
159 if (
m_fd3[1] != STDERR_FILENO) {
160 if (dup2(
m_fd3[1], STDERR_FILENO) != STDERR_FILENO) {
162 std::cerr << e << std::endl;
178 kill(
m_pid, signal_no);
225 if (pid > 0)
return(
false);
226 if ((pid < 0) && (errno == ECHILD))
return(
false);
236 if (pid > 0)
return(
true);
237 if ((pid < 0) && (errno == ECHILD))
return(
true);
362 struct timeval timeout = { 0, 0 };
367 select(fd+1, 0, &wset, 0, &timeout);
368 if (FD_ISSET(fd, &wset)) {
377 struct timeval timeout = { 0, 0 };
382 select(fd+1, &rset, 0, 0, &timeout);
383 if (FD_ISSET(fd, &rset)) {
407 execl(
"/bin/sh",
"sh",
"-c", command.c_str(), (
char *)0);
412 void execute::exec(
const std::string binary,
const std::vector<std::string> argv)
436 bin = (
char *)binary.c_str();
437 base = bin+strlen(bin);
438 while ((base > bin) && (*base !=
'/')) {
444 size = (argv.size() + 2) *
sizeof(
char *);
445 args = (
char **)malloc(size);
446 memset((
void *)args, 0, size);
451 for (c = 0; c < argv.size(); c++) {
452 args[c+1] = (
char *)argv[c].c_str();
544 n = read(
in_fd(), buf, len);
561 n = write(
in_fd(), buf, len);
578 n = read(
out_fd(), buf, len);
595 n = write(
out_fd(), buf, len);
612 n = read(
err_fd(), buf, len);
629 n = write(
err_fd(), buf, len);
643 out <<
"execute::is_child() = " <<
is_child() << std::endl;
644 out <<
"execute::is_parent() = " <<
is_parent() << std::endl;
645 out <<
"execute::my_pid() = " <<
my_pid() << std::endl;
646 out <<
"execute::child_running() = " <<
child_running() << std::endl;
647 out <<
"execute::child_exited() = " <<
child_exited() << std::endl;
652 out <<
"execute::child_signaled() = " <<
child_signaled() << std::endl;
653 out <<
"execute::child_exit_code() = " <<
child_exit_code() << std::endl;
654 out <<
"execute::child_signal_no() = " <<
child_signal_no() << std::endl;
655 out <<
"execute::in_fd() = " <<
in_fd() << std::endl;
656 out <<
"execute::out_fd() = " <<
out_fd() << std::endl;
657 out <<
"execute::err_fd() = " <<
err_fd() << std::endl;
658 out <<
"execute::in_ready() = " <<
in_ready() << std::endl;
659 out <<
"execute::out_ready() = " <<
out_ready() << std::endl;
660 out <<
"execute::err_ready() = " <<
err_ready() << std::endl;
const pid_t pid(void)
Return the PID of this process.
void reroute_stdio(void)
Called by the child to reroute the child's stdin, stdout, and stderr to the parent.
int child_signal_no(void)
If the child was signaled, return the signal number.
pid_t child_pid(void)
Returns the child's PID.
bool err_eof(void)
Check for err EOF.
bool out_eof(void)
Check for output EOF.
void fork(void)
Fork a child process.
std::ostream & operator<<(std::ostream &out, execute &exe)
Convenience function to call execute::print()
void kill_child(void)
Send a KILL signal to the child.
static void _signal_handler(int signo)
Generic signal handler.
int err_read(char *buf, const int len)
Allow parent to read from err_fd()
void exit(int code=0)
Called by the child to exit with a particular code.
void signal_child(int signal_no)
Send a signal to the child.
bool err_ready(void)
Check I/O for output.
bool out_ready(void)
Check I/O for output.
bool child_started(void) const
Returns true if the child has been started.
int in_write(const char *buf, const int len)
Allow parent to write output to in_fd()
int out_fd(void)
Return a file descriptor for I/O between parent a child.
void hup_child(void)
Send a HUP signal to the child.
bool child_running(void)
Returns true if the child is running.
void clear(void)
Reset the execute class to default values, kill the child processif one is running.
bool child_exited_success(void)
Returns true if the child returned exit code 0 and no caught signals.
void exec(const std::string command)
Execute a command, rerouting stdin, stdout, and stderr to parent.
int err_write(const char *buf, const int len)
Allow child to write to err_fd()
int out_read(char *buf, const int len)
Allow parent to read out_fd()
bool child_signaled(void)
Returns true if the child was signaled.
int child_exit_code(void)
Return the child's exit code.
void print(std::ostream &out)
Dump execute object information – used for debugging.
bool child_exited_normally(void)
Returns true if the child has exited normally.
bool check_read_ready_(int fd)
Return true if the file descriptor has input ready to be read.
Fork a child process or execute an external program.
pid_t check_child_(void)
Check the child's status.
int in_read(char *buf, const int len)
Allow child to read input from in_fd()
bool in_ready(void)
Check I/O for input.
bool in_eof(void)
Check for input EOF.
bool child_exited(void)
Returns true of the child has existed.
pid_t my_pid(void)
Returns the PID.
int err_fd(void)
Return a file descriptor for I/O between parent and child.
#define ERROR_INSTANCE(s)
int out_write(const char *buf, const int len)
Allow child to write to out_fd()
bool check_write_ready_(int fd)
Return true if the file descriptor is ready to be written to.
void wait(void)
Wait for the child to exit.
bool is_child(void)
Returns true if called by the child.
bool is_parent(void)
Returns true if called by the parent.
int in_fd(void)
Return a file descriptor for I/O between parent and child.