From 0a87951d8f70e5e065337a84533b87dab407068f Mon Sep 17 00:00:00 2001 From: Jason Hiser <jdhiser@gmail.com> Date: Tue, 17 Dec 2019 20:26:26 -0500 Subject: [PATCH] fixed deadlock in pipe command --- .../libIRDB-core/include/libIRDB-core.hpp | 2 - irdb-libs/libIRDB-core/src/cmdstr.hpp | 68 ++++++++++++++----- irdb-libs/libIRDB-core/src/file.cpp | 1 + irdb-libs/libIRDB-core/src/fileir.cpp | 2 + irdb-libs/libIRDB-core/src/instruction.cpp | 1 + 5 files changed, 54 insertions(+), 20 deletions(-) diff --git a/irdb-libs/libIRDB-core/include/libIRDB-core.hpp b/irdb-libs/libIRDB-core/include/libIRDB-core.hpp index 0d8d5f5ac..b791d9544 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 b99a87d3b..eeccc1bb0 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 87a55124b..e61265ed7 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 901c2463f..0277d7780 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 447f432de..d723741e1 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 -- GitLab