Boost logo

Boost :

Subject: Re: [boost] Boost.Process 0.5 released
From: Boris Schaeling (boris_at_[hidden])
Date: 2012-08-25 11:27:55


On Tue, 21 Aug 2012 10:06:49 +0200, Roland Bock <rbock_at_[hidden]> wrote:

> [...]b) Hmm. Not following. Why not use the null sink from
> boost::iostreams?
> You can create a stream from it that does what I would expect from
> redirecting to /dev/null: Discard all data.

Indeed it would be nice if you could write something like:

execute(
   run_exe("test.exe"),
   bind_stdout(boost::iostreams::null_sink())
);

Unfortunately null_sink doesn't open a file descriptor or HANDLE (it's
just that its read and write functions are no-ops). And without a file
descriptor or HANDLE there is nothing to inherit by the child process.
That's why I had to open /dev/null or NUL myself in the example (and had
to use #ifdefs ;).

> BTW: It might also help to explain whether or not you could just add ">
> /dev/null" to the argument list (and if you could what the differences
> are, for example if one way is expected to be more performant).

That's a good point, noted!

> [...]I am hoping for a way that lets 95% of the users write platform
> independent code without the need for #ifdefs.

So far I'm already happy that for 95% of process related tasks I can write
platform-independent code. I'm looking at this other 5% where I have to
use #ifdefs as a mild but bearable annoyance. :)

> [...]Why? If you say that in POSIX, the typical, the 95% case is to use
> the
> signal call, then I would expect the library to do that for me. And if I
> happen to be one of the 5% who don't want to do what most of the others
> need, then I need to take special care, and probably use ifdefs.
>
> Thus, maybe you could offer a lightweight child class (as it is right
> now) and a RAII child class that does the signal/discard calls.

I don't know whether it's 95% to 5% or the opposite. I find it quite
difficult to set a standard here. If we assume for example that most of
the time people would like to get the exit code from a child process
(which doesn't sound like a bad assumption either?), and it happens that
this should be done asynchronously, ignoring SIGCHLD by default would be
rather bad. As ignoring SIGCHLD and catching SIGCHLD are also very
different operations (one line vs. a Boost.Asio I/O object) it doesn't
sound easy either to put all of this into a RAII type. (If
boost::asio::signal_set would provide a function to ignore a signal, one
wouldn't need to use a system API function like signal() directly. But
then I'm not sure whether Chris would agree to extend
boost::asio::signal_set for that. :)

> [...]If the #ifdefs are required right now for the given examples, then
> using
> different examples removes a symptom, not the cause. I'd prefer the same
> examples.
>
> * #boost_process.tutorial.cleaning_up_resources
> As written above, I'd offer a second version of the child class
> which does the signal/discard in constructor/destructor.

This is indeed the most important problem. Cleaning up resources is
something which can't be ignored (unless you have short-running programs).

> * #boost_process.tutorial.setting_up_standard_streams
> Using boost::iostreams::stream<boost::iostreams::null_sink>
> null((boost::iostreams::null_sink())); obsoletes the system
> dependency (and I would add the examples and hints mentioned above)

Here we seem to have a misunderstanding (see my explanation above). It
would be indeed great if null_sink or null_source could be used.

> * #boost_process.tutorial.asynchronous_i_o
> It might make sense to add such a typedef to boost process for
> convenience. Maybe not. Not sure.
> * #boost_process.tutorial.waiting_for_a_program_to_exit
> o The first #ifdef is hidden in the text: WEXITSTATUS required for
> POSIX? I guess that 90%+ would want to just get the exit code
> and be done with it.

To move somewhat forward with Boost.Process: I (or others if they like -
just send me an email) will create some utility classes and functions
which are not truly mapping existing concepts on all platforms and put
them into their own namespace (and probably header file). They would
provide the convenience some people ask for. And they would also make it
clear that they don't fit perfectly in with the rest of the library and
can have quirks.

> o I am not sure about the #ifdef in the code. Maybe somebody has a
> nice idea, otherwise I would just let leave it as it is.

I agree. Even an utility class wouldn't probably be easy to use.

Boris


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk