Boost logo

Boost :

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

On Mon, 20 Aug 2012 00:53:28 +0200, Alexander Lamaison
<awl03_at_[hidden]> wrote:

> [...]
>> For asynchronous I/O Boost.Process relies on Boost.Asio. Boost.Asio
>> provides two I/O objects which are unfortunately
>> platform-specific. While unfortunate I'm not sure whether this is a
>> Boost.Process problem? It's just that because of Boost.Process we
>> realize that we have no platform-independent class in Boost.Asio for
>> native handles?
> Could these not be typedefs in Boost.Process. After all, you go on to
> use them the same way.

Yes, this could work. posix::stream_descriptor has a few more member
functions than windows::stream_handle. But there is no difference in
regard to the asynchronous read/write operations. I wonder though whether
the typedef shouldn't be provided by Boost.Asio? Or instead of a typedef
Boost.Asio could provide a new class boost::asio::file_descriptor_stream
which could be initialized with a boost::iostreams::file_descriptor_sink
or boost::iostreams::file_descriptor_source?

> [...]I only vaguely remember the last review. Can you remind me what the
> problem was?

The main problem was to create a class which basically does what
boost::asio::signal_set and boost::asio::windows::object_handle do. These
classes are very different, and if you put all their code into one class
it's an interesting mixture of signal handling code and Windows wait
functions. ;) That signals are handled globally in an application doesn't
make it easier. If you look at the two classes in the Boost.Asio
documentation I guess no one would ever think that it's a good idea to
merge them (it makes much more sense for posix::stream_descriptor and

> [...]Yuk. At this point my only thought is how have others done it? (It
> must
> have been done before) What about the Java or Python runtimes? I
> suppose they get to steal the signal all for themselves which makes
> their job easier.

I think they don't need to care much about the system level. They can
invent a new concept Foo, and the rest is a matter of implementation
details. But I'm not sure whether this is the way to go for a Boost C++
library? What I've been trying to do in Boost.Process 0.5 is making
existing cross-platform concepts platform-independent in code. I didn't
try to invent new concepts. So where I didn't find cross-platform concepts
I accepted the fact that platforms are different and used the appropriate
C++ tool to express the difference: #ifdef.

Maybe someone has a great idea how to make SIGCHLD and Windows wait
functions platform-independent. I gave it a shot once, and it was rather
messy. Maybe it's not a SIGCHLD vs. Windows wait function problem either
but must be solved on a very different level. I don't know. I think that's
a task and maybe even a library of its own. It took me already half a year
to create windows::object_handle after the status class in Boost.Process
0.4 was rejected. I don't know how long it will take to solve the
SIGCHLD/Windows wait function problem. And this is not the first time that
it is discussed on the mailing list (only six years since the very first
Boost.Process draft ;).

> [...]My criticism wasn't directed at any lack of initialisers, just that
> the
> default behaviour of the two platforms varied when the library could
> make it match, either favouring the POSIX way of inheriting nothing by
> default or the Windows way of inheriting everything.

Ah, I see. Well, I think I prefer the Law of Economy: If I don't need
something, I don't add it. Here it means undefined behavior if you don't
use an initializer for environment variables. But if you don't care about
environment variables, that's fine and there is no need to do something
extra in the library.

> [...]Exceptions. The error reporting interface of the `execute` function
> looks a little unusual. Have you looked at how Boost.Filesystem does
> it? Their functions are overloaded so that the ones taking an error
> code argument don't throw but set the argument and the ones without just
> throw. No need for `set_on_error`, `throw_on_error`.

Yes, I modeled wait_for_exit() and terminate() after the functions in
Boost.Filesystem. But execute() has such a different interface that I felt
it makes more sense if everything is an initializer. Besides there is this
issue on POSIX that you need another initializer return_on_error if you
want to know somehow whether execve() failed in the child process.

> Unicode. Again, you might want to look at how Boost.Filesystem (v3
> only) handles it. It always calls the wchar_t versions of the Windows
> API and converts the strings internally using a locale. By default the
> behaviour is exactly the same but the advantage is you can pass in a
> custom locale to interpret the strings. This is particularly important
> for narrow char strings in Windows which, are *not* treated as Unicode
> (UTF-8) but rather the local user's code page. The result is that you
> cannot launch a program with a mix of characters from different code
> pages. For example, a Greek user (whose username is presumably in Greek)
> could not launch a program in his user directory and pass it a Russian
> word as an argument. With a custom UTF-8 locale object, it all works
> fine. Of course, you can use the wchar_t interface to do that but that
> makes it difficult to write cross-platform code which is, after all the
> purpose of a cross-platform process library. I know Artyom, for one,
> has strong opinions on this. Not a priority at the moment though but I
> thought I'd mention is before I forget.

And I was already happy to support Unicode API functions on Windows at
all. :)

Thanks for this feedback and the example! I agree it would be useful if
the library supported a UTF-8 locale. Sounds like a nice idea to work on
once all major issues have been resolved. ;)


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