I am trying to install a RPM using QProcess(/bin/rpm). This QProcess is running in a concurrent thread which was started by another QThread.
QThread retThread = new CMyThread(this);
connect(retThread, SIGNAL(finished()), retThread, SLOT(deleteLater()));
retThread->start();
For some reason the QProcess keeps on running and never exits. When I get the pid of the QProcess and check using the ps command, I dont' see any rpm command that is being executed. The standard out and standard error both are merged on to a single channel and logged on to a file.
The log indicates that the rpm command has finished the process of the installation.
The same behavior is not seen when I run the rpm installation using the QProcess on the main thread. Is this anything related to the event loop. If so how to check if the event loop exists . As per to my knowledge a thread should automatically create the event loop from QT 4.4 and above. I am using QT 4.8
http://qt-project.org/wiki/Threads_Events_QObjects
I feel like the event loop exists, since I am getting other thread queued signals in this thread.
QString ORIGINAL_LOG_FILE = "/var/Component.log";
int PROC_WAIT_TIME= 90000;
QSharedPointer<QProcess> process(new QProcess);
QString program = "/bin/rpm";
QStringList compArgs;
compArgs << "-Uvh"<<"--nodeps"<<"some.rpm";
QStringList configEnvironmentVars = process->systemEnvironment();
process->setEnvironment(configEnvironmentVars);
process->setWorkingDirectory("/tmp/something");
connect(process.data() , SIGNAL(finished(int,QProcess::ExitStatus)),this,SLOT(slot_finished(int,QProcess::ExitStatus)) );
// process->setWorkingDirectory();
process->setProcessChannelMode(QProcess::MergedChannels);
process->setStandardOutputFile(ORIGINAL_LOG_FILE, QIODevice::ReadWrite | QIODevice::Append | QIODevice::Text);
process->start(program, compArgs);
if (process->waitForStarted())
{
LOGINFO(m_nodeLogFile,QString("Waiting for the process to finish"));
do
{
LOGINFO(m_nodeLogFile, QString("pid = %1").arg((uint)process->pid()));
LOGINFO(m_nodeLogFile , QString("Error = %1").arg(process->error()));
LOGINFO(m_nodeLogFile,QString("Envirnoment variables = %1").arg(configEnvironmentVars.join("\n")));
LOGINFO(m_nodeLogFile,QString("Working directory = %1").arg(process->workingDirectory()));
LOGINFO(m_nodeLogFile,QString("State = %1").arg(process->state()));
}while(!process->waitForFinished(100));
I even tried to connect to a finish signal.
The reason is due to the open source HTTP server mongoose that we were using. In the open source code the SIGCHLD signal was disabled for the whole application.
void signal(SIGCHLD , SIG_IGN);
This used to cause the whole application not to receive the child exit signal. QProcess needs to handle this signal to determine if the child process has exited.