From 19c465bdaf18acc96372365411a9c10cb5d0cd9e Mon Sep 17 00:00:00 2001 From: Phanes Date: Fri, 1 Dec 2017 03:24:07 -0500 Subject: [PATCH] initial implementation of subprocess execution. currently is merging child STDOUT and child STDERR into parent STDOUT. Next effort. --- conf/units/all_test.units | 2 +- src/sproc/Sproc.cpp | 111 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 107 insertions(+), 6 deletions(-) diff --git a/conf/units/all_test.units b/conf/units/all_test.units index efe4a0e..5e98e87 100644 --- a/conf/units/all_test.units +++ b/conf/units/all_test.units @@ -2,7 +2,7 @@ "units": [ { "name": "independent test 1", - "target": "/usr/bin/true", + "target": "(>&2 echo 'error is a doodle day')", "rectifier": "/usr/bin/true", "active": true, "required": true, diff --git a/src/sproc/Sproc.cpp b/src/sproc/Sproc.cpp index 580760a..d3dcfc9 100644 --- a/src/sproc/Sproc.cpp +++ b/src/sproc/Sproc.cpp @@ -1,10 +1,111 @@ #include "Sproc.h" +#include +#include - - -int Sproc::execute( std::string input ) -{ +/// Sproc::execute +/// +/// \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) { std::cout << std::endl << "made it to subprocess execution but not implemented yet" << std::endl << std::endl; - return EXIT_SUCCESS; + int PIPE_READ = 0; + int PIPE_WRITE = 1; + + int stdin_pipe[2]; + // int aStderrPipe[2]; + int stdout_pipe[2]; + int child_pid; + char nChar; + int child_exit_code; + + if (pipe(stdin_pipe) < 0) + { + perror("allocating pipe for child input redirect"); + return -1; + } + +/* + if (pipe(aStderrPipe < 0)) { + close(aStderrPipe[PIPE_READ]); + close(aStderrPipe[PIPE_WRITE]); + perror("allocating pipe for error redirect"); + return -1; + } +*/ + + if (pipe(stdout_pipe) < 0) + { + close(stdin_pipe[PIPE_READ]); + close(stdin_pipe[PIPE_WRITE]); + perror("allocating pipe for child output redirect"); + return -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(stdout_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]); + + // 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(child_exit_code); + } else if (child_pid > 0) { + // parent continues here + + // close unused file descriptors, these are for child only + close(stdin_pipe[PIPE_READ]); + close(stdout_pipe[PIPE_WRITE]); + + // da fuq? +/* // Include error check here + if (NULL != szMessage) + { + write(stdin_pipe[PIPE_WRITE], szMessage, strlen(szMessage)); + } +*/ + + // Just a char by char read here, you can change it accordingly + while (read(stdout_pipe[PIPE_READ], &nChar, 1) == 1) + { + 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]); + } else { + // failed to create child + close(stdin_pipe[PIPE_READ]); + close(stdin_pipe[PIPE_WRITE]); + close(stdout_pipe[PIPE_READ]); + close(stdout_pipe[PIPE_WRITE]); + } + return child_exit_code; } \ No newline at end of file