Download Reference Manual
The Developer's Library for D
About Wiki Forums Source Search Contact

Problem with tango.sys.Process.redirect

Moderators: kris

Posted: 02/04/10 12:10:23

I have two programs, callee.d

module callee;

import tango.io.Stdout;

int main(char[][] args)
{
    Stderr("This is callee's stderr").newline;
    Stdout("This is callee's stdout").newline;
    
    foreach(i, arg; args)
    {
        if(i < 1)
            continue;
        
        Stdout.formatln("  arg {}: {}", i, arg);
    }
    return 0;
}

and caller.d

module caller;

import tango.io.Stdout;
import tango.sys.Process;

void main(char[][] args)
{
    char[] command = "callee.exe hello";
    bool redirect = false;
    
    foreach (arg; args[1..$])
    {
        command ~= " " ~ arg.dup;
        if(arg == "-r" || arg == "-R")
            redirect = true;
    }
    Process p = new Process(true, command);
    
    // Is this correct?
    if (redirect)
        p.redirect(Redirect.ErrorToOutput);
    
    p.execute();
    Stdout.copy(p.stdout).flush;
    Process.Result result = p.wait();

    Stdout.formatln("Executed '{}'", command);
    Stdout.formatln("Result   '{}' - Status {}", result, result.status);
}

When I now test these programs I get

E:\source\D\tango_5346>callee
This is callee's stderr
This is callee's stdout

E:\source\D\tango_5346>caller world
This is callee's stdout
  arg 1: hello
  arg 2: world
Executed 'callee.exe hello world'
Result   'Process exited normally with return code 0' - Status 0

E:\source\D\tango_5346>caller world -r
object.Exception: Access Violation - Read at address 0x0

E:\source\D\tango_5346>This is callee's stderr
This is callee's stdout
  arg 1: hello
  arg 2: world
  arg 3: -r

My problem is: p.redirect(Redirect.ErrorToOutput?) seems to work, callee's stderr is copied to caller's stdout - this is what I expected. But I also get an Access Violation. Am I using Process.redirect in the wrong way or is this a bug?

(tango-r5346 / Win XP Pro / dmd 1.055)

Author Message

Posted: 02/08/10 15:49:23

Yes, I was using it the wrong way!

When I changed line 21 of caller.d from

        p.redirect(Redirect.ErrorToOutput);

to

        p.redirect(Redirect.ErrorToOutput | Redirect.Output | Redirect.Input);

it worked!

The documentation http://www.dsource.org/projects/tango/docs/stable/tango.sys.Process.html says:

enum Redirect
    Redirect flags for processes. Defined outside process class to cut down on verbosity.
...
    ErrorToOutput
        Send stderr to stdout's handle. Note that the stderr PipeConduit will be null.

So the Access Violation seems to be caused by stderr PipeConduit? being null.

Posted: 02/08/10 20:37:59

Could you please create a ticket on this? And thanks for looking into it!

Posted: 02/09/10 14:52:19

You asked for it, here it is :-) #1849