[Qt-interest] Coordinating stderr between processes in a pipe train

Jeffrey Brendecke jwbrendecke at icanetix.com
Tue Jul 14 13:42:24 CEST 2009


This is a problem that has been vexing me for a while.

I am developing a library of console applications that process input data in a 
series using a traditional filter approach. The following is a text 
application I have been using to make sure the plumbling works:

echo xxxx | xq.exe 0 ERROR | xq.exe 0 xx | xq.exe 0 cc | xq.exe 0 dd >NUL:

Here is the code:

#include <QString>
#include <QTextStream>

#include <cstdlib>

int
main( int argc, char** argv )
{
  int exitCode( 99 );
  QString val;

  if ( 3 != argc ) return exitCode;

  QTextStream in( stdin );
  QTextStream out( stdout );
  QTextStream err( stderr );

  exitCode = std::atoi( argv[1] );
  in >> val;

  if ( 0 == exitCode )
  {
    out << qPrintable(val) << argv[2] << endl;
  }
  err << argv[2] << " " << exitCode << endl;

  return exitCode;
}


I have no problems I can tell with processing stdout. However working with 
stderr is proving unreliable as it sometimes gets garbled when put together 
on the console.

Given the above commandline, sometimes everything looks OK (the order is not 
important for my purposes):

xx 0
cc 0
ERROR 0
dd 0

Other times, it gets garbled (it can get much worse than this):

cxc 0
Ex 0
RROR 0
dd 0

In an outer script, I am capturing stderr and processing from the pipe train 
based on the status of the output lines. The test app was made to see why 
sometimes lines, for example, begging with "ERROR:" were not being processed. 
I have seen the problem both on Linux under bash and on Windows under 
cmd.exe.

Note that this relates to set of long-running applications that work together 
in such a manner, so capturing all of the stderr from each process in 
sequence and then outputing it is not a viable option.

Also note that the underlying reason for analyzing the stderr for errors, 
other than making a nice report, is to tell if the pipe train failed. Other 
than newer versions of bash (with its $PIPESTATUS[] variable), I have found 
no way to do this reliably so that a decision can be made in the next line of 
script following the pipe train to proceed or not (pseudocode):

run pipe train
if pipe train succeeds:
  do a()
else:
  do b()
 
I need to have this work on Windows (for now) with the option of porting to 
Linux later.

Is there something Qt can provide to simplify working with this? This seems 
like such a rudimentary problem that basically has been around the 70's.

Thank you for your assistance.



More information about the Qt-interest-old mailing list