[Interest] QProcess: child read from stdin - no data received?

Till Oliver Knoll till.oliver.knoll at gmail.com
Sun May 13 18:36:02 CEST 2012


Hello,

this seems to be an ever recurring topic: How does one get notified in a 
*child* process (started via QProcess) once there is data to be read on 
stdin (in a platform-independent matter - but for now mostly OS X)?

Setting up everything on the parent process seems to be 
straight-forward. In the child process however it doesn't seem that 
there is an easy-to-use Qt API for that, so my first simple approach was 
to use a QFile and wait until there is something to read:

   // In child process
   QFile file;

   file.open(::stdin, QFile::ReadOnly | QFile::Unbuffered); // try to 
open stdin
   // Start my own message consumation loop
   while (true) {
     // -1: should actually wait forever (until there is data)
     if (file.waitForReadyRead(-1)) {
       ... // read and consume data
     }
   }

Problem: waitForReadyRead returns immediatelly with false (on OS X 
10.7), so my process consumes 99% CPU, but *never* gets anything to 
read. In the parent I use e.g.

   QProcess process = ...;

   int msg = AirIPC::Rq_FindAirPlayServers;
   process.write("Hello!\n");

According to the Qt docs that should write to the child's stdin.


Doing quite some research I mostly found posts like

   http://lists.qt.nokia.com/pipermail/qt-interest/2009-January/001245.html

which indicate that this simply doesn't work with QFile on stdin 
("Thanks for all the help, but I'm going with sockets, this stuff is 
just not working.").

The next obvious approach would be to use QSocketNotifier, but according 
to this:

 
http://stackoverflow.com/questions/7457990/child-process-stdin-doesnt-get-data-sent-by-parent-process

that would not work on Windows (where stdin is not an "ordinary" file 
descriptor, and for sure not one which would work as "socket").


So what's left? Abandon IPC using stdin/stdout altogether and using 
QLocalSocket/Server? According to Qt docs: "On Windows this is a named 
pipe and on Unix this is a local domain socket."


However the reason why I want to split my application into a parent and 
child process is that the parent process should have no network 
"entitlement" (think "Sandboxing on Mac OS X" - the networking should be 
done by the child process alone, which on its turn has no filesystem 
entitlements). So I am a bit concerned that the "no network" entitlement 
for the parent process would prevent it from accessing even a local 
socket? (anyone tried this with success?).


But then again, it is hard to believe that this whole stdin/out IPC with 
Qt apps hasn't been successfully implemented elsewhere. Off course I 
could fall back to platform APIs and plain vanilla C API calls (or using 
"polling threads on Windows", as suggested on Stack Overflow thread 
above), wrapping it into my own platform dependent classes etc. - but 
can it be that hard?


Any ideas?
   Thanks, Oliver



More information about the Interest mailing list