From c92be3f4bee077553e1d24fa6028e5c41be31d1f Mon Sep 17 00:00:00 2001 From: Phanes Date: Sat, 2 Dec 2017 22:01:09 -0500 Subject: [PATCH] fixed subprocess execution and redirect. now supports curses, ssh clients, and more. --- conf/units/all_test.units | 6 +- src/loaders/Plan.cpp | 18 +++--- src/sproc/Sproc.cpp | 125 +------------------------------------- 3 files changed, 13 insertions(+), 136 deletions(-) diff --git a/conf/units/all_test.units b/conf/units/all_test.units index ccc4e4d..7a4e4e6 100644 --- a/conf/units/all_test.units +++ b/conf/units/all_test.units @@ -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 } ] diff --git a/src/loaders/Plan.cpp b/src/loaders/Plan.cpp index 1af8937..f7959cc 100644 --- a/src/loaders/Plan.cpp +++ b/src/loaders/Plan.cpp @@ -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(); -// } + } } diff --git a/src/sproc/Sproc.cpp b/src/sproc/Sproc.cpp index ca7092c..c2bc0c6 100644 --- a/src/sproc/Sproc.cpp +++ b/src/sproc/Sproc.cpp @@ -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 = system( input.c_str() ); child_exit_code = WEXITSTATUS( child_exit_code ); - return child_exit_code; } \ No newline at end of file