Steve Schveighoffer wrote:
This looks great!

Thanks!


Where would the Windows gui flag fit in?

Um...  I kinda forgot about that one. :)  What would you say is the most
common setting, and to which degree?

If we can assume that the user almost always wants it to be off, say, we
can just add a bool argument to the end of spawnProcess() that defaults
to false.

Since using a GUI is in most cases a design choice, another option is to make it a template parameter. But that will require either of bugs 1820 or 2972 to be fixed, otherwise every spawnProcess() call where you want to use its default value will looke like

   spawnProcess!()(...);


Also, note that one can redirect both stdout and stderr to the same File, which 
means if you are closing both, you should only call close once on those files 
(I'm not sure how bad it is, but it probably will result in an ignored error 
from the OS).

Which close() operations are you referring to?

If it's the core.sys.posix.unistd.close() in the child process, I'm pretty sure nothing bad happens, except close() setting errno to EBADF and returning -1. It probably good form to add the check, though.

If it's the std.stdio.File.close() in the parent process, then Andrei has designed it to be a no-op when the file is already closed.


Another thing, I liked how the pid struct used to contain the pipes when I 
wanted to control the std handles, and how the spawnProcess function handled 
the pipe creation for me.  I wonder if it's possible to pass in a default 
argument for the handles, or have a separate function that does the pipe 
creation, and store the right ends of the pipe in the returned struct.

For example, if I want control over all three handles, I have to do:

auto lsstdin = Pipe.create();
auto lsstdout = Pipe.create();
auto lsstderr = Pipe.create();

auto lspid = spawnProcess("ls -l", lsstdin.readEnd, lsstdout.writeEnd, 
lsstderr.writeEnd);

If I do that a lot, I have a lot of pipes littering my local variables, and the 
code is very verbose.

But how often do you do that? I mean, how often do you start several programs in a row, capturing all their input output streams, all inside one scope?

I'm asking out of curiosity. I'm mostly a scientific programmer, not an application programmer, so maybe I'm not thinking big enough. The reason I started working on this stuff was that I've been writing a Linux session manager -- just a lightweight one that takes care of starting other applications on login and restarting them if they die. I can hardly imagine a program that needs to spawn more processes than that, but even that one contained just a single spawn command.

I think the current approach fits with the "systems programming language" aspect of D, and it will feel familiar to C programmers. Only it will be a lot less bug-prone than the corresponding C code, because you no longer have to worry about manually closing the pipes, duplicating the right file descriptors, etc.


I think we can build this on top of your function, into a struct/class that 
handles this stuff for you.  Or we could make the spawnProcess arguments 
variadic and put the created pipe handles back in the pid struct.

That's a possibility.  Something like this might do the trick:

  struct SlaveProcess
  {
      Pid pid;
      File stdin, stdout, stderr;
      this(string command, Redirect redirectFlags = Redirect.all);
      void spawn();
  }

I'm still not entirely convinced it is necessary, though.  :)

-Lars



----- Original Message ----
From: Lars Tandle Kyllingstad <[email protected]>
To: Phobos mailing list <[email protected]>
Sent: Thu, March 11, 2010 6:33:29 AM
Subject: [phobos] Major improvements to std.process

I have just redone the interface of my std.process proposal, and I am very pleased with the result.

Calling "ls -l" is now as simple as writing

   spawnProcess("ls -l");

while "ls -l | grep foobar > filesNamedFoobar.txt" isn't that big of a deal either:

    auto pipe = Pipe.create();
    auto file = File("filesNamedFoobar.txt", "w");

    auto lsPid = spawnProcess("ls -l", stdin, pipe.writeEnd);
    scope(exit) lsPid.wait();

    auto grPid = spawnProcess("grep foobar", pipe.readEnd, file);
    scope(exit) grPid.wait();

The documentation is also a lot better now (though the spawnProcess() signature looks horrible, but that's a DDoc issue). As always, please check out

    http://github.com/kyllingstad/ltk/blob/master/ltk/process.d
    http://kyllingen.net/code/ltk/doc/process.html

and give me your opinions.

-Lars


-- Lars Tandle Kyllingstad
@: [email protected]
#: 40233221
w: http://www.kyllingen.net
_______________________________________________
phobos mailing list
[email protected]
http://lists.puremagic.com/mailman/listinfo/phobos



_______________________________________________
phobos mailing list
[email protected]
http://lists.puremagic.com/mailman/listinfo/phobos


--
Lars Tandle Kyllingstad
@: [email protected]
#: 40233221
w: http://www.kyllingen.net

_______________________________________________
phobos mailing list
[email protected]
http://lists.puremagic.com/mailman/listinfo/phobos

Reply via email to