[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