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

tango.sys.Process: How to interact with a running process?

Moderators: larsivi kris

Posted: 07/14/08 13:37:52

Hi, how do I interact with a *running* process? It seems to me that Process.stdout is only available after the process has gone, which is not exactly useful for what I want to achieve. What am I missing?

Ciao Tom

Ciao

Tom

Author Message

Posted: 07/14/08 14:46:40

This works fine for me on Windows. Maybe the process doesn't fill up its stdout buffer, but just flushes it at exit.

Posted: 07/14/08 15:09:05

If the process you are starting from Tango is another Tango based process, Tango has this feature where if it detects stdout is not a terminal, it does not flush on newline(). You can override this behavior by doing

Stdout.flush = true;

In the main function for the process you start. This will flush every time newline is sent to Stdout.

Not sure if this is the issue, but I've run into it before, thought I'd save you some headache :)

Posted: 07/14/08 17:25:49

Thanks for the quick replies. Yes, I also suspect the flushing to be a reason. The child looks like this:

void
DebugMsg(const char *fmt,...){
  char buf[8192];
  va_list args;
  va_start(args,fmt);

  vsnprintf(buf,sizeof(buf),fmt,args);
  OutputDebugStringA(buf);
  
  va_end(args);
}
int
main(int argc, char **argv){
  char buf[1024];
  int i;
  fputs("Hello\n", stdout);fflush(stdout);
  while(1){
    fgets(buf,1024,stdin);
    for(i=0; i<1000; i++){
      fputs(buf,stdout);
      fflush(stdout);
    }
    DebugMsg("echo: Got %d bytes: {%s}\n",strlen(buf),buf);
    if ( buf[0] == 'q')
      break;
  }
  DebugMsg("Exiting");
  return 0;
}

Compiled with gcc -mno-cygwin, i.e. MinGW under XP. I can see the DebugMsg? with Dbgview, so the flow to the child works. The parent looks like this:

int
main(String[] args){
  char[] xxx;
  int i;
  Process p = new Process(ddbgexe);

  p.execute();
  Stdout.formatln("Process started");
  Stdout.flush();
  p.stdin.write("Hallo\n");
  p.stdin.flush();
  Thread.sleep(0.5);
  p.stdout.read( xxx );  
  Stdout.formatln("{}\n", xxx);
  p.stdin.write("quit\n");
  p.stdin.flush();
  /*
  p.stdout.read( xxx );  
  Stdout.formatln("Output from process '{}' (pid {})\n----------", p.programName, p.pid);
  Stdout.formatln("{}\n", xxx);
  for(i=0; i<100; i++){
    p.stdout.read( xxx );  
    Stdout.formatln("{}\n", xxx);
    Thread.sleep(0.1);
  }
  */
  /*
  Stdout.stream.copy(p.stdout);
  Stdout("----------").newline;
  Stdout.flush();

  Stdout.stream.copy(p.stdout);
  */
  return 0;
}

dmd.1.028, tango-0.99.6, WinXP. I am doing something fundamentally wrong, but what?

Ciao Tom

Ciao

Tom

Posted: 07/15/08 16:06:42

Here is your problem:

char[] xxx;
...
p.stdout.read( xxx );

This is calling DeviceConduit.read, which uses the length of its argument to decide how much to read. Since xxx.length is 0, it's attempting to read 0 bytes, which of course, returns immediately :)

Try this:

char[] xxx = new char[256];

-Steve

Posted: 07/15/08 17:07:32

Thanks, that did the trick. I don't remember where I got the idea that it reads whatever is available...

Ciao

Tom