humble beginnings for subprocess- needs reworked
parent
0552f80b77
commit
3bc8908d65
|
@ -3,5 +3,5 @@ project(ftests)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 11)
|
set(CMAKE_CXX_STANDARD 11)
|
||||||
|
|
||||||
set(SOURCE_FILES examplar.cpp src/loaders/loaders.cpp src/loaders/loaders.h src/json/jsoncpp.cpp src/loaders/JSON_Loader.cpp src/loaders/JSON_Loader.h src/loaders/helpers.cpp src/loaders/helpers.h src/loaders/Suite.cpp src/loaders/Suite.h src/loaders/Plan.cpp src/loaders/Plan.h src/loaders/Conf.cpp src/loaders/Conf.h src/loaders/Unit.cpp src/loaders/Unit.h src/loaders/Task.cpp src/loaders/Task.h)
|
set(SOURCE_FILES examplar.cpp src/loaders/loaders.cpp src/loaders/loaders.h src/json/jsoncpp.cpp src/loaders/JSON_Loader.cpp src/loaders/JSON_Loader.h src/loaders/helpers.cpp src/loaders/helpers.h src/loaders/Suite.cpp src/loaders/Suite.h src/loaders/Plan.cpp src/loaders/Plan.h src/loaders/Conf.cpp src/loaders/Conf.h src/loaders/Unit.cpp src/loaders/Unit.h src/loaders/Task.cpp src/loaders/Task.h src/sproc/Sproc.cpp src/sproc/Sproc.h)
|
||||||
add_executable(ftests ${SOURCE_FILES})
|
add_executable(ftests ${SOURCE_FILES})
|
|
@ -1,4 +1,4 @@
|
||||||
{
|
{
|
||||||
"units_path": "/home/phanes/Development/internal/Examplar/conf/units/all_test.units",
|
"units_path": "/home/phanes/development/internal/Examplar/conf/units/all_test.units",
|
||||||
"plan_path": "/home/phanes/Development/internal/Examplar/conf/plans/test.plan"
|
"plan_path": "/home/phanes/development/internal/Examplar/conf/plans/test.plan"
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ int main( )
|
||||||
bool verbose = true;
|
bool verbose = true;
|
||||||
// A Plan is made up of Tasks, and a Suite is made up of Units.
|
// A Plan is made up of Tasks, and a Suite is made up of Units.
|
||||||
// A Plan declares what units are executed and a Suite declares the definitions of those units.
|
// A Plan declares what units are executed and a Suite declares the definitions of those units.
|
||||||
Conf configuration = Conf("/home/phanes/Development/internal/Examplar/conf/config.json", verbose );
|
Conf configuration = Conf("/home/phanes/development/internal/Examplar/conf/config.json", verbose );
|
||||||
|
|
||||||
// load the configuration file which contains filepaths to definitions of a plan and definitions of units.
|
// load the configuration file which contains filepaths to definitions of a plan and definitions of units.
|
||||||
std::string definitions_file = configuration.get_units_path();
|
std::string definitions_file = configuration.get_units_path();
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "Task.h"
|
#include "Task.h"
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include "../sproc/Sproc.h"
|
||||||
|
|
||||||
/// Task_InvalidDataStructure - Exception thrown when a Task is defined with invalid JSON.
|
/// Task_InvalidDataStructure - Exception thrown when a Task is defined with invalid JSON.
|
||||||
class Task_InvalidDataStructure: public std::runtime_error { public:
|
class Task_InvalidDataStructure: public std::runtime_error { public:
|
||||||
|
@ -96,75 +97,15 @@ void Task::execute( bool verbose )
|
||||||
std::cout << "\t Executing target \"" << this->definition.get_target() << "\"." << std::endl;
|
std::cout << "\t Executing target \"" << this->definition.get_target() << "\"." << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->do_raw_command();
|
ExecutionInput execIn;
|
||||||
}
|
Execution Result;
|
||||||
|
|
||||||
int Task::do_raw_command( std::string command, std::string & STDOUT, std::string & STDIN );
|
execIn.executionString = this->definition.get_target();
|
||||||
{
|
|
||||||
|
|
||||||
/*
|
int execution_status = Sproc::execute( execIn, Result );
|
||||||
* since pipes are unidirectional, we need two pipes. one for data to flow from parent's stdout to child's stdin and
|
|
||||||
* the other for child's stdout to flow to parent's stdin
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define NUM_PIPES 2
|
if ( execution_status )
|
||||||
|
{
|
||||||
#define PARENT_WRITE_PIPE 0
|
std::cout << std::endl << "STDOUT:" << std::endl<< Result.STDOUT << std::endl;
|
||||||
#define PARENT_READ_PIPE 1
|
|
||||||
|
|
||||||
int pipes[NUM_PIPES][2];
|
|
||||||
|
|
||||||
/*
|
|
||||||
* always in a pipe[], pipe[0] is for read and pipe[1] is for write
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define READ_FD 0
|
|
||||||
#define WRITE_FD 1
|
|
||||||
#define PARENT_READ_FD ( pipes[PARENT_READ_PIPE][READ_FD] )
|
|
||||||
#define PARENT_WRITE_FD ( pipes[PARENT_WRITE_PIPE][WRITE_FD] )
|
|
||||||
|
|
||||||
#define CHILD_READ_FD ( pipes[PARENT_WRITE_PIPE][READ_FD] )
|
|
||||||
#define CHILD_WRITE_FD ( pipes[PARENT_READ_PIPE][WRITE_FD] )
|
|
||||||
|
|
||||||
int outfd[2];
|
|
||||||
int infd[2];
|
|
||||||
|
|
||||||
// pipes for parent to write and read
|
|
||||||
pipe(pipes[PARENT_READ_PIPE]);
|
|
||||||
pipe(pipes[PARENT_WRITE_PIPE]);
|
|
||||||
|
|
||||||
if(!fork()) {
|
|
||||||
char *argv[]={ "/usr/bin/bc", "-q", 0};
|
|
||||||
|
|
||||||
dup2(CHILD_READ_FD, STDIN_FILENO);
|
|
||||||
dup2(CHILD_WRITE_FD, STDOUT_FILENO);
|
|
||||||
|
|
||||||
/* Close fds not required by child. Also, we don't
|
|
||||||
want the exec'ed program to know these existed */
|
|
||||||
close(CHILD_READ_FD);
|
|
||||||
close(CHILD_WRITE_FD);
|
|
||||||
close(PARENT_READ_FD);
|
|
||||||
close(PARENT_WRITE_FD);
|
|
||||||
|
|
||||||
execv(argv[0], argv);
|
|
||||||
} else {
|
|
||||||
char buffer[100];
|
|
||||||
int count;
|
|
||||||
|
|
||||||
/* close fds not required by parent */
|
|
||||||
close(CHILD_READ_FD);
|
|
||||||
close(CHILD_WRITE_FD);
|
|
||||||
|
|
||||||
// Write to child’s stdin
|
|
||||||
write(PARENT_WRITE_FD, "2^32\n", 5);
|
|
||||||
|
|
||||||
// Read from child’s stdout
|
|
||||||
count = read(PARENT_READ_FD, buffer, sizeof(buffer)-1);
|
|
||||||
if (count >= 0) {
|
|
||||||
buffer[count] = 0;
|
|
||||||
printf("%s", buffer);
|
|
||||||
} else {
|
|
||||||
printf("IO Error\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
#include "Sproc.h"
|
||||||
|
|
||||||
|
int Sproc::execute(ExecutionInput input, Execution &output)
|
||||||
|
{
|
||||||
|
output.STDOUT = "it worked";
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
#ifndef FTESTS_SPROC_H
|
||||||
|
#define FTESTS_SPROC_H
|
||||||
|
|
||||||
|
#include "string"
|
||||||
|
|
||||||
|
|
||||||
|
struct ExecutionInput {
|
||||||
|
std::string executionString;
|
||||||
|
// std::string STDIN;
|
||||||
|
// std::vector<KeyValuePair> EnvironmentVariables;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Execution {
|
||||||
|
//input
|
||||||
|
ExecutionInput input;
|
||||||
|
|
||||||
|
// output
|
||||||
|
int return_code;
|
||||||
|
|
||||||
|
std::string STDOUT;
|
||||||
|
std::string STDERR;
|
||||||
|
};
|
||||||
|
|
||||||
|
// executes a subprocess and captures STDOUT, STDERR, and return code.
|
||||||
|
// should be able to recieve path of binary to be executed as well as any parameters
|
||||||
|
class Sproc {
|
||||||
|
public:
|
||||||
|
// call the object. returnvalue is enum representing external execution attempt not binary exit code
|
||||||
|
static int execute( ExecutionInput input, Execution & output );
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //FTESTS_SPROC_H
|
Loading…
Reference in New Issue