summaryrefslogtreecommitdiff
path: root/core/launcher/qprocess_unix.cpp
Side-by-side diff
Diffstat (limited to 'core/launcher/qprocess_unix.cpp') (more/less context) (show whitespace changes)
-rw-r--r--core/launcher/qprocess_unix.cpp93
1 files changed, 46 insertions, 47 deletions
diff --git a/core/launcher/qprocess_unix.cpp b/core/launcher/qprocess_unix.cpp
index 19a8c93..d62e4e6 100644
--- a/core/launcher/qprocess_unix.cpp
+++ b/core/launcher/qprocess_unix.cpp
@@ -13,52 +13,51 @@
**
** See http://www.trolltech.com/gpl/ for GPL licensing information.
**
** Contact info@trolltech.com if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/
-//#include "qplatformdefs.h"
-
// Solaris redefines connect -> __xnet_connect with _XOPEN_SOURCE_EXTENDED.
#if defined(connect)
#undef connect
#endif
#include "qprocess.h"
-#ifndef QT_NO_PROCESS
+/* OPIE */
+#include <opie2/odebug.h>
+using namespace Opie::Core;
-#include "qapplication.h"
-#include "qqueue.h"
-#include "qlist.h"
-#include "qsocketnotifier.h"
-#include "qtimer.h"
-#include "qregexp.h"
+/* QT */
+#ifndef QT_NO_PROCESS
+#include <qapplication.h>
+#include <qqueue.h>
+#include <qlist.h>
+#include <qsocketnotifier.h>
+#include <qtimer.h>
+#include <qregexp.h>
#include "qcleanuphandler_p.h"
+/* STD */
#include <stdlib.h>
-
-// ### FOR Qt 2.3 compat
#include <unistd.h>
#include <signal.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <sys/fcntl.h>
-
+#include <sys/resource.h>
#include <errno.h>
-
#ifdef Q_OS_MACX
#include <sys/time.h>
#endif
-#include <sys/resource.h>
#ifdef __MIPSEL__
# ifndef SOCK_DGRAM
# define SOCK_DGRAM 1
# endif
# ifndef SOCK_STREAM
# define SOCK_STREAM 2
# endif
@@ -127,26 +126,26 @@ public:
directly to a running child process.
*/
class QProc
{
public:
QProc( pid_t p, QProcess *proc=0 ) : pid(p), process(proc)
{
#if defined(QT_QPROCESS_DEBUG)
- qDebug( "QProc: Constructor for pid %d and QProcess %p", pid, process );
+ odebug << "QProc: Constructor for pid " << pid << " and QProcess " << process << "" << oendl;
#endif
socketStdin = 0;
socketStdout = 0;
socketStderr = 0;
}
~QProc()
{
#if defined(QT_QPROCESS_DEBUG)
- qDebug( "QProc: Destructor for pid %d and QProcess %p", pid, process );
+ odebug << "QProc: Destructor for pid " << pid << " and QProcess " << process << "" << oendl;
#endif
if ( process != 0 ) {
if ( process->d->notifierStdin )
process->d->notifierStdin->setEnabled( FALSE );
if ( process->d->notifierStdout )
process->d->notifierStdout->setEnabled( FALSE );
if ( process->d->notifierStderr )
process->d->notifierStderr->setEnabled( FALSE );
@@ -208,94 +207,94 @@ QProcessManager::QProcessManager()
// The SIGCHLD handler writes to a socket to tell the manager that
// something happened. This is done to get the processing in sync with the
// event reporting.
if ( ::socketpair( AF_UNIX, SOCK_STREAM, 0, sigchldFd ) ) {
sigchldFd[0] = 0;
sigchldFd[1] = 0;
} else {
#if defined(QT_QPROCESS_DEBUG)
- qDebug( "QProcessManager: install socket notifier (%d)", sigchldFd[1] );
+ odebug << "QProcessManager: install socket notifier (" << sigchldFd[1] << ")" << oendl;
#endif
QSocketNotifier *sn = new QSocketNotifier( sigchldFd[1],
QSocketNotifier::Read, this );
connect( sn, SIGNAL(activated(int)),
this, SLOT(sigchldHnd(int)) );
sn->setEnabled( TRUE );
}
// install a SIGCHLD handler and ignore SIGPIPE
struct sigaction act;
#if defined(QT_QPROCESS_DEBUG)
- qDebug( "QProcessManager: install a SIGCHLD handler" );
+ odebug << "QProcessManager: install a SIGCHLD handler" << oendl;
#endif
act.sa_handler = qt_C_sigchldHnd;
sigemptyset( &(act.sa_mask) );
sigaddset( &(act.sa_mask), SIGCHLD );
act.sa_flags = SA_NOCLDSTOP;
#if defined(SA_RESTART)
act.sa_flags |= SA_RESTART;
#endif
if ( sigaction( SIGCHLD, &act, &oldactChld ) != 0 )
- qWarning( "Error installing SIGCHLD handler" );
+ owarn << "Error installing SIGCHLD handler" << oendl;
#if defined(QT_QPROCESS_DEBUG)
- qDebug( "QProcessManager: install a SIGPIPE handler (SIG_IGN)" );
+ odebug << "QProcessManager: install a SIGPIPE handler (SIG_IGN)" << oendl;
#endif
/*
Using qt_C_sigpipeHnd rather than SIG_IGN is a workaround
for a strange problem where GNU tar (called by backuprestore)
would hang on filesystem-full. Strangely, the qt_C_sigpipeHnd
is never even called, yet this avoids the hang.
*/
act.sa_handler = qt_C_sigpipeHnd;
sigemptyset( &(act.sa_mask) );
sigaddset( &(act.sa_mask), SIGPIPE );
act.sa_flags = 0;
if ( sigaction( SIGPIPE, &act, &oldactPipe ) != 0 )
- qWarning( "Error installing SIGPIPE handler" );
+ owarn << "Error installing SIGPIPE handler" << oendl;
}
QProcessManager::~QProcessManager()
{
delete procList;
if ( sigchldFd[0] != 0 )
::close( sigchldFd[0] );
if ( sigchldFd[1] != 0 )
::close( sigchldFd[1] );
// restore SIGCHLD handler
#if defined(QT_QPROCESS_DEBUG)
- qDebug( "QProcessManager: restore old sigchild handler" );
+ odebug << "QProcessManager: restore old sigchild handler" << oendl;
#endif
if ( sigaction( SIGCHLD, &oldactChld, 0 ) != 0 )
- qWarning( "Error restoring SIGCHLD handler" );
+ owarn << "Error restoring SIGCHLD handler" << oendl;
#if defined(QT_QPROCESS_DEBUG)
- qDebug( "QProcessManager: restore old sigpipe handler" );
+ odebug << "QProcessManager: restore old sigpipe handler" << oendl;
#endif
if ( sigaction( SIGPIPE, &oldactPipe, 0 ) != 0 )
- qWarning( "Error restoring SIGPIPE handler" );
+ owarn << "Error restoring SIGPIPE handler" << oendl;
}
void QProcessManager::append( QProc *p )
{
procList->append( p );
#if defined(QT_QPROCESS_DEBUG)
- qDebug( "QProcessManager: append process (procList.count(): %d)", procList->count() );
+ odebug << "QProcessManager: append process (procList.count(): " << procList->count() << ")" << oendl;
#endif
}
void QProcessManager::remove( QProc *p )
{
procList->remove( p );
#if defined(QT_QPROCESS_DEBUG)
- qDebug( "QProcessManager: remove process (procList.count(): %d)", procList->count() );
+ odebug << "QProcessManager: remove process (procList.count(): " << procList->count() << ")" << oendl;
#endif
cleanup();
}
void QProcessManager::cleanup()
{
if ( procList->count() == 0 ) {
QTimer::singleShot( 0, this, SLOT(removeMe()) );
@@ -311,57 +310,57 @@ void QProcessManager::removeMe()
}
}
void QProcessManager::sigchldHnd( int fd )
{
char tmp;
::read( fd, &tmp, sizeof(tmp) );
#if defined(QT_QPROCESS_DEBUG)
- qDebug( "QProcessManager::sigchldHnd()" );
+ odebug << "QProcessManager::sigchldHnd()" << oendl;
#endif
QProc *proc;
QProcess *process;
bool removeProc;
proc = procList->first();
while ( proc != 0 ) {
removeProc = FALSE;
process = proc->process;
QProcess *process_exit_notify=0;
if ( process != 0 ) {
if ( !process->isRunning() ) {
#if defined(QT_QPROCESS_DEBUG)
- qDebug( "QProcessManager::sigchldHnd() (PID: %d): process exited (QProcess available)", proc->pid );
+ odebug << "QProcessManager::sigchldHnd() (PID: " << proc->pid << "): process exited (QProcess available)" << oendl;
#endif
// read pending data
int nbytes = 0;
if ( ::ioctl(proc->socketStdout, FIONREAD, (char*)&nbytes)==0 && nbytes>0 ) {
#if defined(QT_QPROCESS_DEBUG)
- qDebug( "QProcessManager::sigchldHnd() (PID: %d): reading %d bytes of pending data on stdout", proc->pid, nbytes );
+ odebug << "QProcessManager::sigchldHnd() (PID: " << proc->pid << "): reading " << nbytes << " bytes of pending data on stdout" << oendl;
#endif
process->socketRead( proc->socketStdout );
}
nbytes = 0;
if ( ::ioctl(proc->socketStderr, FIONREAD, (char*)&nbytes)==0 && nbytes>0 ) {
#if defined(QT_QPROCESS_DEBUG)
- qDebug( "QProcessManager::sigchldHnd() (PID: %d): reading %d bytes of pending data on stderr", proc->pid, nbytes );
+ odebug << "QProcessManager::sigchldHnd() (PID: " << proc->pid << "): reading " << nbytes << " bytes of pending data on stderr" << oendl;
#endif
process->socketRead( proc->socketStderr );
}
if ( process->notifyOnExit )
process_exit_notify = process;
removeProc = TRUE;
}
} else {
int status;
if ( ::waitpid( proc->pid, &status, WNOHANG ) == proc->pid ) {
#if defined(QT_QPROCESS_DEBUG)
- qDebug( "QProcessManager::sigchldHnd() (PID: %d): process exited (QProcess not available)", proc->pid );
+ odebug << "QProcessManager::sigchldHnd() (PID: " << proc->pid << "): process exited (QProcess not available)" << oendl;
#endif
removeProc = TRUE;
}
}
if ( removeProc ) {
QProc *oldproc = proc;
proc = procList->next();
remove( oldproc );
@@ -381,34 +380,34 @@ void QProcessManager::sigchldHnd( int fd )
* QProcessPrivate
*
**********************************************************************/
QProcessManager *QProcessPrivate::procManager = 0;
QProcessPrivate::QProcessPrivate()
{
#if defined(QT_QPROCESS_DEBUG)
- qDebug( "QProcessPrivate: Constructor" );
+ odebug << "QProcessPrivate: Constructor" << oendl;
#endif
stdinBufRead = 0;
notifierStdin = 0;
notifierStdout = 0;
notifierStderr = 0;
exitValuesCalculated = FALSE;
socketReadCalled = FALSE;
proc = 0;
}
QProcessPrivate::~QProcessPrivate()
{
#if defined(QT_QPROCESS_DEBUG)
- qDebug( "QProcessPrivate: Destructor" );
+ odebug << "QProcessPrivate: Destructor" << oendl;
#endif
if ( proc != 0 ) {
if ( proc->socketStdin != 0 ) {
::close( proc->socketStdin );
proc->socketStdin = 0;
}
proc->process = 0;
@@ -594,17 +593,17 @@ QProcess::~QProcess()
also if the process could not be started. (On operating systems that have
zombie processes, Qt will also wait() on the old process.)
\sa launch() closeStdin()
*/
bool QProcess::start( QStringList *env )
{
#if defined(QT_QPROCESS_DEBUG)
- qDebug( "QProcess::start()" );
+ odebug << "QProcess::start()" << oendl;
#endif
reset();
int sStdin[2];
int sStdout[2];
int sStderr[2];
// open sockets for piping
@@ -630,17 +629,17 @@ bool QProcess::start( QStringList *env )
// construct the arguments for exec
QCString *arglistQ = new QCString[ _arguments.count() + 1 ];
const char** arglist = new const char*[ _arguments.count() + 1 ];
int i = 0;
for ( QStringList::Iterator it = _arguments.begin(); it != _arguments.end(); ++it ) {
arglistQ[i] = (*it).local8Bit();
arglist[i] = arglistQ[i];
#if defined(QT_QPROCESS_DEBUG)
- qDebug( "QProcess::start(): arg %d = %s", i, arglist[i] );
+ odebug << "QProcess::start(): arg " << i << " = " << arglist[i] << "" << oendl;
#endif
i++;
}
arglist[i] = 0;
// Must make sure signal handlers are installed before exec'ing
// in case the process exits quickly.
if ( d->procManager == 0 ) {
@@ -794,17 +793,17 @@ bool QProcess::start( QStringList *env )
// cleanup and return
delete[] arglistQ;
delete[] arglist;
return TRUE;
error:
#if defined(QT_QPROCESS_DEBUG)
- qDebug( "QProcess::start(): error starting process" );
+ odebug << "QProcess::start(): error starting process" << oendl;
#endif
if ( d->procManager )
d->procManager->cleanup();
if ( comms & Stdin ) {
::close( sStdin[1] );
::close( sStdin[0] );
}
if ( comms & Stdout ) {
@@ -873,39 +872,39 @@ void QProcess::kill() const
Returns TRUE if the process is running, otherwise FALSE.
\sa normalExit() exitStatus() processExited()
*/
bool QProcess::isRunning() const
{
if ( d->exitValuesCalculated ) {
#if defined(QT_QPROCESS_DEBUG)
- qDebug( "QProcess::isRunning(): FALSE (already computed)" );
+ odebug << "QProcess::isRunning(): FALSE (already computed)" << oendl;
#endif
return FALSE;
}
if ( d->proc == 0 )
return FALSE;
int status;
if ( ::waitpid( d->proc->pid, &status, WNOHANG ) == d->proc->pid )
{
// compute the exit values
QProcess *that = (QProcess*)this; // mutable
that->exitNormal = WIFEXITED( status ) != 0;
if ( exitNormal ) {
that->exitStat = (char)WEXITSTATUS( status );
}
d->exitValuesCalculated = TRUE;
#if defined(QT_QPROCESS_DEBUG)
- qDebug( "QProcess::isRunning() (PID: %d): FALSE", d->proc->pid );
+ odebug << "QProcess::isRunning() (PID: " << d->proc->pid << "): FALSE" << oendl;
#endif
return FALSE;
}
#if defined(QT_QPROCESS_DEBUG)
- qDebug( "QProcess::isRunning() (PID: %d): TRUE", d->proc->pid );
+ odebug << "QProcess::isRunning() (PID: " << d->proc->pid << "): TRUE" << oendl;
#endif
return TRUE;
}
/*!
Writes the data \a buf to the standard input of the process. The process may
or may not read this data.
@@ -915,17 +914,17 @@ bool QProcess::isRunning() const
not mean that the process really read the data, since this class only detects
when it was able to write the data to the operating system.
\sa wroteToStdin() closeStdin() readStdout() readStderr()
*/
void QProcess::writeToStdin( const QByteArray& buf )
{
#if defined(QT_QPROCESS_DEBUG)
-// qDebug( "QProcess::writeToStdin(): write to stdin (%d)", d->socketStdin );
+// odebug << "QProcess::writeToStdin(): write to stdin (" << d->socketStdin << ")" << oendl;
#endif
d->stdinBuf.enqueue( new QByteArray(buf) );
if ( d->notifierStdin != 0 )
d->notifierStdin->setEnabled( TRUE );
}
/*!
@@ -942,20 +941,20 @@ void QProcess::closeStdin()
return;
if ( d->proc->socketStdin !=0 ) {
while ( !d->stdinBuf.isEmpty() ) {
delete d->stdinBuf.dequeue();
}
delete d->notifierStdin;
d->notifierStdin = 0;
if ( ::close( d->proc->socketStdin ) != 0 ) {
- qWarning( "Could not close stdin of child process" );
+ owarn << "Could not close stdin of child process" << oendl;
}
#if defined(QT_QPROCESS_DEBUG)
- qDebug( "QProcess::closeStdin(): stdin (%d) closed", d->proc->socketStdin );
+ odebug << "QProcess::closeStdin(): stdin (" << d->proc->socketStdin << ") closed" << oendl;
#endif
d->proc->socketStdin = 0;
}
}
/*
This private slot is called when the process has outputted data to either
@@ -965,17 +964,17 @@ void QProcess::socketRead( int fd )
{
if ( d->socketReadCalled ) {
// the slots that are connected to the readyRead...() signals might
// trigger a recursive call of socketRead(). Avoid this since you get a
// blocking read otherwise.
return;
}
#if defined(QT_QPROCESS_DEBUG)
- qDebug( "QProcess::socketRead(): %d", fd );
+ odebug << "QProcess::socketRead(): " << fd << "" << oendl;
#endif
if ( fd == 0 )
return;
const int bufsize = 4096;
QByteArray *buffer = 0;
uint oldSize;
int n;
if ( fd == d->proc->socketStdout ) {
@@ -994,27 +993,27 @@ void QProcess::socketRead( int fd )
if ( n > 0 )
buffer->resize( oldSize + n );
else
buffer->resize( oldSize );
// eof or error?
if ( n == 0 || n == -1 ) {
if ( fd == d->proc->socketStdout ) {
#if defined(QT_QPROCESS_DEBUG)
- qDebug( "QProcess::socketRead(): stdout (%d) closed", fd );
+ odebug << "QProcess::socketRead(): stdout (" << fd << ") closed" << oendl;
#endif
d->notifierStdout->setEnabled( FALSE );
delete d->notifierStdout;
d->notifierStdout = 0;
::close( d->proc->socketStdout );
d->proc->socketStdout = 0;
return;
} else if ( fd == d->proc->socketStderr ) {
#if defined(QT_QPROCESS_DEBUG)
- qDebug( "QProcess::socketRead(): stderr (%d) closed", fd );
+ odebug << "QProcess::socketRead(): stderr (" << fd << ") closed" << oendl;
#endif
d->notifierStderr->setEnabled( FALSE );
delete d->notifierStderr;
d->notifierStderr = 0;
::close( d->proc->socketStderr );
d->proc->socketStderr = 0;
return;
}
@@ -1056,17 +1055,17 @@ void QProcess::socketWrite( int fd )
{
if ( fd != d->proc->socketStdin || d->proc->socketStdin == 0 )
return;
if ( d->stdinBuf.isEmpty() ) {
d->notifierStdin->setEnabled( FALSE );
return;
}
#if defined(QT_QPROCESS_DEBUG)
- qDebug( "QProcess::socketWrite(): write to stdin (%d)", fd );
+ odebug << "QProcess::socketWrite(): write to stdin (" << fd << ")" << oendl;
#endif
ssize_t ret = ::write( fd,
d->stdinBuf.head()->data() + d->stdinBufRead,
d->stdinBuf.head()->size() - d->stdinBufRead );
if ( ret > 0 )
d->stdinBufRead += ret;
if ( d->stdinBufRead == (ssize_t)d->stdinBuf.head()->size() ) {
d->stdinBufRead = 0;