On Saturday, 23 February 2013 at 22:48:04 UTC, H. S. Teoh wrote:
On Sat, Feb 23, 2013 at 03:15:26PM -0500, Steven Schveighoffer wrote:
On Sat, 23 Feb 2013 11:42:26 -0500, H. S. Teoh
<[email protected]> wrote:

>- wait():
>   - Some code examples would be nice.
>
>   - For the POSIX-specific version, I thought the Posix
>     standard specifies that the actual return code /
>     signal number should be extracted by means of
>     system-specific macros (in C anyway)?
>     Wouldn't it be better to encapsulate this in a POD
>     struct or something instead of exposing the
>     implementation-specific values to the user?

We handle the extraction as an implementation detail, the result should be cross-platform (at least on signal-using
platforms). I don't know what a POD struct would get you,
maybe you could elaborate what you mean?

Oh, I thought the return value was just straight from the syscall, which requires WIFEXITED, WEXITSTATUS, WCOREDUMP,
etc., to interpret. If it has already been suitably interpreted
in std.process, then I guess it's OK.

Otherwise, I was thinking of encapsulating these macros in
some kind of POD struct, that provides methods like
.ifExited, .exitStatus, .coreDump, etc. so that the user
code doesn't have to directly play with the exact values returned by the specific OS.

>   - How do I wait for *any* child process to terminate, not
>     just a specific Pid?

I don't think we have a method to do that. It would be complex, especially if posix wait() returned a pid that we
are not handling!

I suppose what you could do is call posix wait (I have a feeling we may need to change our global wait function, or
eliminate it), and then map the result back to a Pid you
are tracking.

You have any ideas how this could be implemented? I'd prefer not to keep a global cache of child process objects...

Btw on windows a simple array with the hProcesses is all you
need to do this, the code below uses AA for reverse lookup,
really simple stuff;

https://github.com/Wallbraker/Unicorn/blob/master/src/uni/util/cmd.d#L354

The code was written before before I know of the new
std.process, but it solved exactly this problem.


Why not? On Posix at least, you get SIGCHLD, etc., for all child processes anyway, so a global cache doesn't seem to be out-of-place.

But you do have a point about pids that we aren't managing, e.g. if the user code is doing some fork()s on its own. But
the way I see it, std.process is supposed to alleviate the
need to do such things directly, so in my mind, if everything
is going through std.process anyway, might as well just manage
all child processes there. OTOH, this may cause problems if the
D program links in C/C++ libraries that manage their own chil
processes.

But as you state above, it only works for a single CmdGroup on
posix and will probably interact badly with code using wait.

I never got so far because the code works for my limited case,
but supposedly process groups might help out, but the seem to
interfere with signals. More reading is required.

http://linux.die.net/man/7/credentials


Still, it would be nice to have some way of waiting for a set of child Pids, not just a single one. It would be a pain if
user code had to manually manage child processes all the time
when there's more than one of them running at a time.

Hmm. The more I think about it, the more it makes sense to just have std.process manage all child process related stuff. It's
too painful to deal with multiple child processes otherwise.
Maybe provide an opt-out in case you need to link in some
C/C++ libraries that need their own child process handling, but
the default, IMO, should be to manage everything through
std.process.

This needs to be opt-in, because this stuff should not break
libraries using fork/wait by default.

Cheers, Jakob.

Reply via email to