www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Opening temporary files for std.process.spawnProcess input/output

reply "wobbles" <grogan.colin gmail.com> writes:
Hi,
Any reason why the following wont work?

void main(string[] args)
{
     auto pidIn = File.tmpfile();
     auto pidOut = File.tmpfile();
     auto pid = spawnProcess(["ls", "./"], pidIn, pidOut, 
std.stdio.stdout, null, Config.newEnv);

     if(wait(pid) == 0)
         writefln("%s", pidOut.readln());
}

The pidOut.readln() throws this exception:
object.Exception /usr/include/dmd/phobos/std/stdio.d(1377): 
Attempt to read from an unopened file.

I figured tmpfile() would be open for read/write by default?
Also, theres no way to pass in args to File.tmpfile() to make 
them read/write.

Any ideas?
Feb 25 2015
next sibling parent "Tobias Pankrath" <tobias pankrath.net> writes:
On Wednesday, 25 February 2015 at 13:56:06 UTC, wobbles wrote:
 Hi,
 Any reason why the following wont work?

 void main(string[] args)
 {
     auto pidIn = File.tmpfile();
     auto pidOut = File.tmpfile();
     auto pid = spawnProcess(["ls", "./"], pidIn, pidOut, 
 std.stdio.stdout, null, Config.newEnv);

     if(wait(pid) == 0)
         writefln("%s", pidOut.readln());
 }

 The pidOut.readln() throws this exception:
 object.Exception /usr/include/dmd/phobos/std/stdio.d(1377): 
 Attempt to read from an unopened file.

 I figured tmpfile() would be open for read/write by default?
 Also, theres no way to pass in args to File.tmpfile() to make 
 them read/write.

 Any ideas?
maybe only for writing: http://www.cplusplus.com/reference/cstdio/tmpfile/
Feb 25 2015
prev sibling parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 02/25/2015 05:56 AM, wobbles wrote:

 Hi,
 Any reason why the following wont work?

 void main(string[] args)
 {
      auto pidIn = File.tmpfile();
      auto pidOut = File.tmpfile();
      auto pid = spawnProcess(["ls", "./"], pidIn, pidOut,
 std.stdio.stdout, null, Config.newEnv);

      if(wait(pid) == 0)
          writefln("%s", pidOut.readln());
 }

 The pidOut.readln() throws this exception:
 object.Exception /usr/include/dmd/phobos/std/stdio.d(1377): Attempt to
 read from an unopened file.

 I figured tmpfile() would be open for read/write by default?
 Also, theres no way to pass in args to File.tmpfile() to make them
 read/write.

 Any ideas?
It looks like the file is closed when spawnProcess is finished. I don't know whether it is done by spawnProcess explicitly or whether it is a behavior for temporary files. How about using a pipe? The following works: import std.stdio; import std.process; void main(string[] args) { auto pidIn = File.tmpfile(); auto pidOut = pipe(); auto pid = spawnProcess(["ls", "./" ], pidIn, pidOut.writeEnd, std.stdio.stdout, null, Config.newEnv); if(wait(pid) == 0) writeln(pidOut.readEnd.byLine); } Ali
Feb 25 2015
next sibling parent "wobbles" <grogan.colin gmail.com> writes:
On Wednesday, 25 February 2015 at 19:09:16 UTC, Ali Çehreli wrote:
 On 02/25/2015 05:56 AM, wobbles wrote:

 Hi,
 Any reason why the following wont work?

 void main(string[] args)
 {
      auto pidIn = File.tmpfile();
      auto pidOut = File.tmpfile();
      auto pid = spawnProcess(["ls", "./"], pidIn, pidOut,
 std.stdio.stdout, null, Config.newEnv);

      if(wait(pid) == 0)
          writefln("%s", pidOut.readln());
 }

 The pidOut.readln() throws this exception:
 object.Exception /usr/include/dmd/phobos/std/stdio.d(1377):
Attempt to
 read from an unopened file.

 I figured tmpfile() would be open for read/write by default?
 Also, theres no way to pass in args to File.tmpfile() to make
them
 read/write.

 Any ideas?
It looks like the file is closed when spawnProcess is finished. I don't know whether it is done by spawnProcess explicitly or whether it is a behavior for temporary files. How about using a pipe? The following works: import std.stdio; import std.process; void main(string[] args) { auto pidIn = File.tmpfile(); auto pidOut = pipe(); auto pid = spawnProcess(["ls", "./" ], pidIn, pidOut.writeEnd, std.stdio.stdout, null, Config.newEnv); if(wait(pid) == 0) writeln(pidOut.readEnd.byLine); } Ali
This works, Thanks folks!
Feb 26 2015
prev sibling parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 2/25/15 2:09 PM, Ali Çehreli wrote:

 It looks like the file is closed when spawnProcess is finished. I don't
 know whether it is done by spawnProcess explicitly or whether it is a
 behavior for temporary files.
I know the problem is solved, but I wanted to chime in with some explanation here: Yes, it's closed on purpose. Typically, when you open a file descriptor in order to have the child use it for stdin/stdout/stderr, you want to close the handle on the parent, since the parent isn't using it. Even with pipes, there are 2 ends. The child uses one and closes the other, and the parent uses one and closes the other. There is a way to disable this behavior, use Config.retainStdout. http://dlang.org/library/std/process/config.html The only time these aren't closed by default is if the default handles are used (you don't want to close e.g. stdout in the parent if you use it in the child). -Steve
Feb 26 2015