The new std.process is ready for review

Lars T. Kyllingstad public at kyllingen.net
Sun Feb 24 06:41:16 PST 2013


I apologise if this gets posted twice, but my newsgroup client is 
acting up.

On Saturday, 23 February 2013 at 16:44:30 UTC, H. S. Teoh wrote:
> I just looked over the docs. Looks very good!

Thanks! :)

> Just a few minor comments:
>
> - wait():
>    - Some code examples would be nice.

The wait() documentation says "Examples: See the spawnProcess 
documentation", and provides a link.  I didn't see any point in 
duplicating the examples there just for the sake of it.


>    - 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?

Steve already answered this, but yes, the number returned by 
wait() has already been processed by these macros.  wait() 
therefore has the same result on all POSIX systems.


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

I will write a separate post about this shortly.


> - execute() and shell(): I'm a bit concerned about returning the
>   *entire* output of a process as a string. What if the output 
> generates
>   too much output to store in a string? Would it be better to 
> return a
>   range instead (either a range of chars or range of lines 
> maybe)? Or is
>   this what pipeProcess was intended for? In any case, would it 
> make
>   sense to specify some kind of upper limit to the size of the 
> output so
>   that the program won't be vulnerable to bad subprocess 
> behaviour
>   (generate infinite output, etc.)?

Again, Steve answered this, but let me clarify:  There are three 
layers of functionality in this module.

1. spawnProcess() gives you detailed control over process 
creation, in a cross-platform manner.

2. pipeProcess()/pipeShell() are convenience functions that take 
care of creating pipes to the child process for you, as this is a 
common use case.  Use this if you need detailed control over what 
goes in and out of the process.

3. execute()/shell() are a second layer of convenience, if you 
just want a simple way to execute a process and retrieve its 
output.  If there is any chance of the process producing vast 
amounts of output, you really should use pipeProcess() or even 
spawnProcess().

Of course, it is a simple matter to add an optional maxOutputSize 
parameter to execute() and an "overflow" flag to the returned 
tuple, but I think it adds more API clutter than it is worth.  
I'd love to hear others' opinions about it, though.


> - ProcessException: are there any specific methods to help user 
> code
>   extract information about the error? Or is the user expected 
> to check
>   errno himself (on Posix; or whatever it is on Windows)?

Well, no.  The thing is, ProcessException may be associated with 
an errno code, with a Windows GetLastError() code, or it may 
simply be a pure "D error" with no relation at all to the 
underlying C APIs.

Personally, I believe that the distinction between 
ProcessException (for process management errors) and 
StdioException (for I/O errors, mostly related to pipes) provides 
enough granularity for most use cases.  I believe it's the best 
we can do in a cross-platform manner without inventing our own 
error codes and mapping them to errno/GetLastError() codes.  If 
anyone needs the underlying OS error code, they can still 
retrieve them using the system-specific APIs.

Again, I am of course open for discussion about this.

Lars


More information about the Digitalmars-d mailing list