Starting interactive processes with QProcess

Posted by Bradley T. Hughes on March 16, 2006 · 3 comments

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? :)

QShare(this)

No related posts.


3 comments

1 Andreas March 16, 2006 at 2:25 am
 

Wait; I admit to writing the class, but the dup-trick was your idea ;-) .

2 Eduardo Habkost March 19, 2006 at 1:46 pm
 

Wouldn’t process->setCommunication(0) do the trick?

3 brad March 20, 2006 at 1:07 am
 

> Wouldn’t process->setCommunication(0) do the trick?

Yeh, it should when using Qt 3′s QProcess (note that I’m referring to Qt 4′s QProcess in my posting). :)

Comments on this entry are closed.

Previous post:

Next post: