26 #include <sys/types.h>
34 #include <QtCore/QSocketNotifier>
36 class K3ProcessController::Private
52 QSocketNotifier *notifier;
53 QList<K3Process*> kProcessList;
55 static struct sigaction oldChildHandlerData;
56 static bool handlerSet;
62 int K3ProcessController::Private::refCount = 0;
66 if ( !Private::refCount ) {
76 if( !Private::refCount ) {
79 Private::instance = 0;
95 K3ProcessController::K3ProcessController()
104 fcntl( d->fd[0], F_SETFL, O_NONBLOCK );
105 fcntl( d->fd[1], F_SETFL, O_NONBLOCK );
106 fcntl( d->fd[0], F_SETFD, FD_CLOEXEC );
107 fcntl( d->fd[1], F_SETFD, FD_CLOEXEC );
109 d->notifier =
new QSocketNotifier( d->fd[0], QSocketNotifier::Read );
110 d->notifier->setEnabled(
true );
111 QObject::connect( d->notifier, SIGNAL(activated(
int)),
112 SLOT(slotDoHousekeeping()));
115 K3ProcessController::~K3ProcessController()
122 #warning FIXME: why does close() freeze up destruction?
139 bool K3ProcessController::Private::handlerSet = false;
141 void K3ProcessController::setupHandlers()
143 if( Private::handlerSet )
145 Private::handlerSet =
true;
148 struct sigaction act;
149 sigemptyset( &act.sa_mask );
151 act.sa_handler = SIG_IGN;
153 sigaction( SIGPIPE, &act, 0L );
156 act.sa_flags = SA_NOCLDSTOP;
160 act.sa_flags |= SA_RESTART;
162 sigaction( SIGCHLD, &act, &Private::oldChildHandlerData );
164 sigaddset( &act.sa_mask, SIGCHLD );
166 sigprocmask( SIG_UNBLOCK, &act.sa_mask, 0 );
172 void K3ProcessController::resetHandlers()
174 if( !Private::handlerSet )
176 Private::handlerSet =
false;
179 sigset_t
mask, omask;
180 sigemptyset( &mask );
181 sigaddset( &mask, SIGCHLD );
182 sigprocmask( SIG_BLOCK, &mask, &omask );
184 struct sigaction act;
185 sigaction( SIGCHLD, &Private::oldChildHandlerData, &act );
187 sigaction( SIGCHLD, &act, 0 );
188 Private::handlerSet =
true;
191 sigprocmask( SIG_SETMASK, &omask, 0 );
203 int saved_errno = errno;
206 ::write(
instance()->d->fd[1], &dummy, 1 );
209 if ( Private::oldChildHandlerData.sa_handler != SIG_IGN &&
210 Private::oldChildHandlerData.sa_handler != SIG_DFL ) {
211 Private::oldChildHandlerData.sa_handler( arg );
228 if( ::read( d->fd[0], dummy,
sizeof(dummy) ) > 0 )
237 d->needcheck =
false;
239 ::write( d->fd[1], &dummy, 1 );
243 void K3ProcessController::slotDoHousekeeping()
246 ::read( d->fd[0], dummy,
sizeof(dummy) );
250 QList<K3Process*>::iterator it( d->kProcessList.begin() );
251 QList<K3Process*>::iterator eit( d->kProcessList.end() );
255 if( prc->
runs && waitpid( prc->
pid_, &status, WNOHANG ) > 0 )
265 QList<int>::iterator uit( d->unixProcessList.begin() );
266 QList<int>::iterator ueit( d->unixProcessList.end() );
269 if( waitpid( *uit, 0, WNOHANG ) > 0 )
271 uit = d->unixProcessList.erase( uit );
283 struct timeval tv, *tvp;
295 FD_SET( d->fd[0], &fds );
297 switch( select( d->fd[0]+1, &fds, 0, 0, tvp ) )
306 slotDoHousekeeping();
318 d->kProcessList.append( p );
323 d->kProcessList.removeAll( p );
328 d->unixProcessList.append( pid );
332 #include "k3processcontroller.moc"