From 0973ec45e9bdb7760a5480a14d712373b4990750 Mon Sep 17 00:00:00 2001 From: Adrian Kummerlaender Date: Thu, 1 Jun 2017 16:24:47 +0200 Subject: Adapt `FunctionExternalCommand` to new `boost::process` version --- src/function/external_command.cc | 111 ++++++++++++++++++--------------------- 1 file changed, 50 insertions(+), 61 deletions(-) (limited to 'src/function') diff --git a/src/function/external_command.cc b/src/function/external_command.cc index dda403e..0190de5 100644 --- a/src/function/external_command.cc +++ b/src/function/external_command.cc @@ -24,13 +24,14 @@ inline bool isWrappedOutput(const XMLCh* nodeName) { } std::unique_ptr readOutput( - boost::process::pistream& outputStream) { + boost::process::ipstream& outputStream) { const std::string rawOutput( (std::istreambuf_iterator(outputStream)), (std::istreambuf_iterator()) ); - if ( rawOutput.substr(0, 5) == "( rawOutput ); @@ -61,20 +62,6 @@ boost::optional importDocumentElement( } } -boost::process::context createContext( - const InputXSLT::FilesystemContext& fsContext) { - boost::process::context context; - - context.environment = boost::process::self::get_environment(); - context.stdout_behavior = boost::process::capture_stream(); - context.stdin_behavior = boost::process::capture_stream(); - context.work_directory = boost::filesystem::canonical( - fsContext.getBase().parent_path() - ).string(); - - return context; -} - } namespace InputXSLT { @@ -84,61 +71,63 @@ DomDocumentCache::document_ptr FunctionExternalCommand::constructDocument( std::string command, boost::optional input ) const { - DomDocumentCache::document_ptr domDocument{ - DomDocumentCache::createDocument("content") - }; + namespace bp = boost::process; - boost::process::child commandProcess{ - boost::process::launch_shell(command, createContext(fsContext)) - }; + DomDocumentCache::document_ptr domDocument{ + DomDocumentCache::createDocument("content")}; + ResultNodeFacade result(domDocument.get(), "command"); - if ( input ) { - boost::process::postream& inputStream = commandProcess.get_stdin(); - inputStream << *input; - inputStream.close(); - } + try { + bp::ipstream commandOutput; + bp::opstream commandInput; - std::unique_ptr outputStream{ - readOutput(commandProcess.get_stdout()) - }; - boost::process::status status = commandProcess.wait(); + bp::child commandProcess{ + command, + bp::start_dir = boost::filesystem::canonical(fsContext.getBase().parent_path()), + bp::std_out = commandOutput, + bp::std_in = commandInput + }; - ResultNodeFacade result(domDocument.get(), "command"); - result.setAttribute("executed", command); - result.setAttribute("code", std::to_string(status.exit_status())); - - if ( status.exited() ) { - try { - if ( boost::optional documentElement{ - importDocumentElement( - outputStream.get(), - domDocument.get() - ) - } ) { - if ( isWrappedOutput((*documentElement)->getNodeName()) ) { - result.setContent( - (*documentElement)->getChildNodes() - ); - } else { - result.setContent(*documentElement); - } - - result.setAttribute("result", "success"); + if ( input ) { + commandInput << *input; + commandInput.flush(); + } + commandInput.pipe().close(); + + std::unique_ptr outputStream{ + readOutput(commandOutput)}; + commandProcess.wait(); + + result.setAttribute("executed", command); + result.setAttribute("code", std::to_string(commandProcess.exit_code())); + + if ( boost::optional documentElement{ + importDocumentElement(outputStream.get(), domDocument.get()) + } ) { + if ( isWrappedOutput((*documentElement)->getNodeName()) ) { + result.setContent( + (*documentElement)->getChildNodes() + ); } else { - result.setAttribute("result", "error"); + result.setContent(*documentElement); } - } - catch ( const xercesc::DOMException& exception ) { - result.setAttribute("result", "error"); - result.setValueNode( - "error", - *XercesStringGuard(exception.msg) - ); + result.setAttribute("result", "success"); + } else { + result.setAttribute("result", "error"); } - } else { + } + catch ( const std::system_error& exception ) { result.setAttribute("result", "error"); } + catch ( const xercesc::DOMException& exception ) { + result.setAttribute("result", "error"); + + result.setValueNode( + "error", + *XercesStringGuard(exception.msg) + ); + } return domDocument; } -- cgit v1.2.3