Subnavigation

Starting interactive processes with QProcess

I've been playing with QProcess quite a bit lately, which is a wonderful class. However, I noticed that I cannot start an interactive process with it (i.e. a process that gets stdin from the terminal). This is because QProcess redirects stdin for all processes it starts back to the parent process, so that the programmer can send data to the process using write(). Thing is, I don't want this. So, after talking a bit with Andreas (who wrote QProcess), we came up with the following trick:

class InteractiveProcess : public QProcess
{
static int stdinClone;
public:
InteractiveProcess(QObject *parent = 0)
: QProcess(parent)
{
if (stdinClone == -1)
stdinClone = ::dup(fileno(stdin));
}
protected:
void setupChildProcess()
{
::dup2(stdinClone, fileno(stdin));
}
};

int InteractiveProcess::stdinClone = -1;

Basically, we clone stdin in the parent process, and in the child (which calls our QProcess::setupChidProcess() reimplementation), we redirect stdin to the clone created by the parent.

Pretty neat, isn't it? :)


Blog Topics:

Comments