Boost logo

Boost :

Subject: Re: [boost] Boost.Process 0.5 released
From: Boris Schaeling (boris_at_[hidden])
Date: 2012-08-20 18:11:52

On Sat, 18 Aug 2012 23:54:24 +0200, Roland Bock <rbock_at_[hidden]> wrote:

Hi Roland,

> [...]But things like wait_for_exit seem strange to me: If the library
> takes
> care of the forking and handles setting up pipes in such a nice way, why
> should the user of the library be bothered with the different ways of
> interpreting the exit information (unless he really, really wants to)?

can you show me some sample code how you'd like to interpret the exit code?

> Same with a /dev/null sink. Offering a factory method would be easy and
> spares the user.

I think this is a Boost.Iostreams problem. We have a null device in
Boost.Iostreams (see
but it's a class with no-op functions. If the class would open /dev/null
or NUL, one could use the null device. What I can do for now is changing
the example in the Boost.Process documentation. Instead of writing to
/dev/null or NUL, it should write to foo.txt - problem solved. ;)

> [...]I understand that the signal stuff is not required for Windows, but
> why
> not offer a convenience function that sets the signal handler on POSIX
> and does nothing on Windows?
> Same with the discard method. Does something on Windows, does nothing on
> POSIX, and I get to write code without using the #ifdefs every other
> line.

I'm afraid it leads to code obfuscation if you have a superset of all
existing functions platforms provide and they are all used together in the
same code with no clear indication which ones do something useful and
which ones are no-ops. Imagine you had no-op Windows API functions and
no-op POSIX API functions. You could use all system API functions from
Windows and POSIX without #ifdefs in the same source file and claim your
code is platform-indepedent. But I think I wouldn't call it
platform-independent but a complete mess. ;) It is maybe no problem for
the example you are referring to as we are talking only about two lines
here. But we start trading convenience vs. clarity? And if you call
discard() and think you are fine on all platforms, you'd make a mistake?

> The other thing about the discard: I think one of the first things I'd
> do is write a wrapper for child that is non-copyable (as also suggested
> by Joel) and calls discard in its destructor. I wonder if that should
> not be part of the library, too?

This is related to the paragraph above. The RAII type would only make
sense on Windows but the code would compile on all platforms. If you don't
know that you must do something extra on POSIX (like ignoring SIGCHLD),
your program will leak resources (leaking is maybe the wrong word as init
will clean up after the program exits; but you might be tricked into
thinking the platform-independent RAII type does something for you on all
platforms which wouldn't be true).

> With the probable exception of the asynchronous IO and wait, I think it
> should be possible to get rid of the #ifdefs in the tutorial. And IMHO
> that would be a nice improvement for what looks like a cool library
> already :-)

Thanks! I mentioned it already in another email I think: If I rewrite some
and remove other examples from the tutorial, most of the #ifdefs could
disappear. Boost.Process would still support all of that (and I know
anyway how to do all of that myself :). But it would make it more
difficult for others as everyone would have to figure out himself how to
do certain things like asynchronous I/O. I agree that the best solution
would still be to support everything with truly platform-independent
classes and functions. But I think that some problems have be solved in
Boost.Asio (posix::stream_descriptor vs. windows::stream_handle) or
Boost.Iostreams (/dev/null vs. NUL) and that other problems are a bit more
complicated that it's not clear at all how to solve them in a
platform-independent way (signals vs. wait functions)?


> [...]

Boost list run by bdawes at, gregod at, cpdaniel at, john at