$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
Subject: Re: [boost] Boost.Process article: Tutorial and request for	comments
From: Boris Schaeling (boris_at_[hidden])
Date: 2009-04-25 08:52:24
On Tue, 21 Apr 2009 20:15:11 +0200, Phil Endecott  
<spam_from_boost_dev_at_[hidden]> wrote:
> [...]First a general comment about how I would prefer that portable  
> system API wrappers are implemented.  No doubt other would have  
> different views.  Ideally, I'd like to see separate thin wrappers for  
> Windows and POSIX that just "C++-ify" those APIs.  Then on top of that  
> implement a portability layer.  My reason is this: I rarely if ever care  
> about Windows and I already know how the POSIX APIs work (i.e. what the  
> functions are called and what the semantics are).  So please don't hide  
> the bottom level thin wrappers that you must have as an implementation  
> detail.
I see. It reminds me a bit of the free-standing functions in  
Boost.Filesystem which I think simply call POSIX and Windows API  
functions? I'm not sure though if I can work on such a layer - I hardly  
have time to work on the upper layer. :-/
> Re the environment: I'm not enthusiastic that you have copied the  
> environment into your own data structure.  Why can't your environment  
> type just wrap getenv() and setenv()?   i.e.
Before I answer your questions I should note that I did not design  
Boost.Process. I went through the entire code last year to make sure that  
what we have works (fixing countless bugs and testing the library with  
numerous compilers and platforms). I try to answer your questions as far  
as I understand the rationale of the design.
> class environment {
>    struct env_var_proxy {
>      const char* varname;
>      env_var_proxy(const char* varname_): varname(varname_) {}
>      operator const char*() const { return getenv(varname); }
>      void operator=(const char* newval) { setenv(varname,newval,1); }
>    }
The type environment is also used to setup a new environment for a child  
process, eg.:
context ctx;
ctx.environment.insert(environment::value_type("PATH", "/newpath"));
launch(..., ctx);
> [...]This example code:
>
>    std::string exec = find_executable_in_path("notepad.exe");
>    std::vector<std::string> args = boost::assign::list_of("notepad.exe");
>    context ctx;
>    ctx.environment = self::get_environment();
>    launch(exec, args, ctx);
>
> Is actually more verbose than directly calling the POSIX functions:
>
>    int child_pid = fork();
>    if (child_pid == -1) throw "fork failed";
>    if (child_pid == 0) {
>      execlp("notepad.exe","notepad.exe",NULL);
>      _exit(1);
>    }
>
> Why don't you boil it down to:
>
>    launch_process("notepad.exe");
Currently the environment variables of the current process are not  
automatically inherited by a child process. I agree that it should be  
easier to launch a new process. But then environment variables should  
probably be inherited by default?
> You write:
>
>> it is very important to refer to the executable with an absolute path -  
>> on all platforms including POSIX systems
>
> Why do you say that?
It's a requirement of Boost.Process. It doesn't need to be an absolute  
path but can also be a relative path of course. What's not guaranteed  
though is that an executable is automatically found when only a filename  
is given. There is a function which searches for an executable and returns  
an absolute path. Would you like to see Boost.Process search for an  
executable automatically?
> It's not clear to me if your terminate() calls wait() or not.  Beware of  
> processes that ignore SIGCHLD.
Currently terminate() only calls kill().
>> 3) Currently Boost.Process is really only useful for creating child
>> processes. It's not possible for example to detect and iterate over  
>> other
>> processes on a system. I guess Boost.Process should be enhanced here.  
>> Then
>> one day the well-known utility 'ps' on POSIX systems could be  
>> implemented
>> in Boost C++. Any comments?
>
> What is the use case for this?
I asked myself the other way round: Why should a library for process  
management only support child processes? But I'd agree that accessing  
other processes has a lower priority.
> [...]
>> 8) There is a method wait() which makes it possible to wait for another
>> process to exit. Currently wait() is provided by the class child though.
>> Shouldn't it really be defined by the class process (so you can wait not
>> only for child processes to exit)?
>
> Are you certain that wait() can be used to monitor non-child processes?   
> I don't believe that it can.
Hm, on POSIX systems it doesn't work but on Windows it works. Another  
problem to think about.
Boris