

Definition at line 161 of file q3process_unix.cpp.
Public Slots | |
| void | removeMe () |
| void | sigchldHnd (int) |
Public Member Functions | |
| Q3ProcessManager () | |
| ~Q3ProcessManager () | |
| void | append (QProc *p) |
| void | remove (QProc *p) |
| void | cleanup () |
Public Attributes | |
| sigaction | oldactChld |
| sigaction | oldactPipe |
| Q3PtrList< QProc > * | procList |
| int | sigchldFd [2] |
Private Attributes | |
| QSocketNotifier * | sn |
| Q3ProcessManager::Q3ProcessManager | ( | ) |
Definition at line 243 of file q3process_unix.cpp.
References QObject::connect(), oldactChld, oldactPipe, procList, qDebug(), qt_C_sigchldHnd(), qWarning(), QSocketNotifier::Read, Q3PtrCollection::setAutoDelete(), QSocketNotifier::setEnabled(), sigchldFd, sigchldHnd(), SIGNAL, SLOT, and sn.
00243 : sn(0) 00244 { 00245 procList = new Q3PtrList<QProc>; 00246 procList->setAutoDelete( true ); 00247 00248 // The SIGCHLD handler writes to a socket to tell the manager that 00249 // something happened. This is done to get the processing in sync with the 00250 // event reporting. 00251 #ifndef Q_OS_QNX6 00252 if ( ::socketpair( AF_UNIX, SOCK_STREAM, 0, sigchldFd ) ) { 00253 #else 00254 if ( qnx6SocketPairReplacement (sigchldFd) ) { 00255 #endif 00256 sigchldFd[0] = 0; 00257 sigchldFd[1] = 0; 00258 } else { 00259 #if defined(QT_Q3PROCESS_DEBUG) 00260 qDebug( "Q3ProcessManager: install socket notifier (%d)", sigchldFd[1] ); 00261 #endif 00262 sn = new QSocketNotifier( sigchldFd[1], 00263 QSocketNotifier::Read, this ); 00264 connect( sn, SIGNAL(activated(int)), 00265 this, SLOT(sigchldHnd(int)) ); 00266 sn->setEnabled( true ); 00267 } 00268 00269 // install a SIGCHLD handler and ignore SIGPIPE 00270 struct sigaction act; 00271 00272 #if defined(QT_Q3PROCESS_DEBUG) 00273 qDebug( "Q3ProcessManager: install a SIGCHLD handler" ); 00274 #endif 00275 act.sa_handler = qt_C_sigchldHnd; 00276 sigemptyset( &(act.sa_mask) ); 00277 sigaddset( &(act.sa_mask), SIGCHLD ); 00278 act.sa_flags = SA_NOCLDSTOP; 00279 #if defined(SA_RESTART) 00280 act.sa_flags |= SA_RESTART; 00281 #endif 00282 if ( sigaction( SIGCHLD, &act, &oldactChld ) != 0 ) 00283 qWarning( "Error installing SIGCHLD handler" ); 00284 00285 #if defined(QT_Q3PROCESS_DEBUG) 00286 qDebug( "Q3ProcessManager: install a SIGPIPE handler (SIG_IGN)" ); 00287 #endif 00288 act.sa_handler = QT_SIGNAL_IGNORE; 00289 sigemptyset( &(act.sa_mask) ); 00290 sigaddset( &(act.sa_mask), SIGPIPE ); 00291 act.sa_flags = 0; 00292 if ( sigaction( SIGPIPE, &act, &oldactPipe ) != 0 ) 00293 qWarning( "Error installing SIGPIPE handler" ); 00294 }
Here is the call graph for this function:

| Q3ProcessManager::~Q3ProcessManager | ( | ) |
Definition at line 296 of file q3process_unix.cpp.
References oldactChld, oldactPipe, procList, qDebug(), qWarning(), and sigchldFd.
00297 { 00298 delete procList; 00299 00300 if ( sigchldFd[0] != 0 ) 00301 ::close( sigchldFd[0] ); 00302 if ( sigchldFd[1] != 0 ) 00303 ::close( sigchldFd[1] ); 00304 00305 // restore SIGCHLD handler 00306 #if defined(QT_Q3PROCESS_DEBUG) 00307 qDebug( "Q3ProcessManager: restore old sigchild handler" ); 00308 #endif 00309 if ( sigaction( SIGCHLD, &oldactChld, 0 ) != 0 ) 00310 qWarning( "Error restoring SIGCHLD handler" ); 00311 00312 #if defined(QT_Q3PROCESS_DEBUG) 00313 qDebug( "Q3ProcessManager: restore old sigpipe handler" ); 00314 #endif 00315 if ( sigaction( SIGPIPE, &oldactPipe, 0 ) != 0 ) 00316 qWarning( "Error restoring SIGPIPE handler" ); 00317 }
Here is the call graph for this function:

| void Q3ProcessManager::append | ( | QProc * | p | ) |
Definition at line 319 of file q3process_unix.cpp.
References Q3PtrList< type >::append(), Q3PtrList< type >::count(), p, procList, and qDebug().
Referenced by Q3ProcessPrivate::newProc().
00320 { 00321 procList->append( p ); 00322 #if defined(QT_Q3PROCESS_DEBUG) 00323 qDebug( "Q3ProcessManager: append process (procList.count(): %d)", procList->count() ); 00324 #endif 00325 }
Here is the call graph for this function:

| void Q3ProcessManager::remove | ( | QProc * | p | ) |
Definition at line 327 of file q3process_unix.cpp.
References cleanup(), Q3PtrList< type >::count(), p, procList, qDebug(), and Q3PtrList< type >::remove().
Referenced by sigchldHnd().
00328 { 00329 procList->remove( p ); 00330 #if defined(QT_Q3PROCESS_DEBUG) 00331 qDebug( "Q3ProcessManager: remove process (procList.count(): %d)", procList->count() ); 00332 #endif 00333 cleanup(); 00334 }
Here is the call graph for this function:

| void Q3ProcessManager::cleanup | ( | ) |
Definition at line 336 of file q3process_unix.cpp.
References Q3PtrList< type >::count(), procList, removeMe(), QTimer::singleShot(), and SLOT.
Referenced by remove(), and Q3Process::start().
00337 { 00338 if ( procList->count() == 0 ) { 00339 QTimer::singleShot( 0, this, SLOT(removeMe()) ); 00340 } 00341 }
Here is the call graph for this function:

| void Q3ProcessManager::removeMe | ( | ) | [slot] |
Definition at line 343 of file q3process_unix.cpp.
References Q3PtrList< type >::count(), procList, Q3ProcessPrivate::procManager, q3process_cleanup(), and qRemovePostRoutine().
Referenced by cleanup().
00344 { 00345 if ( procList->count() == 0 ) { 00346 qRemovePostRoutine(q3process_cleanup); 00347 Q3ProcessPrivate::procManager = 0; 00348 delete this; 00349 } 00350 }
| void Q3ProcessManager::sigchldHnd | ( | int | ) | [slot] |
Definition at line 352 of file q3process_unix.cpp.
References Q3Process::d, emit, Q3PtrList< type >::first(), QSocketNotifier::isEnabled(), Q3Process::isRunning(), Q3PtrList< type >::next(), Q3ProcessPrivate::notifierStderr, Q3ProcessPrivate::notifierStdout, Q3Process::notifyOnExit, QProc::pid, QProc::process, Q3Process::processExited(), procList, qDebug(), remove(), QSocketNotifier::setEnabled(), sn, Q3Process::socketRead(), QProc::socketStderr, and QProc::socketStdout.
Referenced by Q3Process::isRunning(), and Q3ProcessManager().
00353 { 00354 // Disable the socket notifier to make sure that this function is not 00355 // called recursively -- this can happen, if you enter the event loop in 00356 // the slot connected to the processExited() signal (e.g. by showing a 00357 // modal dialog) and there are more than one process which exited in the 00358 // meantime. 00359 if ( sn ) { 00360 if ( !sn->isEnabled() ) 00361 return; 00362 sn->setEnabled( false ); 00363 } 00364 00365 char tmp; 00366 ::read( fd, &tmp, sizeof(tmp) ); 00367 #if defined(QT_Q3PROCESS_DEBUG) 00368 qDebug( "Q3ProcessManager::sigchldHnd()" ); 00369 #endif 00370 QProc *proc; 00371 Q3Process *process; 00372 bool removeProc; 00373 proc = procList->first(); 00374 while ( proc != 0 ) { 00375 removeProc = false; 00376 process = proc->process; 00377 if ( process != 0 ) { 00378 if ( !process->isRunning() ) { 00379 #if defined(QT_Q3PROCESS_DEBUG) 00380 qDebug( "Q3ProcessManager::sigchldHnd() (PID: %d): process exited (Q3Process available)", proc->pid ); 00381 #endif 00382 /* 00383 Apparently, there is not consistency among different 00384 operating systems on how to use FIONREAD. 00385 00386 FreeBSD, Linux and Solaris all expect the 3rd 00387 argument to ioctl() to be an int, which is normally 00388 32-bit even on 64-bit machines. 00389 00390 IRIX, on the other hand, expects a size_t, which is 00391 64-bit on 64-bit machines. 00392 00393 So, the solution is to use size_t initialized to 00394 zero to make sure all bits are set to zero, 00395 preventing underflow with the FreeBSD/Linux/Solaris 00396 ioctls. 00397 */ 00398 size_t nbytes = 0; 00399 // read pending data 00400 if ( proc->socketStdout && ::ioctl(proc->socketStdout, FIONREAD, (char*)&nbytes)==0 && nbytes>0 ) { 00401 #if defined(QT_Q3PROCESS_DEBUG) 00402 qDebug( "Q3ProcessManager::sigchldHnd() (PID: %d): reading %d bytes of pending data on stdout", proc->pid, nbytes ); 00403 #endif 00404 process->socketRead( proc->socketStdout ); 00405 } 00406 nbytes = 0; 00407 if ( proc->socketStderr && ::ioctl(proc->socketStderr, FIONREAD, (char*)&nbytes)==0 && nbytes>0 ) { 00408 #if defined(QT_Q3PROCESS_DEBUG) 00409 qDebug( "Q3ProcessManager::sigchldHnd() (PID: %d): reading %d bytes of pending data on stderr", proc->pid, nbytes ); 00410 #endif 00411 process->socketRead( proc->socketStderr ); 00412 } 00413 // close filedescriptors if open, and disable the 00414 // socket notifiers 00415 if ( proc->socketStdout ) { 00416 ::close( proc->socketStdout ); 00417 proc->socketStdout = 0; 00418 if (process->d->notifierStdout) 00419 process->d->notifierStdout->setEnabled(false); 00420 } 00421 if ( proc->socketStderr ) { 00422 ::close( proc->socketStderr ); 00423 proc->socketStderr = 0; 00424 if (process->d->notifierStderr) 00425 process->d->notifierStderr->setEnabled(false); 00426 } 00427 00428 if ( process->notifyOnExit ) 00429 emit process->processExited(); 00430 00431 removeProc = true; 00432 } 00433 } else { 00434 int status; 00435 if ( ::waitpid( proc->pid, &status, WNOHANG ) == proc->pid ) { 00436 #if defined(QT_Q3PROCESS_DEBUG) 00437 qDebug( "Q3ProcessManager::sigchldHnd() (PID: %d): process exited (Q3Process not available)", proc->pid ); 00438 #endif 00439 removeProc = true; 00440 } 00441 } 00442 if ( removeProc ) { 00443 QProc *oldproc = proc; 00444 proc = procList->next(); 00445 remove( oldproc ); 00446 } else { 00447 proc = procList->next(); 00448 } 00449 } 00450 if ( sn ) 00451 sn->setEnabled( true ); 00452 }
| struct sigaction Q3ProcessManager::oldactChld |
Definition at line 179 of file q3process_unix.cpp.
Referenced by Q3ProcessManager(), and ~Q3ProcessManager().
| struct sigaction Q3ProcessManager::oldactPipe |
Definition at line 180 of file q3process_unix.cpp.
Referenced by Q3ProcessManager(), and ~Q3ProcessManager().
Definition at line 181 of file q3process_unix.cpp.
Referenced by append(), cleanup(), Q3ProcessPrivate::closeOpenSocketsForChild(), Q3ProcessManager(), remove(), removeMe(), sigchldHnd(), and ~Q3ProcessManager().
| int Q3ProcessManager::sigchldFd[2] |
Definition at line 182 of file q3process_unix.cpp.
Referenced by Q3ProcessPrivate::closeOpenSocketsForChild(), Q3Process::isRunning(), Q3ProcessManager(), qt_C_sigchldHnd(), and ~Q3ProcessManager().
QSocketNotifier* Q3ProcessManager::sn [private] |
Definition at line 185 of file q3process_unix.cpp.
Referenced by Q3ProcessManager(), and sigchldHnd().
1.5.1