From bc48696d7f463d0a230193f2173ec8516a2ca4b0 Mon Sep 17 00:00:00 2001 From: Adrian Kummerlaender Date: Thu, 16 Oct 2014 19:20:04 +0200 Subject: Changed FunctionExternalCommand stream read order * long outputs to stdout from child processes filled up the `boost::process::pistream` buffer and caused `write` to block ** this issue was circumvented by reading the stream into a `std::stringstream` instance before retrieving the blocking exit status * modified document import implementation accordingly --- src/function/external_command.cc | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) (limited to 'src/function/external_command.cc') diff --git a/src/function/external_command.cc b/src/function/external_command.cc index 3819a43..40b02b9 100644 --- a/src/function/external_command.cc +++ b/src/function/external_command.cc @@ -15,19 +15,22 @@ namespace { using InputXSLT::XercesStringGuard; -inline xercesc::DOMNode* importDocumentElement( - boost::process::pistream& outputStream, - xercesc::DOMDocument* const domDocument -) { - std::stringstream xmlStream( +inline std::unique_ptr readOutput( + boost::process::pistream& outputStream) { + return std::make_unique( "" + std::string( (std::istreambuf_iterator(outputStream)), (std::istreambuf_iterator()) ) + "" ); +} +inline xercesc::DOMNode* importDocumentElement( + std::stringstream* const outputStream, + xercesc::DOMDocument* const domDocument +) { xercesc::XercesDOMParser parser; - parser.parse(xalan::XSLTInputSource(xmlStream)); + parser.parse(xalan::XSLTInputSource(*outputStream)); return domDocument->importNode( parser.getDocument()->getDocumentElement(), @@ -66,8 +69,11 @@ DomDocumentCache::document_ptr FunctionExternalCommand::constructDocument( inputStream.close(); } - boost::process::pistream& outputStream = commandProcess.get_stdout(); - boost::process::status status = commandProcess.wait(); + std::unique_ptr outputStream{ + readOutput(commandProcess.get_stdout()) + }; + + boost::process::status status = commandProcess.wait(); ResultNodeFacade result(domDocument.get(), "command"); result.setAttribute("executed", command); @@ -77,7 +83,7 @@ DomDocumentCache::document_ptr FunctionExternalCommand::constructDocument( try { result.setContent( importDocumentElement( - outputStream, + outputStream.get(), domDocument.get() )->getChildNodes() ); -- cgit v1.2.3