21 #include "kprocctrl.h" 26 #include <sys/types.h> 34 #include <tqsocketnotifier.h> 37 int KProcessController::refCount;
58 KProcessController::KProcessController()
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, TQT_SIGNAL(activated(
int)),
75 TQT_SLOT(slotDoHousekeeping()));
78 KProcessController::~KProcessController()
88 static void theReaper(
int num )
97 bool KProcessController::handlerSet = false;
99 void KProcessController::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 KProcessController::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 KProcessController::notifierFd()
const 173 if( ::read( fd[0], dummy,
sizeof(dummy) ) > 0 )
184 ::write( fd[1], &dummy, 1 );
188 void KProcessController::slotDoHousekeeping()
191 ::read( fd[0], dummy,
sizeof(dummy) );
195 TQValueListIterator<KProcess*> it( kProcessList.begin() );
196 TQValueListIterator<KProcess*> 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 KProcessController::addKProcess(
KProcess* p )
263 kProcessList.append( p );
266 void KProcessController::removeKProcess(
KProcess* p )
268 kProcessList.remove( p );
271 void KProcessController::addProcess(
int pid )
273 unixProcessList.append( pid );
277 #include "kprocctrl.moc" Child process invocation, monitoring and control.
static KProcessController * theKProcessController
Only a single instance of this class is allowed at a time, and this static variable is used to track ...
static void ref()
Create an instance if none exists yet.
bool runs
true if the process is currently running.
void unscheduleCheck()
Call this function to defer processing of the data that became available on notifierFd().
virtual void processHasExited(int state)
Immediately called after a successfully started process in NotifyOnExit mode has exited.
Used internally by KProcess.
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 void deref()
Destroy the instance if one exists and it is not referenced any more.
pid_t pid_
The PID of the currently running process.
static void theSigCHLDHandler(int signal)
Automatically called upon SIGCHLD.