fixed subprocess execution and redirect. now supports curses, ssh clients, and more.
parent
6fd80a31c5
commit
c92be3f4be
|
@ -18,7 +18,7 @@
|
|||
},
|
||||
{
|
||||
"name": "A DEFINITION THAT IS NOT USED",
|
||||
"target": "/usr/bin/false",
|
||||
"target": "/usr/bin/dialog --yesno test 50 50",
|
||||
"rectifier": "/usr/bin/false",
|
||||
"active": true,
|
||||
"required": true,
|
||||
|
@ -26,10 +26,10 @@
|
|||
},
|
||||
{
|
||||
"name": "dependent test",
|
||||
"target": "/usr/bin/false",
|
||||
"target": "ssh root@phanes.silogroup.org",
|
||||
"rectifier": "/usr/bin/false",
|
||||
"active": true,
|
||||
"required": true,
|
||||
"required": false,
|
||||
"rectify": true
|
||||
}
|
||||
]
|
||||
|
|
|
@ -114,17 +114,17 @@ void Plan::load_definitions( Suite unit_definitions, bool verbose )
|
|||
void Plan::execute( bool verbose )
|
||||
{
|
||||
// for each task in this plan
|
||||
// for ( int i = 0; i < this->tasks.size(); i++ )
|
||||
// {
|
||||
// if ( verbose ) {
|
||||
// std::cout << "Executing task \"" << this->tasks[i].get_name() << "\"." << std::endl;
|
||||
std::cout << "Executing task \"" << this->tasks[0].get_name() << "\"." << std::endl;
|
||||
// }
|
||||
// this->tasks[i].execute( verbose );
|
||||
this->tasks[0].execute( verbose );
|
||||
for ( int i = 0; i < this->tasks.size(); i++ )
|
||||
{
|
||||
if ( verbose ) {
|
||||
std::cout << "Executing task \"" << this->tasks[i].get_name() << "\"." << std::endl;
|
||||
// std::cout << "Executing task \"" << this->tasks[0].get_name() << "\"." << std::endl;
|
||||
}
|
||||
this->tasks[i].execute( verbose );
|
||||
// this->tasks[0].execute( verbose );
|
||||
|
||||
// for testing a logic issue in Task.execute(), remove when done
|
||||
// throw Plan_InvalidTaskIndex();
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,131 +8,8 @@
|
|||
/// \param input - The commandline input to execute.
|
||||
/// \return - The return code of the execution of input in the calling shell.
|
||||
int Sproc::execute(std::string input) {
|
||||
int PIPE_READ = 0;
|
||||
int PIPE_WRITE = 1;
|
||||
|
||||
int stdin_pipe[2];
|
||||
int stderr_pipe[2];
|
||||
int stdout_pipe[2];
|
||||
pid_t child_pid, w;
|
||||
char nChar;
|
||||
int child_exit_code = -666;
|
||||
|
||||
// experimental
|
||||
int status;
|
||||
|
||||
if ( pipe(stdin_pipe) < 0 )
|
||||
{
|
||||
perror("allocating pipe for child input redirect");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if ( pipe(stdout_pipe) < 0 )
|
||||
{
|
||||
close(stdin_pipe[PIPE_READ]);
|
||||
close(stdin_pipe[PIPE_WRITE]);
|
||||
perror("allocating pipe for child output redirect");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if ( pipe(stderr_pipe) < 0 ) {
|
||||
close(stderr_pipe[PIPE_READ]);
|
||||
close(stderr_pipe[PIPE_WRITE]);
|
||||
perror("allocating pipe for error redirect");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
|
||||
child_pid = fork();
|
||||
if (0 == child_pid)
|
||||
{
|
||||
// child continues here
|
||||
|
||||
// redirect stdin
|
||||
if (dup2(stdin_pipe[PIPE_READ], STDIN_FILENO) == -1) {
|
||||
exit(errno);
|
||||
}
|
||||
|
||||
// redirect stdout
|
||||
if (dup2(stdout_pipe[PIPE_WRITE], STDOUT_FILENO) == -1) {
|
||||
exit(errno);
|
||||
}
|
||||
|
||||
// redirect stderr
|
||||
if (dup2(stderr_pipe[PIPE_WRITE], STDERR_FILENO) == -1) {
|
||||
exit(errno);
|
||||
}
|
||||
|
||||
// all these are for use by parent only
|
||||
close(stdin_pipe[PIPE_READ]);
|
||||
close(stdin_pipe[PIPE_WRITE]);
|
||||
|
||||
close(stdout_pipe[PIPE_READ]);
|
||||
close(stdout_pipe[PIPE_WRITE]);
|
||||
|
||||
close(stderr_pipe[PIPE_READ]);
|
||||
close(stderr_pipe[PIPE_WRITE]);
|
||||
|
||||
|
||||
// run child process image
|
||||
// replace this with any exec* function find easier to use ("man exec")
|
||||
child_exit_code = system( input.c_str() );
|
||||
|
||||
// if we get here at all, an error occurred, but we are in the child
|
||||
// process, so just exit
|
||||
exit(WEXITSTATUS(child_exit_code));
|
||||
} else if (child_pid > 0) {
|
||||
// parent continues here
|
||||
|
||||
do {
|
||||
w = waitpid(child_pid, &child_exit_code, WUNTRACED | WCONTINUED);
|
||||
if (w == -1) {
|
||||
perror("waitpid");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (WIFEXITED(child_exit_code)) {
|
||||
;;
|
||||
//printf("exited, status=%d\n", WEXITSTATUS(child_exit_code));
|
||||
} else if (WIFSIGNALED(child_exit_code)) {
|
||||
printf("killed by signal %d\n", WTERMSIG(child_exit_code));
|
||||
} else if (WIFSTOPPED(child_exit_code)) {
|
||||
printf("stopped by signal %d\n", WSTOPSIG(child_exit_code));
|
||||
} else if (WIFCONTINUED(child_exit_code)) {
|
||||
printf("continued\n");
|
||||
}
|
||||
} while (!WIFEXITED(child_exit_code) && !WIFSIGNALED(child_exit_code));
|
||||
|
||||
// close unused file descriptors, these are for child only
|
||||
close(stdin_pipe[PIPE_READ]);
|
||||
close(stdout_pipe[PIPE_WRITE]);
|
||||
close(stderr_pipe[PIPE_WRITE]);
|
||||
|
||||
// Just a char by char read here, you can change it accordingly
|
||||
while ( read( stdout_pipe[PIPE_READ], &nChar, 1 ) == 1 )
|
||||
{
|
||||
// does this loop also need to involve STDERR? -CP
|
||||
write(STDOUT_FILENO, &nChar, 1);
|
||||
}
|
||||
|
||||
// done with these in this example program, you would normally keep these
|
||||
// open of course as long as you want to talk to the child
|
||||
close(stdin_pipe[PIPE_WRITE]);
|
||||
close(stdout_pipe[PIPE_READ]);
|
||||
close(stderr_pipe[PIPE_READ]);
|
||||
} else {
|
||||
// failed to create child
|
||||
std::cout << "Failed to create child." << std::endl;
|
||||
close(stdin_pipe[PIPE_READ]);
|
||||
close(stdin_pipe[PIPE_WRITE]);
|
||||
|
||||
close(stdout_pipe[PIPE_READ]);
|
||||
close(stdout_pipe[PIPE_WRITE]);
|
||||
|
||||
close(stderr_pipe[PIPE_READ]);
|
||||
close(stderr_pipe[PIPE_WRITE]);
|
||||
}
|
||||
child_exit_code = WEXITSTATUS( child_exit_code );
|
||||
|
||||
return child_exit_code;
|
||||
}
|
Loading…
Reference in New Issue