diff --git a/irdb-libs/libIRDB-core/include/libIRDB-core.hpp b/irdb-libs/libIRDB-core/include/libIRDB-core.hpp index 0d8d5f5ac23fcda5e001b8f3289587985529df44..b791d9544845d7ff3dfe432fdf7fdee58e885ee8 100644 --- a/irdb-libs/libIRDB-core/include/libIRDB-core.hpp +++ b/irdb-libs/libIRDB-core/include/libIRDB-core.hpp @@ -54,7 +54,5 @@ #include <IRDB_Objects.hpp> #include <decode.hpp> -int command_to_stream(const std::string& command, std::ostream& stream); - #endif diff --git a/irdb-libs/libIRDB-core/src/cmdstr.hpp b/irdb-libs/libIRDB-core/src/cmdstr.hpp index b99a87d3bce18a2b968fa691195cc82f0060c3bd..eeccc1bb0a34614837db055fa8b44bb307d10632 100644 --- a/irdb-libs/libIRDB-core/src/cmdstr.hpp +++ b/irdb-libs/libIRDB-core/src/cmdstr.hpp @@ -1,10 +1,7 @@ #ifndef cmdstr_hpp #define cmdstr_hpp -/*BINFMTCXX: -std=c++11 -Wall -Werror -*/ - -#include <spawn.h> // see manpages-posix-dev +#include <spawn.h> #include <poll.h> #include <stdio.h> #include <stdlib.h> @@ -14,18 +11,45 @@ #include <iostream> #include <string> #include <vector> +#include <array> + using namespace std; static inline pair<string,int> command_to_string( const string& command) { auto ret=string(); int exit_code=0; - int cout_pipe[2]; - int cerr_pipe[2]; posix_spawn_file_actions_t action; - if(pipe(cout_pipe) || pipe(cerr_pipe)) - cout << "pipe returned an error.\n"; + + const auto pipe_closer = function<void(int*)>([](int *p_pipefd) -> void + { + const auto pipe = *p_pipefd; + close(pipe); + delete p_pipefd; + }); + using PipeFD_t = unique_ptr<int,decltype(pipe_closer)>; + + const auto pipe_opener = [&]() -> vector<PipeFD_t> + { + auto pipe_fds = array<int,2>(); + if(pipe( pipe_fds.data())) + { + const auto err_str = string(strerror(errno)); + throw runtime_error("Cannot open pipe: " + err_str); + } + auto ret = vector<PipeFD_t>(); +// PipeFD_t p(new int(pipe_fds[0]), pipe_closer); +// ret.push_back(move(p)); + ret.push_back({new int(pipe_fds[0]), pipe_closer}); + ret.push_back({new int(pipe_fds[1]), pipe_closer}); + return ret; + }; + + auto cout_pipe_vec = pipe_opener(); + auto cerr_pipe_vec = pipe_opener(); + const auto cout_pipe = vector<int>{*(cout_pipe_vec[0]), *(cout_pipe_vec[1])}; + const auto cerr_pipe = vector<int>{*(cerr_pipe_vec[0]), *(cerr_pipe_vec[1])}; posix_spawn_file_actions_init(&action); posix_spawn_file_actions_addclose(&action, cout_pipe[0]); @@ -36,8 +60,6 @@ static inline pair<string,int> command_to_string( const string& command) posix_spawn_file_actions_addclose(&action, cout_pipe[1]); posix_spawn_file_actions_addclose(&action, cerr_pipe[1]); - // string command = "echo bla"; // example #1 - // string command = "pgmcrater -width 64 -height 9 |pgmtopbm |pnmtoplainpnm"; vector<char> argsmem[] = {{'s', 'h', '\0'}, {'-', 'c', '\0'}}; // allows non-const access to literals char *args[] = {&argsmem[0][0], &argsmem[1][0],const_cast<char*>(command.c_str()),nullptr}; @@ -45,23 +67,23 @@ static inline pair<string,int> command_to_string( const string& command) if(posix_spawnp(&pid, args[0], &action, NULL, args, environ) != 0) cout << "posix_spawnp failed with error: " << strerror(errno) << "\n"; - close(cout_pipe[1]), close(cerr_pipe[1]); // close child-side of pipes + cout_pipe_vec[1].reset(); + cerr_pipe_vec[1].reset(); // close child-side of pipes + // Read from pipes string buffer(1024,' '); - std::vector<pollfd> plist = { {cout_pipe[0],POLLIN}, {cerr_pipe[0],POLLIN} }; + vector<pollfd> plist = { {cout_pipe[0],POLLIN}, {cerr_pipe[0],POLLIN} }; for ( int rval; (rval=poll(&plist[0],plist.size(),/*timeout*/-1))>0; ) { - if ( plist[0].revents&POLLIN) { + if ( plist[0].revents&POLLIN) + { const auto bytes_read = read(cout_pipe[0], &buffer[0], buffer.length()); - // cout << "read " << bytes_read << " bytes from stdout.\n"; - // cout << buffer.substr(0, static_cast<size_t>(bytes_read)) << "\n"; ret += buffer.substr(0, static_cast<size_t>(bytes_read)); } - else if ( plist[1].revents&POLLIN ) { + else if ( plist[1].revents&POLLIN ) + { const auto bytes_read = read(cerr_pipe[0], &buffer[0], buffer.length()); - // cout << "read " << bytes_read << " bytes from stderr.\n"; - // cout << buffer.substr(0, static_cast<size_t>(bytes_read)) << "\n"; ret += buffer.substr(0, static_cast<size_t>(bytes_read)); } else @@ -75,4 +97,14 @@ static inline pair<string,int> command_to_string( const string& command) return {ret,exit_code}; } +static inline int command_to_stream(const string& command, ostream& stream) +{ + cout << "Issuing command: " << command << endl; + const auto res = command_to_string(command); + + stream << res.first << endl; + return res.second; +} + + #endif diff --git a/irdb-libs/libIRDB-core/src/file.cpp b/irdb-libs/libIRDB-core/src/file.cpp index 87a55124bb4324f7d4859786c08ce2e1256cf363..e61265ed77e375dd144341120827c747439dee1e 100644 --- a/irdb-libs/libIRDB-core/src/file.cpp +++ b/irdb-libs/libIRDB-core/src/file.cpp @@ -25,6 +25,7 @@ #include <unistd.h> #include <fstream> #include <iostream> +#include "cmdstr.hpp" #include <irdb-util> diff --git a/irdb-libs/libIRDB-core/src/fileir.cpp b/irdb-libs/libIRDB-core/src/fileir.cpp index 901c2463f7fcaa6d452903b46aa4d5b711710f36..0277d77806b2ad23283a7d4ef55aec416470fa51 100644 --- a/irdb-libs/libIRDB-core/src/fileir.cpp +++ b/irdb-libs/libIRDB-core/src/fileir.cpp @@ -44,6 +44,7 @@ using namespace std; #undef EIP +#if 0 int command_to_stream(const string& command, ostream& stream) { cout << "Issuing command: " << command << endl; @@ -52,6 +53,7 @@ int command_to_stream(const string& command, ostream& stream) stream << res.first << endl; return res.second; } +#endif static void UpdateEntryPoints( const std::map<db_id_t,Instruction_t*> &insnMap, diff --git a/irdb-libs/libIRDB-core/src/instruction.cpp b/irdb-libs/libIRDB-core/src/instruction.cpp index 447f432de30535e300160d5231786c6e85ed0202..d723741e1bb2673555dd76cfbfdd1eeba07652e7 100644 --- a/irdb-libs/libIRDB-core/src/instruction.cpp +++ b/irdb-libs/libIRDB-core/src/instruction.cpp @@ -25,6 +25,7 @@ #include <sstream> #include <iomanip> #include <irdb-util> +#include "cmdstr.hpp" #undef EIP