Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
214 views
in Technique[技术] by (71.8m points)

c++ - How to bind program termination with end-of-stream in Boost.Process 0.5?

In this simple example of Boost.Process 0.5 ( http://www.highscore.de/boost/process0.5/index.html) the output of a program (ls) is feeding a stream. The stream works fine but contrary to the expectation the stream doesn't become invalid (e.g. end-of-stream) after the program finishes (similar to previous version of Boost.Process, e.g. http://www.highscore.de/boost/process/index.html)

What am I missing in order to make the stream (is in the example) automatically invalid after child program exits?

Perhaps is it an option that I have to set in the Boost.Streams stream of file_descriptor?

#include <boost/process.hpp> // version 0.5 from http://www.highscore.de/boost/process0.5/process.zip
#include <boost/iostreams/device/file_descriptor.hpp>
#include <boost/iostreams/stream.hpp>
#include <string>
using namespace boost::process;
using namespace boost::process::initializers;
using namespace boost::iostreams;
int main(){
    boost::process::pipe p = create_pipe();
    file_descriptor_sink sink(p.sink, close_handle);
    child c = execute(run_exe("/usr/bin/ls"), bind_stdout(sink));
    file_descriptor_source source(p.source,  close_handle);
    stream<file_descriptor_source> is(source);
    std::string s;
    while(std::getline(is, s)){
        std::cout << "read: " << s << std::endl;
    }
    std::clog << "end" << std::endl; // never reach
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

UPDATE 2020: Boost.Process is now part of Boost https://www.boost.org/doc/libs/1_74_0/doc/html/process.html and this answer might be completely out-of-date. It only applies to an experimental version "0.5" http://www.highscore.de/boost/process0.5/index.html.


I had a private (actually through Nabble) communication with Boris Schaeling, the author of the library. After discarding several possibilities, like bugs in posix/boost.iostreams, he gave me a slight modification of the code that works. Basically, what I can deduce is that the file_descriptor sink must be out of scope (destroyed) in order for the stream to return an EOF. The working code simply adds a specific scope for sink (listed at the end). I think this makes easy to encapsulate all in a pistream kind of class. (Next step in my list will be to allow also output to the process.)

Works with Boost 1.48 (Fedora 17).

#include <boost/process.hpp> // version 0.5
#include <boost/iostreams/device/file_descriptor.hpp>
#include <boost/iostreams/stream.hpp>
#include <string>

using namespace boost::process;
using namespace boost::process::initializers;
using namespace boost::iostreams;

int main() {
    pipe p = create_pipe();
    {
        // note the scope for sink
        file_descriptor_sink sink(p.sink, close_handle);
        /*  child c = */ // not necessary to hold a child object, it seems.
        execute(run_exe("/usr/bin/ls"), bind_stdout(sink));
    }   // note the scope for sink

    file_descriptor_source source(p.source,  close_handle);
    stream<file_descriptor_source> is(source);
    std::string s;
    while(std::getline(is, s)) {
        std::cout << "read: " << s << std::endl;
    }
    std::clog << "end" << std::endl; // never reach
}

Compiles with c(lang)++ -lboost_system -lboost_iostreams

EDIT: This seems to work as well, which avoid the artificial scope, but can be confusing because the sink has to be a temporary:

    ...
    pipe p = create_pipe();
    execute(run_exe("/usr/bin/ls"), bind_stdout(        
        file_descriptor_sink(p.sink, close_handle)
    ));
    file_descriptor_source source(p.source,  close_handle);
    ...

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...