Author Topic: redirect process output  (Read 3759 times)

Offline mariocup

  • Developer
  • Lives here!
  • *****
  • Posts: 587
redirect process output
« on: May 07, 2007, 03:35:05 pm »
Hi,
I'm trying to start external processes from my plugin and to access the standard output of these processes.
First I tried to use wxProcess with Redirect() and reading the process object's output stream in OnIdle. Unfortunately, the CanRead method of the wxInputStream object always returned false.

The second try was using PipedProcess. I registered an event handler for cbEVT_PIPEDPROCESS_STDOUT, but the handler never got called although the process wrote to stdout.


EVT_PIPEDPROCESS_STDOUT (HtcToolchainPlugin::m_IdProcInsight, HtcToolchainPlugin::OnInsightOutput)


m_pProcInsight = new PipedProcess ((void**)&m_pProcInsight,this,m_IdProcInsight,true);
m_PidProcInsight = wxExecute (cmdLine, wxEXEC_ASYNC,m_pProcInsight);


I'm working with SVN 3926 and wxWidgets-2.8.3
Does anyone has suggestions what might be missing in the initialization/execution of the piped process?

Btw.: Event handlers for termination events of the processes get called.

Best Regards

Offline mandrav

  • Project Leader
  • Administrator
  • Lives here!
  • *****
  • Posts: 4291
    • Code::Blocks IDE
Re: redirect process output
« Reply #1 on: May 07, 2007, 03:39:25 pm »
You need to add a polling timer or use OnIdle(). Check the compiler or debugger plugins' sources for ideas.
Be patient!
This bug will be fixed soon...

Offline mariocup

  • Developer
  • Lives here!
  • *****
  • Posts: 587
Re: redirect process output
« Reply #2 on: May 09, 2007, 04:00:26 pm »
Two questions/remarks:

First point is, I do not understand, why I have to poll in my own OnIdle handler, since PipedProcess calls HasInput in its own OnIdle.

Second, I found out, that I get data from a launched process every 4 kB of data are written by that process; befor the 4kB-buffer is full, IsInputAvailable of wxProcess returns false. Gdb is an exception, since gdb uses unbuffered I/O. If I create a wxTextInputStream of the processes input stream, I can read data less than 4kB, but with a blocking Read function, if no data is available.
My question is: is there a possibility to read byte-by-byte non-blocking from an input stream, or do I have to use an extra thread for reading from the stream?

Bye,

Mario

Offline mandrav

  • Project Leader
  • Administrator
  • Lives here!
  • *****
  • Posts: 4291
    • Code::Blocks IDE
Re: redirect process output
« Reply #3 on: May 09, 2007, 05:57:03 pm »
Two questions/remarks:

First point is, I do not understand, why I have to poll in my own OnIdle handler, since PipedProcess calls HasInput in its own OnIdle.

Second, I found out, that I get data from a launched process every 4 kB of data are written by that process; befor the 4kB-buffer is full, IsInputAvailable of wxProcess returns false. Gdb is an exception, since gdb uses unbuffered I/O. If I create a wxTextInputStream of the processes input stream, I can read data less than 4kB, but with a blocking Read function, if no data is available.
My question is: is there a possibility to read byte-by-byte non-blocking from an input stream, or do I have to use an extra thread for reading from the stream?

Bye,

Mario


I can't help you more if you choose to ignore my previous post. I already told you what you need to do...
Be patient!
This bug will be fixed soon...

Offline dmoore

  • Developer
  • Lives here!
  • *****
  • Posts: 1576
Re: redirect process output
« Reply #4 on: May 09, 2007, 07:03:03 pm »
Two questions/remarks:

First point is, I do not understand, why I have to poll in my own OnIdle handler, since PipedProcess calls HasInput in its own OnIdle.

I wondered the same thing several months ago when I was prototyping some plugins to run/debug interpreted shell scripts. I'm pretty sure the PipedProcess polling isn't actually implemented (either correctly or at all). In the end I just polled with a simple timer, but polling in an onidle handler will work too.

Quote
Second, I found out, that I get data from a launched process every 4 kB of data are written by that process; befor the 4kB-buffer is full, IsInputAvailable of wxProcess returns false. Gdb is an exception, since gdb uses unbuffered I/O. If I create a wxTextInputStream of the processes input stream, I can read data less than 4kB, but with a blocking Read function, if no data is available.
My question is: is there a possibility to read byte-by-byte non-blocking from an input stream, or do I have to use an extra thread for reading from the stream?

AFAIK, the buffering problem has nothing to do with wxWidgets or Threading issues. The root cause is the operating system (windows, specifically). The output stream the OS offers for piping is simply empty until the buffer fills. AFAIK in windows, there is no way to force a given program to produce unbuffered output, although programs can choose to produce unbuffered output (for example the python interpreter offers the -u switch for running scripts in unbuffered mode)