20 #include "tdeprocess.h"
21 #include "kprocctrl.h"
26 #include <sys/types.h>
34 #include <tqsocketnotifier.h>
37 int TDEProcessController::refCount;
58 TDEProcessController::TDEProcessController()
67 fcntl( fd[0], F_SETFL, O_NONBLOCK );
68 fcntl( fd[1], F_SETFL, O_NONBLOCK );
69 fcntl( fd[0], F_SETFD, FD_CLOEXEC );
70 fcntl( fd[1], F_SETFD, FD_CLOEXEC );
72 notifier =
new TQSocketNotifier( fd[0], TQSocketNotifier::Read );
73 notifier->setEnabled(
true );
74 TQObject::connect( notifier, TQ_SIGNAL(activated(
int)),
75 TQ_SLOT(slotDoHousekeeping()));
78 TDEProcessController::~TDEProcessController()
88 static void theReaper(
int num )
97 bool TDEProcessController::handlerSet = false;
99 void TDEProcessController::setupHandlers()
106 struct sigaction act;
107 sigemptyset( &act.sa_mask );
109 act.sa_handler = SIG_IGN;
111 sigaction( SIGPIPE, &act, 0L );
113 act.sa_handler = theReaper;
114 act.sa_flags = SA_NOCLDSTOP;
118 act.sa_flags |= SA_RESTART;
120 sigaction( SIGCHLD, &act, &oldChildHandlerData );
122 sigaddset( &act.sa_mask, SIGCHLD );
124 sigprocmask( SIG_UNBLOCK, &act.sa_mask, 0 );
130 void TDEProcessController::resetHandlers()
137 sigaction( SIGCHLD, &oldChildHandlerData, 0 );
149 int saved_errno = errno;
155 if( oldChildHandlerData.sa_handler != SIG_IGN &&
156 oldChildHandlerData.sa_handler != SIG_DFL )
157 oldChildHandlerData.sa_handler( arg );
165 int TDEProcessController::notifierFd()
const
173 if( ::read( fd[0], dummy,
sizeof(dummy) ) > 0 )
184 ::write( fd[1], &dummy, 1 );
188 void TDEProcessController::slotDoHousekeeping()
191 ::read( fd[0], dummy,
sizeof(dummy) );
195 TQValueListIterator<TDEProcess*> it( kProcessList.begin() );
196 TQValueListIterator<TDEProcess*> eit( kProcessList.end() );
200 if( prc->
runs && waitpid( prc->
pid_, &status, WNOHANG ) > 0 )
210 TQValueListIterator<int> uit( unixProcessList.begin() );
211 TQValueListIterator<int> ueit( unixProcessList.end() );
214 if( waitpid( *uit, 0, WNOHANG ) > 0 )
216 uit = unixProcessList.remove( uit );
228 struct timeval tv, *tvp;
240 FD_SET( fd[0], &fds );
242 switch( select( fd[0]+1, &fds, 0, 0, tvp ) )
251 slotDoHousekeeping();
261 void TDEProcessController::addTDEProcess(
TDEProcess* p )
263 kProcessList.append( p );
266 void TDEProcessController::removeTDEProcess(
TDEProcess* p )
268 kProcessList.remove( p );
271 void TDEProcessController::addProcess(
int pid )
273 unixProcessList.append( pid );
277 #include "kprocctrl.moc"
Used internally by TDEProcess.
static void theSigCHLDHandler(int signal)
Automatically called upon SIGCHLD.
static void deref()
Destroy the instance if one exists and it is not referenced any more.
static void ref()
Create an instance if none exists yet.
bool waitForProcessExit(int timeout)
Wait for any process to exit and handle their exit without starting an event loop.
void rescheduleCheck()
This function must be called at some point after calling unscheduleCheck().
static TDEProcessController * theTDEProcessController
Only a single instance of this class is allowed at a time, and this static variable is used to track ...
void unscheduleCheck()
Call this function to defer processing of the data that became available on notifierFd().
Child process invocation, monitoring and control.
pid_t pid_
The PID of the currently running process.
virtual void processHasExited(int state)
Immediately called after a successfully started process in NotifyOnExit mode has exited.
bool runs
true if the process is currently running.
TDEAction * close(const TQObject *recvr, const char *slot, TDEActionCollection *parent, const char *name=0)