Diffstat (limited to 'core/launcher/qprocess_unix.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | core/launcher/qprocess_unix.cpp | 646 |
1 files changed, 323 insertions, 323 deletions
diff --git a/core/launcher/qprocess_unix.cpp b/core/launcher/qprocess_unix.cpp index 56e1b1d..97c0460 100644 --- a/core/launcher/qprocess_unix.cpp +++ b/core/launcher/qprocess_unix.cpp | |||
@@ -133,32 +133,32 @@ public: | |||
133 | #if defined(QT_QPROCESS_DEBUG) | 133 | #if defined(QT_QPROCESS_DEBUG) |
134 | odebug << "QProc: Constructor for pid " << pid << " and QProcess " << process << "" << oendl; | 134 | odebug << "QProc: Constructor for pid " << pid << " and QProcess " << process << "" << oendl; |
135 | #endif | 135 | #endif |
136 | socketStdin = 0; | 136 | socketStdin = 0; |
137 | socketStdout = 0; | 137 | socketStdout = 0; |
138 | socketStderr = 0; | 138 | socketStderr = 0; |
139 | } | 139 | } |
140 | ~QProc() | 140 | ~QProc() |
141 | { | 141 | { |
142 | #if defined(QT_QPROCESS_DEBUG) | 142 | #if defined(QT_QPROCESS_DEBUG) |
143 | odebug << "QProc: Destructor for pid " << pid << " and QProcess " << process << "" << oendl; | 143 | odebug << "QProc: Destructor for pid " << pid << " and QProcess " << process << "" << oendl; |
144 | #endif | 144 | #endif |
145 | if ( process != 0 ) { | 145 | if ( process != 0 ) { |
146 | if ( process->d->notifierStdin ) | 146 | if ( process->d->notifierStdin ) |
147 | process->d->notifierStdin->setEnabled( FALSE ); | 147 | process->d->notifierStdin->setEnabled( FALSE ); |
148 | if ( process->d->notifierStdout ) | 148 | if ( process->d->notifierStdout ) |
149 | process->d->notifierStdout->setEnabled( FALSE ); | 149 | process->d->notifierStdout->setEnabled( FALSE ); |
150 | if ( process->d->notifierStderr ) | 150 | if ( process->d->notifierStderr ) |
151 | process->d->notifierStderr->setEnabled( FALSE ); | 151 | process->d->notifierStderr->setEnabled( FALSE ); |
152 | process->d->proc = 0; | 152 | process->d->proc = 0; |
153 | } | 153 | } |
154 | if( socketStdin != 0 ) | 154 | if( socketStdin != 0 ) |
155 | ::close( socketStdin ); | 155 | ::close( socketStdin ); |
156 | // ### close these sockets even on parent exit or is it better only on | 156 | // ### close these sockets even on parent exit or is it better only on |
157 | // sigchld (but what do I have to do with them on exit then)? | 157 | // sigchld (but what do I have to do with them on exit then)? |
158 | if( socketStdout != 0 ) | 158 | if( socketStdout != 0 ) |
159 | ::close( socketStdout ); | 159 | ::close( socketStdout ); |
160 | if( socketStderr != 0 ) | 160 | if( socketStderr != 0 ) |
161 | ::close( socketStderr ); | 161 | ::close( socketStderr ); |
162 | } | 162 | } |
163 | 163 | ||
164 | pid_t pid; | 164 | pid_t pid; |
@@ -208,17 +208,17 @@ QProcessManager::QProcessManager() | |||
208 | // something happened. This is done to get the processing in sync with the | 208 | // something happened. This is done to get the processing in sync with the |
209 | // event reporting. | 209 | // event reporting. |
210 | if ( ::socketpair( AF_UNIX, SOCK_STREAM, 0, sigchldFd ) ) { | 210 | if ( ::socketpair( AF_UNIX, SOCK_STREAM, 0, sigchldFd ) ) { |
211 | sigchldFd[0] = 0; | 211 | sigchldFd[0] = 0; |
212 | sigchldFd[1] = 0; | 212 | sigchldFd[1] = 0; |
213 | } else { | 213 | } else { |
214 | #if defined(QT_QPROCESS_DEBUG) | 214 | #if defined(QT_QPROCESS_DEBUG) |
215 | odebug << "QProcessManager: install socket notifier (" << sigchldFd[1] << ")" << oendl; | 215 | odebug << "QProcessManager: install socket notifier (" << sigchldFd[1] << ")" << oendl; |
216 | #endif | 216 | #endif |
217 | QSocketNotifier *sn = new QSocketNotifier( sigchldFd[1], | 217 | QSocketNotifier *sn = new QSocketNotifier( sigchldFd[1], |
218 | QSocketNotifier::Read, this ); | 218 | QSocketNotifier::Read, this ); |
219 | connect( sn, SIGNAL(activated(int)), | 219 | connect( sn, SIGNAL(activated(int)), |
220 | this, SLOT(sigchldHnd(int)) ); | 220 | this, SLOT(sigchldHnd(int)) ); |
221 | sn->setEnabled( TRUE ); | 221 | sn->setEnabled( TRUE ); |
222 | } | 222 | } |
223 | 223 | ||
224 | // install a SIGCHLD handler and ignore SIGPIPE | 224 | // install a SIGCHLD handler and ignore SIGPIPE |
@@ -241,10 +241,10 @@ QProcessManager::QProcessManager() | |||
241 | odebug << "QProcessManager: install a SIGPIPE handler (SIG_IGN)" << oendl; | 241 | odebug << "QProcessManager: install a SIGPIPE handler (SIG_IGN)" << oendl; |
242 | #endif | 242 | #endif |
243 | /* | 243 | /* |
244 | Using qt_C_sigpipeHnd rather than SIG_IGN is a workaround | 244 | Using qt_C_sigpipeHnd rather than SIG_IGN is a workaround |
245 | for a strange problem where GNU tar (called by backuprestore) | 245 | for a strange problem where GNU tar (called by backuprestore) |
246 | would hang on filesystem-full. Strangely, the qt_C_sigpipeHnd | 246 | would hang on filesystem-full. Strangely, the qt_C_sigpipeHnd |
247 | is never even called, yet this avoids the hang. | 247 | is never even called, yet this avoids the hang. |
248 | */ | 248 | */ |
249 | act.sa_handler = qt_C_sigpipeHnd; | 249 | act.sa_handler = qt_C_sigpipeHnd; |
250 | sigemptyset( &(act.sa_mask) ); | 250 | sigemptyset( &(act.sa_mask) ); |
@@ -259,9 +259,9 @@ QProcessManager::~QProcessManager() | |||
259 | delete procList; | 259 | delete procList; |
260 | 260 | ||
261 | if ( sigchldFd[0] != 0 ) | 261 | if ( sigchldFd[0] != 0 ) |
262 | ::close( sigchldFd[0] ); | 262 | ::close( sigchldFd[0] ); |
263 | if ( sigchldFd[1] != 0 ) | 263 | if ( sigchldFd[1] != 0 ) |
264 | ::close( sigchldFd[1] ); | 264 | ::close( sigchldFd[1] ); |
265 | 265 | ||
266 | // restore SIGCHLD handler | 266 | // restore SIGCHLD handler |
267 | #if defined(QT_QPROCESS_DEBUG) | 267 | #if defined(QT_QPROCESS_DEBUG) |
@@ -297,16 +297,16 @@ void QProcessManager::remove( QProc *p ) | |||
297 | void QProcessManager::cleanup() | 297 | void QProcessManager::cleanup() |
298 | { | 298 | { |
299 | if ( procList->count() == 0 ) { | 299 | if ( procList->count() == 0 ) { |
300 | QTimer::singleShot( 0, this, SLOT(removeMe()) ); | 300 | QTimer::singleShot( 0, this, SLOT(removeMe()) ); |
301 | } | 301 | } |
302 | } | 302 | } |
303 | 303 | ||
304 | void QProcessManager::removeMe() | 304 | void QProcessManager::removeMe() |
305 | { | 305 | { |
306 | if ( procList->count() == 0 ) { | 306 | if ( procList->count() == 0 ) { |
307 | qprocess_cleanup_procmanager.remove( &QProcessPrivate::procManager ); | 307 | qprocess_cleanup_procmanager.remove( &QProcessPrivate::procManager ); |
308 | QProcessPrivate::procManager = 0; | 308 | QProcessPrivate::procManager = 0; |
309 | delete this; | 309 | delete this; |
310 | } | 310 | } |
311 | } | 311 | } |
312 | 312 | ||
@@ -322,53 +322,53 @@ void QProcessManager::sigchldHnd( int fd ) | |||
322 | bool removeProc; | 322 | bool removeProc; |
323 | proc = procList->first(); | 323 | proc = procList->first(); |
324 | while ( proc != 0 ) { | 324 | while ( proc != 0 ) { |
325 | removeProc = FALSE; | 325 | removeProc = FALSE; |
326 | process = proc->process; | 326 | process = proc->process; |
327 | QProcess *process_exit_notify=0; | 327 | QProcess *process_exit_notify=0; |
328 | if ( process != 0 ) { | 328 | if ( process != 0 ) { |
329 | if ( !process->isRunning() ) { | 329 | if ( !process->isRunning() ) { |
330 | #if defined(QT_QPROCESS_DEBUG) | 330 | #if defined(QT_QPROCESS_DEBUG) |
331 | odebug << "QProcessManager::sigchldHnd() (PID: " << proc->pid << "): process exited (QProcess available)" << oendl; | 331 | odebug << "QProcessManager::sigchldHnd() (PID: " << proc->pid << "): process exited (QProcess available)" << oendl; |
332 | #endif | 332 | #endif |
333 | // read pending data | 333 | // read pending data |
334 | int nbytes = 0; | 334 | int nbytes = 0; |
335 | if ( ::ioctl(proc->socketStdout, FIONREAD, (char*)&nbytes)==0 && nbytes>0 ) { | 335 | if ( ::ioctl(proc->socketStdout, FIONREAD, (char*)&nbytes)==0 && nbytes>0 ) { |
336 | #if defined(QT_QPROCESS_DEBUG) | 336 | #if defined(QT_QPROCESS_DEBUG) |
337 | odebug << "QProcessManager::sigchldHnd() (PID: " << proc->pid << "): reading " << nbytes << " bytes of pending data on stdout" << oendl; | 337 | odebug << "QProcessManager::sigchldHnd() (PID: " << proc->pid << "): reading " << nbytes << " bytes of pending data on stdout" << oendl; |
338 | #endif | 338 | #endif |
339 | process->socketRead( proc->socketStdout ); | 339 | process->socketRead( proc->socketStdout ); |
340 | } | 340 | } |
341 | nbytes = 0; | 341 | nbytes = 0; |
342 | if ( ::ioctl(proc->socketStderr, FIONREAD, (char*)&nbytes)==0 && nbytes>0 ) { | 342 | if ( ::ioctl(proc->socketStderr, FIONREAD, (char*)&nbytes)==0 && nbytes>0 ) { |
343 | #if defined(QT_QPROCESS_DEBUG) | 343 | #if defined(QT_QPROCESS_DEBUG) |
344 | odebug << "QProcessManager::sigchldHnd() (PID: " << proc->pid << "): reading " << nbytes << " bytes of pending data on stderr" << oendl; | 344 | odebug << "QProcessManager::sigchldHnd() (PID: " << proc->pid << "): reading " << nbytes << " bytes of pending data on stderr" << oendl; |
345 | #endif | 345 | #endif |
346 | process->socketRead( proc->socketStderr ); | 346 | process->socketRead( proc->socketStderr ); |
347 | } | 347 | } |
348 | 348 | ||
349 | if ( process->notifyOnExit ) | 349 | if ( process->notifyOnExit ) |
350 | process_exit_notify = process; | 350 | process_exit_notify = process; |
351 | 351 | ||
352 | removeProc = TRUE; | 352 | removeProc = TRUE; |
353 | } | 353 | } |
354 | } else { | 354 | } else { |
355 | int status; | 355 | int status; |
356 | if ( ::waitpid( proc->pid, &status, WNOHANG ) == proc->pid ) { | 356 | if ( ::waitpid( proc->pid, &status, WNOHANG ) == proc->pid ) { |
357 | #if defined(QT_QPROCESS_DEBUG) | 357 | #if defined(QT_QPROCESS_DEBUG) |
358 | odebug << "QProcessManager::sigchldHnd() (PID: " << proc->pid << "): process exited (QProcess not available)" << oendl; | 358 | odebug << "QProcessManager::sigchldHnd() (PID: " << proc->pid << "): process exited (QProcess not available)" << oendl; |
359 | #endif | 359 | #endif |
360 | removeProc = TRUE; | 360 | removeProc = TRUE; |
361 | } | 361 | } |
362 | } | 362 | } |
363 | if ( removeProc ) { | 363 | if ( removeProc ) { |
364 | QProc *oldproc = proc; | 364 | QProc *oldproc = proc; |
365 | proc = procList->next(); | 365 | proc = procList->next(); |
366 | remove( oldproc ); | 366 | remove( oldproc ); |
367 | } else { | 367 | } else { |
368 | proc = procList->next(); | 368 | proc = procList->next(); |
369 | } | 369 | } |
370 | if ( process_exit_notify ) | 370 | if ( process_exit_notify ) |
371 | emit process_exit_notify->processExited(); | 371 | emit process_exit_notify->processExited(); |
372 | } | 372 | } |
373 | } | 373 | } |
374 | 374 | ||
@@ -406,15 +406,15 @@ QProcessPrivate::~QProcessPrivate() | |||
406 | #endif | 406 | #endif |
407 | 407 | ||
408 | if ( proc != 0 ) { | 408 | if ( proc != 0 ) { |
409 | if ( proc->socketStdin != 0 ) { | 409 | if ( proc->socketStdin != 0 ) { |
410 | ::close( proc->socketStdin ); | 410 | ::close( proc->socketStdin ); |
411 | proc->socketStdin = 0; | 411 | proc->socketStdin = 0; |
412 | } | 412 | } |
413 | proc->process = 0; | 413 | proc->process = 0; |
414 | } | 414 | } |
415 | 415 | ||
416 | while ( !stdinBuf.isEmpty() ) { | 416 | while ( !stdinBuf.isEmpty() ) { |
417 | delete stdinBuf.dequeue(); | 417 | delete stdinBuf.dequeue(); |
418 | } | 418 | } |
419 | delete notifierStdin; | 419 | delete notifierStdin; |
420 | delete notifierStdout; | 420 | delete notifierStdout; |
@@ -429,18 +429,18 @@ QProcessPrivate::~QProcessPrivate() | |||
429 | void QProcessPrivate::closeOpenSocketsForChild() | 429 | void QProcessPrivate::closeOpenSocketsForChild() |
430 | { | 430 | { |
431 | if ( procManager != 0 ) { | 431 | if ( procManager != 0 ) { |
432 | if ( procManager->sigchldFd[0] != 0 ) | 432 | if ( procManager->sigchldFd[0] != 0 ) |
433 | ::close( procManager->sigchldFd[0] ); | 433 | ::close( procManager->sigchldFd[0] ); |
434 | if ( procManager->sigchldFd[1] != 0 ) | 434 | if ( procManager->sigchldFd[1] != 0 ) |
435 | ::close( procManager->sigchldFd[1] ); | 435 | ::close( procManager->sigchldFd[1] ); |
436 | 436 | ||
437 | // close also the sockets from other QProcess instances | 437 | // close also the sockets from other QProcess instances |
438 | QProc *proc; | 438 | QProc *proc; |
439 | for ( proc=procManager->procList->first(); proc!=0; proc=procManager->procList->next() ) { | 439 | for ( proc=procManager->procList->first(); proc!=0; proc=procManager->procList->next() ) { |
440 | ::close( proc->socketStdin ); | 440 | ::close( proc->socketStdin ); |
441 | ::close( proc->socketStdout ); | 441 | ::close( proc->socketStdout ); |
442 | ::close( proc->socketStderr ); | 442 | ::close( proc->socketStderr ); |
443 | } | 443 | } |
444 | } | 444 | } |
445 | } | 445 | } |
446 | 446 | ||
@@ -448,8 +448,8 @@ void QProcessPrivate::newProc( pid_t pid, QProcess *process ) | |||
448 | { | 448 | { |
449 | proc = new QProc( pid, process ); | 449 | proc = new QProc( pid, process ); |
450 | if ( procManager == 0 ) { | 450 | if ( procManager == 0 ) { |
451 | procManager = new QProcessManager; | 451 | procManager = new QProcessManager; |
452 | qprocess_cleanup_procmanager.add( &procManager ); | 452 | qprocess_cleanup_procmanager.add( &procManager ); |
453 | } | 453 | } |
454 | // the QProcessManager takes care of deleting the QProc instances | 454 | // the QProcessManager takes care of deleting the QProc instances |
455 | procManager->append( proc ); | 455 | procManager->append( proc ); |
@@ -463,9 +463,9 @@ void QProcessPrivate::newProc( pid_t pid, QProcess *process ) | |||
463 | QT_SIGNAL_RETTYPE qt_C_sigchldHnd( QT_SIGNAL_ARGS ) | 463 | QT_SIGNAL_RETTYPE qt_C_sigchldHnd( QT_SIGNAL_ARGS ) |
464 | { | 464 | { |
465 | if ( QProcessPrivate::procManager == 0 ) | 465 | if ( QProcessPrivate::procManager == 0 ) |
466 | return; | 466 | return; |
467 | if ( QProcessPrivate::procManager->sigchldFd[0] == 0 ) | 467 | if ( QProcessPrivate::procManager->sigchldFd[0] == 0 ) |
468 | return; | 468 | return; |
469 | 469 | ||
470 | char a = 1; | 470 | char a = 1; |
471 | ::write( QProcessPrivate::procManager->sigchldFd[0], &a, sizeof(a) ); | 471 | ::write( QProcessPrivate::procManager->sigchldFd[0], &a, sizeof(a) ); |
@@ -508,9 +508,9 @@ void QProcess::reset() | |||
508 | QByteArray* QProcess::bufStdout() | 508 | QByteArray* QProcess::bufStdout() |
509 | { | 509 | { |
510 | if ( d->proc && d->proc->socketStdout ) { | 510 | if ( d->proc && d->proc->socketStdout ) { |
511 | // ### can this cause a blocking behaviour (maybe do a ioctl() to see | 511 | // ### can this cause a blocking behaviour (maybe do a ioctl() to see |
512 | // if data is available)? | 512 | // if data is available)? |
513 | socketRead( d->proc->socketStdout ); | 513 | socketRead( d->proc->socketStdout ); |
514 | } | 514 | } |
515 | return &d->bufStdout; | 515 | return &d->bufStdout; |
516 | } | 516 | } |
@@ -518,9 +518,9 @@ QByteArray* QProcess::bufStdout() | |||
518 | QByteArray* QProcess::bufStderr() | 518 | QByteArray* QProcess::bufStderr() |
519 | { | 519 | { |
520 | if ( d->proc && d->proc->socketStderr ) { | 520 | if ( d->proc && d->proc->socketStderr ) { |
521 | // ### can this cause a blocking behaviour (maybe do a ioctl() to see | 521 | // ### can this cause a blocking behaviour (maybe do a ioctl() to see |
522 | // if data is available)? | 522 | // if data is available)? |
523 | socketRead( d->proc->socketStderr ); | 523 | socketRead( d->proc->socketStderr ); |
524 | } | 524 | } |
525 | return &d->bufStderr; | 525 | return &d->bufStderr; |
526 | } | 526 | } |
@@ -529,11 +529,11 @@ void QProcess::consumeBufStdout( int consume ) | |||
529 | { | 529 | { |
530 | uint n = d->bufStdout.size(); | 530 | uint n = d->bufStdout.size(); |
531 | if ( consume==-1 || (uint)consume >= n ) { | 531 | if ( consume==-1 || (uint)consume >= n ) { |
532 | d->bufStdout.resize( 0 ); | 532 | d->bufStdout.resize( 0 ); |
533 | } else { | 533 | } else { |
534 | QByteArray tmp( n - consume ); | 534 | QByteArray tmp( n - consume ); |
535 | memcpy( tmp.data(), d->bufStdout.data()+consume, n-consume ); | 535 | memcpy( tmp.data(), d->bufStdout.data()+consume, n-consume ); |
536 | d->bufStdout = tmp; | 536 | d->bufStdout = tmp; |
537 | } | 537 | } |
538 | } | 538 | } |
539 | 539 | ||
@@ -541,11 +541,11 @@ void QProcess::consumeBufStderr( int consume ) | |||
541 | { | 541 | { |
542 | uint n = d->bufStderr.size(); | 542 | uint n = d->bufStderr.size(); |
543 | if ( consume==-1 || (uint)consume >= n ) { | 543 | if ( consume==-1 || (uint)consume >= n ) { |
544 | d->bufStderr.resize( 0 ); | 544 | d->bufStderr.resize( 0 ); |
545 | } else { | 545 | } else { |
546 | QByteArray tmp( n - consume ); | 546 | QByteArray tmp( n - consume ); |
547 | memcpy( tmp.data(), d->bufStderr.data()+consume, n-consume ); | 547 | memcpy( tmp.data(), d->bufStderr.data()+consume, n-consume ); |
548 | d->bufStderr = tmp; | 548 | d->bufStderr = tmp; |
549 | } | 549 | } |
550 | } | 550 | } |
551 | 551 | ||
@@ -608,22 +608,22 @@ bool QProcess::start( QStringList *env ) | |||
608 | 608 | ||
609 | // open sockets for piping | 609 | // open sockets for piping |
610 | if ( (comms & Stdin) && ::socketpair( AF_UNIX, SOCK_STREAM, 0, sStdin ) == -1 ) { | 610 | if ( (comms & Stdin) && ::socketpair( AF_UNIX, SOCK_STREAM, 0, sStdin ) == -1 ) { |
611 | return FALSE; | 611 | return FALSE; |
612 | } | 612 | } |
613 | if ( (comms & Stderr) && ::socketpair( AF_UNIX, SOCK_STREAM, 0, sStderr ) == -1 ) { | 613 | if ( (comms & Stderr) && ::socketpair( AF_UNIX, SOCK_STREAM, 0, sStderr ) == -1 ) { |
614 | return FALSE; | 614 | return FALSE; |
615 | } | 615 | } |
616 | if ( (comms & Stdout) && ::socketpair( AF_UNIX, SOCK_STREAM, 0, sStdout ) == -1 ) { | 616 | if ( (comms & Stdout) && ::socketpair( AF_UNIX, SOCK_STREAM, 0, sStdout ) == -1 ) { |
617 | return FALSE; | 617 | return FALSE; |
618 | } | 618 | } |
619 | 619 | ||
620 | // the following pipe is only used to determine if the process could be | 620 | // the following pipe is only used to determine if the process could be |
621 | // started | 621 | // started |
622 | int fd[2]; | 622 | int fd[2]; |
623 | if ( pipe( fd ) < 0 ) { | 623 | if ( pipe( fd ) < 0 ) { |
624 | // non critical error, go on | 624 | // non critical error, go on |
625 | fd[0] = 0; | 625 | fd[0] = 0; |
626 | fd[1] = 0; | 626 | fd[1] = 0; |
627 | } | 627 | } |
628 | 628 | ||
629 | // construct the arguments for exec | 629 | // construct the arguments for exec |
@@ -631,164 +631,164 @@ bool QProcess::start( QStringList *env ) | |||
631 | const char** arglist = new const char*[ _arguments.count() + 1 ]; | 631 | const char** arglist = new const char*[ _arguments.count() + 1 ]; |
632 | int i = 0; | 632 | int i = 0; |
633 | for ( QStringList::Iterator it = _arguments.begin(); it != _arguments.end(); ++it ) { | 633 | for ( QStringList::Iterator it = _arguments.begin(); it != _arguments.end(); ++it ) { |
634 | arglistQ[i] = (*it).local8Bit(); | 634 | arglistQ[i] = (*it).local8Bit(); |
635 | arglist[i] = arglistQ[i]; | 635 | arglist[i] = arglistQ[i]; |
636 | #if defined(QT_QPROCESS_DEBUG) | 636 | #if defined(QT_QPROCESS_DEBUG) |
637 | odebug << "QProcess::start(): arg " << i << " = " << arglist[i] << "" << oendl; | 637 | odebug << "QProcess::start(): arg " << i << " = " << arglist[i] << "" << oendl; |
638 | #endif | 638 | #endif |
639 | i++; | 639 | i++; |
640 | } | 640 | } |
641 | arglist[i] = 0; | 641 | arglist[i] = 0; |
642 | 642 | ||
643 | // Must make sure signal handlers are installed before exec'ing | 643 | // Must make sure signal handlers are installed before exec'ing |
644 | // in case the process exits quickly. | 644 | // in case the process exits quickly. |
645 | if ( d->procManager == 0 ) { | 645 | if ( d->procManager == 0 ) { |
646 | d->procManager = new QProcessManager; | 646 | d->procManager = new QProcessManager; |
647 | qprocess_cleanup_procmanager.add( &d->procManager ); | 647 | qprocess_cleanup_procmanager.add( &d->procManager ); |
648 | } | 648 | } |
649 | 649 | ||
650 | // fork and exec | 650 | // fork and exec |
651 | QApplication::flushX(); | 651 | QApplication::flushX(); |
652 | pid_t pid = fork(); | 652 | pid_t pid = fork(); |
653 | if ( pid == 0 ) { | 653 | if ( pid == 0 ) { |
654 | // child | 654 | // child |
655 | d->closeOpenSocketsForChild(); | 655 | d->closeOpenSocketsForChild(); |
656 | if ( comms & Stdin ) { | 656 | if ( comms & Stdin ) { |
657 | ::close( sStdin[1] ); | 657 | ::close( sStdin[1] ); |
658 | ::dup2( sStdin[0], STDIN_FILENO ); | 658 | ::dup2( sStdin[0], STDIN_FILENO ); |
659 | } | 659 | } |
660 | if ( comms & Stdout ) { | 660 | if ( comms & Stdout ) { |
661 | ::close( sStdout[0] ); | 661 | ::close( sStdout[0] ); |
662 | ::dup2( sStdout[1], STDOUT_FILENO ); | 662 | ::dup2( sStdout[1], STDOUT_FILENO ); |
663 | } | 663 | } |
664 | if ( comms & Stderr ) { | 664 | if ( comms & Stderr ) { |
665 | ::close( sStderr[0] ); | 665 | ::close( sStderr[0] ); |
666 | ::dup2( sStderr[1], STDERR_FILENO ); | 666 | ::dup2( sStderr[1], STDERR_FILENO ); |
667 | } | 667 | } |
668 | if ( comms & DupStderr ) { | 668 | if ( comms & DupStderr ) { |
669 | ::dup2( STDOUT_FILENO, STDERR_FILENO ); | 669 | ::dup2( STDOUT_FILENO, STDERR_FILENO ); |
670 | } | 670 | } |
671 | #ifndef QT_NO_DIR | 671 | #ifndef QT_NO_DIR |
672 | ::chdir( workingDir.absPath().latin1() ); | 672 | ::chdir( workingDir.absPath().latin1() ); |
673 | #endif | 673 | #endif |
674 | if ( fd[0] ) | 674 | if ( fd[0] ) |
675 | ::close( fd[0] ); | 675 | ::close( fd[0] ); |
676 | if ( fd[1] ) | 676 | if ( fd[1] ) |
677 | ::fcntl( fd[1], F_SETFD, FD_CLOEXEC ); // close on exec shows sucess | 677 | ::fcntl( fd[1], F_SETFD, FD_CLOEXEC ); // close on exec shows sucess |
678 | 678 | ||
679 | if ( env == 0 ) { // inherit environment and start process | 679 | if ( env == 0 ) { // inherit environment and start process |
680 | ::execvp( arglist[0], (char*const*)arglist ); // ### cast not nice | 680 | ::execvp( arglist[0], (char*const*)arglist ); // ### cast not nice |
681 | } else { // start process with environment settins as specified in env | 681 | } else { // start process with environment settins as specified in env |
682 | // construct the environment for exec | 682 | // construct the environment for exec |
683 | int numEntries = env->count(); | 683 | int numEntries = env->count(); |
684 | bool setLibraryPath = | 684 | bool setLibraryPath = |
685 | env->grep( QRegExp( "^LD_LIBRARY_PATH=" ) ).isEmpty() && | 685 | env->grep( QRegExp( "^LD_LIBRARY_PATH=" ) ).isEmpty() && |
686 | getenv( "LD_LIBRARY_PATH" ) != 0; | 686 | getenv( "LD_LIBRARY_PATH" ) != 0; |
687 | if ( setLibraryPath ) | 687 | if ( setLibraryPath ) |
688 | numEntries++; | 688 | numEntries++; |
689 | QCString *envlistQ = new QCString[ numEntries + 1 ]; | 689 | QCString *envlistQ = new QCString[ numEntries + 1 ]; |
690 | const char** envlist = new const char*[ numEntries + 1 ]; | 690 | const char** envlist = new const char*[ numEntries + 1 ]; |
691 | int i = 0; | 691 | int i = 0; |
692 | if ( setLibraryPath ) { | 692 | if ( setLibraryPath ) { |
693 | envlistQ[i] = QString( "LD_LIBRARY_PATH=%1" ).arg( getenv( "LD_LIBRARY_PATH" ) ).local8Bit(); | 693 | envlistQ[i] = QString( "LD_LIBRARY_PATH=%1" ).arg( getenv( "LD_LIBRARY_PATH" ) ).local8Bit(); |
694 | envlist[i] = envlistQ[i]; | 694 | envlist[i] = envlistQ[i]; |
695 | i++; | 695 | i++; |
696 | } | 696 | } |
697 | for ( QStringList::Iterator it = env->begin(); it != env->end(); ++it ) { | 697 | for ( QStringList::Iterator it = env->begin(); it != env->end(); ++it ) { |
698 | envlistQ[i] = (*it).local8Bit(); | 698 | envlistQ[i] = (*it).local8Bit(); |
699 | envlist[i] = envlistQ[i]; | 699 | envlist[i] = envlistQ[i]; |
700 | i++; | 700 | i++; |
701 | } | 701 | } |
702 | envlist[i] = 0; | 702 | envlist[i] = 0; |
703 | 703 | ||
704 | // look for the executable in the search path | 704 | // look for the executable in the search path |
705 | if ( _arguments.count()>0 && getenv("PATH")!=0 ) { | 705 | if ( _arguments.count()>0 && getenv("PATH")!=0 ) { |
706 | QString command = _arguments[0]; | 706 | QString command = _arguments[0]; |
707 | if ( !command.contains( '/' ) ) { | 707 | if ( !command.contains( '/' ) ) { |
708 | QStringList pathList = QStringList::split( ':', getenv( "PATH" ) ); | 708 | QStringList pathList = QStringList::split( ':', getenv( "PATH" ) ); |
709 | for (QStringList::Iterator it = pathList.begin(); it != pathList.end(); ++it ) { | 709 | for (QStringList::Iterator it = pathList.begin(); it != pathList.end(); ++it ) { |
710 | QString dir = *it; | 710 | QString dir = *it; |
711 | #ifdef Q_OS_MACX | 711 | #ifdef Q_OS_MACX |
712 | if(QFile::exists(dir + "/" + command + ".app")) //look in a bundle | 712 | if(QFile::exists(dir + "/" + command + ".app")) //look in a bundle |
713 | dir += "/" + command + ".app/Contents/MacOS"; | 713 | dir += "/" + command + ".app/Contents/MacOS"; |
714 | #endif | 714 | #endif |
715 | #ifndef QT_NO_DIR | 715 | #ifndef QT_NO_DIR |
716 | QFileInfo fileInfo( dir, command ); | 716 | QFileInfo fileInfo( dir, command ); |
717 | #else | 717 | #else |
718 | QFileInfo fileInfo( dir + "/" + command ); | 718 | QFileInfo fileInfo( dir + "/" + command ); |
719 | #endif | 719 | #endif |
720 | if ( fileInfo.isExecutable() ) { | 720 | if ( fileInfo.isExecutable() ) { |
721 | arglistQ[0] = fileInfo.filePath().local8Bit(); | 721 | arglistQ[0] = fileInfo.filePath().local8Bit(); |
722 | arglist[0] = arglistQ[0]; | 722 | arglist[0] = arglistQ[0]; |
723 | break; | 723 | break; |
724 | } | 724 | } |
725 | } | 725 | } |
726 | } | 726 | } |
727 | } | 727 | } |
728 | ::execve( arglist[0], (char*const*)arglist, (char*const*)envlist ); // ### casts not nice | 728 | ::execve( arglist[0], (char*const*)arglist, (char*const*)envlist ); // ### casts not nice |
729 | } | 729 | } |
730 | if ( fd[1] ) { | 730 | if ( fd[1] ) { |
731 | char buf = 0; | 731 | char buf = 0; |
732 | ::write( fd[1], &buf, 1 ); | 732 | ::write( fd[1], &buf, 1 ); |
733 | ::close( fd[1] ); | 733 | ::close( fd[1] ); |
734 | } | 734 | } |
735 | ::exit( -1 ); | 735 | ::exit( -1 ); |
736 | } else if ( pid == -1 ) { | 736 | } else if ( pid == -1 ) { |
737 | // error forking | 737 | // error forking |
738 | goto error; | 738 | goto error; |
739 | } | 739 | } |
740 | 740 | ||
741 | // test if exec was successful | 741 | // test if exec was successful |
742 | if ( fd[1] ) | 742 | if ( fd[1] ) |
743 | ::close( fd[1] ); | 743 | ::close( fd[1] ); |
744 | if ( fd[0] ) { | 744 | if ( fd[0] ) { |
745 | char buf; | 745 | char buf; |
746 | for ( ;; ) { | 746 | for ( ;; ) { |
747 | int n = ::read( fd[0], &buf, 1 ); | 747 | int n = ::read( fd[0], &buf, 1 ); |
748 | if ( n==1 ) { | 748 | if ( n==1 ) { |
749 | // socket was not closed => error | 749 | // socket was not closed => error |
750 | d->proc = 0; | 750 | d->proc = 0; |
751 | goto error; | 751 | goto error; |
752 | } else if ( n==-1 ) { | 752 | } else if ( n==-1 ) { |
753 | if ( errno==EAGAIN || errno==EINTR ) | 753 | if ( errno==EAGAIN || errno==EINTR ) |
754 | // try it again | 754 | // try it again |
755 | continue; | 755 | continue; |
756 | } | 756 | } |
757 | break; | 757 | break; |
758 | } | 758 | } |
759 | ::close( fd[0] ); | 759 | ::close( fd[0] ); |
760 | } | 760 | } |
761 | 761 | ||
762 | d->newProc( pid, this ); | 762 | d->newProc( pid, this ); |
763 | 763 | ||
764 | if ( comms & Stdin ) { | 764 | if ( comms & Stdin ) { |
765 | ::close( sStdin[0] ); | 765 | ::close( sStdin[0] ); |
766 | d->proc->socketStdin = sStdin[1]; | 766 | d->proc->socketStdin = sStdin[1]; |
767 | d->notifierStdin = new QSocketNotifier( sStdin[1], QSocketNotifier::Write ); | 767 | d->notifierStdin = new QSocketNotifier( sStdin[1], QSocketNotifier::Write ); |
768 | connect( d->notifierStdin, SIGNAL(activated(int)), | 768 | connect( d->notifierStdin, SIGNAL(activated(int)), |
769 | this, SLOT(socketWrite(int)) ); | 769 | this, SLOT(socketWrite(int)) ); |
770 | // setup notifiers for the sockets | 770 | // setup notifiers for the sockets |
771 | if ( !d->stdinBuf.isEmpty() ) { | 771 | if ( !d->stdinBuf.isEmpty() ) { |
772 | d->notifierStdin->setEnabled( TRUE ); | 772 | d->notifierStdin->setEnabled( TRUE ); |
773 | } | 773 | } |
774 | } | 774 | } |
775 | if ( comms & Stdout ) { | 775 | if ( comms & Stdout ) { |
776 | ::close( sStdout[1] ); | 776 | ::close( sStdout[1] ); |
777 | d->proc->socketStdout = sStdout[0]; | 777 | d->proc->socketStdout = sStdout[0]; |
778 | d->notifierStdout = new QSocketNotifier( sStdout[0], QSocketNotifier::Read ); | 778 | d->notifierStdout = new QSocketNotifier( sStdout[0], QSocketNotifier::Read ); |
779 | connect( d->notifierStdout, SIGNAL(activated(int)), | 779 | connect( d->notifierStdout, SIGNAL(activated(int)), |
780 | this, SLOT(socketRead(int)) ); | 780 | this, SLOT(socketRead(int)) ); |
781 | if ( ioRedirection ) | 781 | if ( ioRedirection ) |
782 | d->notifierStdout->setEnabled( TRUE ); | 782 | d->notifierStdout->setEnabled( TRUE ); |
783 | } | 783 | } |
784 | if ( comms & Stderr ) { | 784 | if ( comms & Stderr ) { |
785 | ::close( sStderr[1] ); | 785 | ::close( sStderr[1] ); |
786 | d->proc->socketStderr = sStderr[0]; | 786 | d->proc->socketStderr = sStderr[0]; |
787 | d->notifierStderr = new QSocketNotifier( sStderr[0], QSocketNotifier::Read ); | 787 | d->notifierStderr = new QSocketNotifier( sStderr[0], QSocketNotifier::Read ); |
788 | connect( d->notifierStderr, SIGNAL(activated(int)), | 788 | connect( d->notifierStderr, SIGNAL(activated(int)), |
789 | this, SLOT(socketRead(int)) ); | 789 | this, SLOT(socketRead(int)) ); |
790 | if ( ioRedirection ) | 790 | if ( ioRedirection ) |
791 | d->notifierStderr->setEnabled( TRUE ); | 791 | d->notifierStderr->setEnabled( TRUE ); |
792 | } | 792 | } |
793 | 793 | ||
794 | // cleanup and return | 794 | // cleanup and return |
@@ -801,18 +801,18 @@ error: | |||
801 | odebug << "QProcess::start(): error starting process" << oendl; | 801 | odebug << "QProcess::start(): error starting process" << oendl; |
802 | #endif | 802 | #endif |
803 | if ( d->procManager ) | 803 | if ( d->procManager ) |
804 | d->procManager->cleanup(); | 804 | d->procManager->cleanup(); |
805 | if ( comms & Stdin ) { | 805 | if ( comms & Stdin ) { |
806 | ::close( sStdin[1] ); | 806 | ::close( sStdin[1] ); |
807 | ::close( sStdin[0] ); | 807 | ::close( sStdin[0] ); |
808 | } | 808 | } |
809 | if ( comms & Stdout ) { | 809 | if ( comms & Stdout ) { |
810 | ::close( sStdout[0] ); | 810 | ::close( sStdout[0] ); |
811 | ::close( sStdout[1] ); | 811 | ::close( sStdout[1] ); |
812 | } | 812 | } |
813 | if ( comms & Stderr ) { | 813 | if ( comms & Stderr ) { |
814 | ::close( sStderr[0] ); | 814 | ::close( sStderr[0] ); |
815 | ::close( sStderr[1] ); | 815 | ::close( sStderr[1] ); |
816 | } | 816 | } |
817 | ::close( fd[0] ); | 817 | ::close( fd[0] ); |
818 | ::close( fd[1] ); | 818 | ::close( fd[1] ); |
@@ -835,7 +835,7 @@ error: | |||
835 | void QProcess::tryTerminate() const | 835 | void QProcess::tryTerminate() const |
836 | { | 836 | { |
837 | if ( d->proc != 0 ) | 837 | if ( d->proc != 0 ) |
838 | ::kill( d->proc->pid, SIGTERM ); | 838 | ::kill( d->proc->pid, SIGTERM ); |
839 | } | 839 | } |
840 | 840 | ||
841 | /*! | 841 | /*! |
@@ -865,7 +865,7 @@ void QProcess::tryTerminate() const | |||
865 | void QProcess::kill() const | 865 | void QProcess::kill() const |
866 | { | 866 | { |
867 | if ( d->proc != 0 ) | 867 | if ( d->proc != 0 ) |
868 | ::kill( d->proc->pid, SIGKILL ); | 868 | ::kill( d->proc->pid, SIGKILL ); |
869 | } | 869 | } |
870 | 870 | ||
871 | /*! | 871 | /*! |
@@ -879,24 +879,24 @@ bool QProcess::isRunning() const | |||
879 | #if defined(QT_QPROCESS_DEBUG) | 879 | #if defined(QT_QPROCESS_DEBUG) |
880 | odebug << "QProcess::isRunning(): FALSE (already computed)" << oendl; | 880 | odebug << "QProcess::isRunning(): FALSE (already computed)" << oendl; |
881 | #endif | 881 | #endif |
882 | return FALSE; | 882 | return FALSE; |
883 | } | 883 | } |
884 | if ( d->proc == 0 ) | 884 | if ( d->proc == 0 ) |
885 | return FALSE; | 885 | return FALSE; |
886 | int status; | 886 | int status; |
887 | if ( ::waitpid( d->proc->pid, &status, WNOHANG ) == d->proc->pid ) | 887 | if ( ::waitpid( d->proc->pid, &status, WNOHANG ) == d->proc->pid ) |
888 | { | 888 | { |
889 | // compute the exit values | 889 | // compute the exit values |
890 | QProcess *that = (QProcess*)this; // mutable | 890 | QProcess *that = (QProcess*)this; // mutable |
891 | that->exitNormal = WIFEXITED( status ) != 0; | 891 | that->exitNormal = WIFEXITED( status ) != 0; |
892 | if ( exitNormal ) { | 892 | if ( exitNormal ) { |
893 | that->exitStat = (char)WEXITSTATUS( status ); | 893 | that->exitStat = (char)WEXITSTATUS( status ); |
894 | } | 894 | } |
895 | d->exitValuesCalculated = TRUE; | 895 | d->exitValuesCalculated = TRUE; |
896 | #if defined(QT_QPROCESS_DEBUG) | 896 | #if defined(QT_QPROCESS_DEBUG) |
897 | odebug << "QProcess::isRunning() (PID: " << d->proc->pid << "): FALSE" << oendl; | 897 | odebug << "QProcess::isRunning() (PID: " << d->proc->pid << "): FALSE" << oendl; |
898 | #endif | 898 | #endif |
899 | return FALSE; | 899 | return FALSE; |
900 | } | 900 | } |
901 | #if defined(QT_QPROCESS_DEBUG) | 901 | #if defined(QT_QPROCESS_DEBUG) |
902 | odebug << "QProcess::isRunning() (PID: " << d->proc->pid << "): TRUE" << oendl; | 902 | odebug << "QProcess::isRunning() (PID: " << d->proc->pid << "): TRUE" << oendl; |
@@ -923,7 +923,7 @@ void QProcess::writeToStdin( const QByteArray& buf ) | |||
923 | #endif | 923 | #endif |
924 | d->stdinBuf.enqueue( new QByteArray(buf) ); | 924 | d->stdinBuf.enqueue( new QByteArray(buf) ); |
925 | if ( d->notifierStdin != 0 ) | 925 | if ( d->notifierStdin != 0 ) |
926 | d->notifierStdin->setEnabled( TRUE ); | 926 | d->notifierStdin->setEnabled( TRUE ); |
927 | } | 927 | } |
928 | 928 | ||
929 | 929 | ||
@@ -938,20 +938,20 @@ void QProcess::writeToStdin( const QByteArray& buf ) | |||
938 | void QProcess::closeStdin() | 938 | void QProcess::closeStdin() |
939 | { | 939 | { |
940 | if ( d->proc == 0 ) | 940 | if ( d->proc == 0 ) |
941 | return; | 941 | return; |
942 | if ( d->proc->socketStdin !=0 ) { | 942 | if ( d->proc->socketStdin !=0 ) { |
943 | while ( !d->stdinBuf.isEmpty() ) { | 943 | while ( !d->stdinBuf.isEmpty() ) { |
944 | delete d->stdinBuf.dequeue(); | 944 | delete d->stdinBuf.dequeue(); |
945 | } | 945 | } |
946 | delete d->notifierStdin; | 946 | delete d->notifierStdin; |
947 | d->notifierStdin = 0; | 947 | d->notifierStdin = 0; |
948 | if ( ::close( d->proc->socketStdin ) != 0 ) { | 948 | if ( ::close( d->proc->socketStdin ) != 0 ) { |
949 | owarn << "Could not close stdin of child process" << oendl; | 949 | owarn << "Could not close stdin of child process" << oendl; |
950 | } | 950 | } |
951 | #if defined(QT_QPROCESS_DEBUG) | 951 | #if defined(QT_QPROCESS_DEBUG) |
952 | odebug << "QProcess::closeStdin(): stdin (" << d->proc->socketStdin << ") closed" << oendl; | 952 | odebug << "QProcess::closeStdin(): stdin (" << d->proc->socketStdin << ") closed" << oendl; |
953 | #endif | 953 | #endif |
954 | d->proc->socketStdin = 0; | 954 | d->proc->socketStdin = 0; |
955 | } | 955 | } |
956 | } | 956 | } |
957 | 957 | ||
@@ -963,27 +963,27 @@ void QProcess::closeStdin() | |||
963 | void QProcess::socketRead( int fd ) | 963 | void QProcess::socketRead( int fd ) |
964 | { | 964 | { |
965 | if ( d->socketReadCalled ) { | 965 | if ( d->socketReadCalled ) { |
966 | // the slots that are connected to the readyRead...() signals might | 966 | // the slots that are connected to the readyRead...() signals might |
967 | // trigger a recursive call of socketRead(). Avoid this since you get a | 967 | // trigger a recursive call of socketRead(). Avoid this since you get a |
968 | // blocking read otherwise. | 968 | // blocking read otherwise. |
969 | return; | 969 | return; |
970 | } | 970 | } |
971 | #if defined(QT_QPROCESS_DEBUG) | 971 | #if defined(QT_QPROCESS_DEBUG) |
972 | odebug << "QProcess::socketRead(): " << fd << "" << oendl; | 972 | odebug << "QProcess::socketRead(): " << fd << "" << oendl; |
973 | #endif | 973 | #endif |
974 | if ( fd == 0 ) | 974 | if ( fd == 0 ) |
975 | return; | 975 | return; |
976 | const int bufsize = 4096; | 976 | const int bufsize = 4096; |
977 | QByteArray *buffer = 0; | 977 | QByteArray *buffer = 0; |
978 | uint oldSize; | 978 | uint oldSize; |
979 | int n; | 979 | int n; |
980 | if ( fd == d->proc->socketStdout ) { | 980 | if ( fd == d->proc->socketStdout ) { |
981 | buffer = &d->bufStdout; | 981 | buffer = &d->bufStdout; |
982 | } else if ( fd == d->proc->socketStderr ) { | 982 | } else if ( fd == d->proc->socketStderr ) { |
983 | buffer = &d->bufStderr; | 983 | buffer = &d->bufStderr; |
984 | } else { | 984 | } else { |
985 | // this case should never happen, but just to be safe | 985 | // this case should never happen, but just to be safe |
986 | return; | 986 | return; |
987 | } | 987 | } |
988 | 988 | ||
989 | // read data | 989 | // read data |
@@ -991,57 +991,57 @@ void QProcess::socketRead( int fd ) | |||
991 | buffer->resize( oldSize + bufsize ); | 991 | buffer->resize( oldSize + bufsize ); |
992 | n = ::read( fd, buffer->data()+oldSize, bufsize ); | 992 | n = ::read( fd, buffer->data()+oldSize, bufsize ); |
993 | if ( n > 0 ) | 993 | if ( n > 0 ) |
994 | buffer->resize( oldSize + n ); | 994 | buffer->resize( oldSize + n ); |
995 | else | 995 | else |
996 | buffer->resize( oldSize ); | 996 | buffer->resize( oldSize ); |
997 | // eof or error? | 997 | // eof or error? |
998 | if ( n == 0 || n == -1 ) { | 998 | if ( n == 0 || n == -1 ) { |
999 | if ( fd == d->proc->socketStdout ) { | 999 | if ( fd == d->proc->socketStdout ) { |
1000 | #if defined(QT_QPROCESS_DEBUG) | 1000 | #if defined(QT_QPROCESS_DEBUG) |
1001 | odebug << "QProcess::socketRead(): stdout (" << fd << ") closed" << oendl; | 1001 | odebug << "QProcess::socketRead(): stdout (" << fd << ") closed" << oendl; |
1002 | #endif | 1002 | #endif |
1003 | d->notifierStdout->setEnabled( FALSE ); | 1003 | d->notifierStdout->setEnabled( FALSE ); |
1004 | delete d->notifierStdout; | 1004 | delete d->notifierStdout; |
1005 | d->notifierStdout = 0; | 1005 | d->notifierStdout = 0; |
1006 | ::close( d->proc->socketStdout ); | 1006 | ::close( d->proc->socketStdout ); |
1007 | d->proc->socketStdout = 0; | 1007 | d->proc->socketStdout = 0; |
1008 | return; | 1008 | return; |
1009 | } else if ( fd == d->proc->socketStderr ) { | 1009 | } else if ( fd == d->proc->socketStderr ) { |
1010 | #if defined(QT_QPROCESS_DEBUG) | 1010 | #if defined(QT_QPROCESS_DEBUG) |
1011 | odebug << "QProcess::socketRead(): stderr (" << fd << ") closed" << oendl; | 1011 | odebug << "QProcess::socketRead(): stderr (" << fd << ") closed" << oendl; |
1012 | #endif | 1012 | #endif |
1013 | d->notifierStderr->setEnabled( FALSE ); | 1013 | d->notifierStderr->setEnabled( FALSE ); |
1014 | delete d->notifierStderr; | 1014 | delete d->notifierStderr; |
1015 | d->notifierStderr = 0; | 1015 | d->notifierStderr = 0; |
1016 | ::close( d->proc->socketStderr ); | 1016 | ::close( d->proc->socketStderr ); |
1017 | d->proc->socketStderr = 0; | 1017 | d->proc->socketStderr = 0; |
1018 | return; | 1018 | return; |
1019 | } | 1019 | } |
1020 | } | 1020 | } |
1021 | // read all data that is available | 1021 | // read all data that is available |
1022 | while ( n == bufsize ) { | 1022 | while ( n == bufsize ) { |
1023 | oldSize = buffer->size(); | 1023 | oldSize = buffer->size(); |
1024 | buffer->resize( oldSize + bufsize ); | 1024 | buffer->resize( oldSize + bufsize ); |
1025 | n = ::read( fd, buffer->data()+oldSize, bufsize ); | 1025 | n = ::read( fd, buffer->data()+oldSize, bufsize ); |
1026 | if ( n > 0 ) | 1026 | if ( n > 0 ) |
1027 | buffer->resize( oldSize + n ); | 1027 | buffer->resize( oldSize + n ); |
1028 | else | 1028 | else |
1029 | buffer->resize( oldSize ); | 1029 | buffer->resize( oldSize ); |
1030 | } | 1030 | } |
1031 | 1031 | ||
1032 | d->socketReadCalled = TRUE; | 1032 | d->socketReadCalled = TRUE; |
1033 | if ( fd == d->proc->socketStdout ) { | 1033 | if ( fd == d->proc->socketStdout ) { |
1034 | #if defined(QT_QPROCESS_DEBUG) | 1034 | #if defined(QT_QPROCESS_DEBUG) |
1035 | qDebug( "QProcess::socketRead(): %d bytes read from stdout (%d)", | 1035 | odebug << "QProcess::socketRead(): " << buffer->size()-oldSize << "bytes read from stdout (" |
1036 | buffer->size()-oldSize, fd ); | 1036 | << fd << ")" << oendl; |
1037 | #endif | 1037 | #endif |
1038 | emit readyReadStdout(); | 1038 | emit readyReadStdout(); |
1039 | } else if ( fd == d->proc->socketStderr ) { | 1039 | } else if ( fd == d->proc->socketStderr ) { |
1040 | #if defined(QT_QPROCESS_DEBUG) | 1040 | #if defined(QT_QPROCESS_DEBUG) |
1041 | qDebug( "QProcess::socketRead(): %d bytes read from stderr (%d)", | 1041 | odebug << "QProcess::socketRead(): " << buffer->size()-oldSize << " bytes read from stderr (" |
1042 | buffer->size()-oldSize, fd ); | 1042 | << fd << ")" << oendl; |
1043 | #endif | 1043 | #endif |
1044 | emit readyReadStderr(); | 1044 | emit readyReadStderr(); |
1045 | } | 1045 | } |
1046 | d->socketReadCalled = FALSE; | 1046 | d->socketReadCalled = FALSE; |
1047 | } | 1047 | } |
@@ -1054,25 +1054,25 @@ void QProcess::socketRead( int fd ) | |||
1054 | void QProcess::socketWrite( int fd ) | 1054 | void QProcess::socketWrite( int fd ) |
1055 | { | 1055 | { |
1056 | if ( fd != d->proc->socketStdin || d->proc->socketStdin == 0 ) | 1056 | if ( fd != d->proc->socketStdin || d->proc->socketStdin == 0 ) |
1057 | return; | 1057 | return; |
1058 | if ( d->stdinBuf.isEmpty() ) { | 1058 | if ( d->stdinBuf.isEmpty() ) { |
1059 | d->notifierStdin->setEnabled( FALSE ); | 1059 | d->notifierStdin->setEnabled( FALSE ); |
1060 | return; | 1060 | return; |
1061 | } | 1061 | } |
1062 | #if defined(QT_QPROCESS_DEBUG) | 1062 | #if defined(QT_QPROCESS_DEBUG) |
1063 | odebug << "QProcess::socketWrite(): write to stdin (" << fd << ")" << oendl; | 1063 | odebug << "QProcess::socketWrite(): write to stdin (" << fd << ")" << oendl; |
1064 | #endif | 1064 | #endif |
1065 | ssize_t ret = ::write( fd, | 1065 | ssize_t ret = ::write( fd, |
1066 | d->stdinBuf.head()->data() + d->stdinBufRead, | 1066 | d->stdinBuf.head()->data() + d->stdinBufRead, |
1067 | d->stdinBuf.head()->size() - d->stdinBufRead ); | 1067 | d->stdinBuf.head()->size() - d->stdinBufRead ); |
1068 | if ( ret > 0 ) | 1068 | if ( ret > 0 ) |
1069 | d->stdinBufRead += ret; | 1069 | d->stdinBufRead += ret; |
1070 | if ( d->stdinBufRead == (ssize_t)d->stdinBuf.head()->size() ) { | 1070 | if ( d->stdinBufRead == (ssize_t)d->stdinBuf.head()->size() ) { |
1071 | d->stdinBufRead = 0; | 1071 | d->stdinBufRead = 0; |
1072 | delete d->stdinBuf.dequeue(); | 1072 | delete d->stdinBuf.dequeue(); |
1073 | if ( wroteToStdinConnected && d->stdinBuf.isEmpty() ) | 1073 | if ( wroteToStdinConnected && d->stdinBuf.isEmpty() ) |
1074 | emit wroteToStdin(); | 1074 | emit wroteToStdin(); |
1075 | socketWrite( fd ); | 1075 | socketWrite( fd ); |
1076 | } | 1076 | } |
1077 | } | 1077 | } |
1078 | 1078 | ||
@@ -1105,15 +1105,15 @@ void QProcess::setIoRedirection( bool value ) | |||
1105 | { | 1105 | { |
1106 | ioRedirection = value; | 1106 | ioRedirection = value; |
1107 | if ( ioRedirection ) { | 1107 | if ( ioRedirection ) { |
1108 | if ( d->notifierStdout ) | 1108 | if ( d->notifierStdout ) |
1109 | d->notifierStdout->setEnabled( TRUE ); | 1109 | d->notifierStdout->setEnabled( TRUE ); |
1110 | if ( d->notifierStderr ) | 1110 | if ( d->notifierStderr ) |
1111 | d->notifierStderr->setEnabled( TRUE ); | 1111 | d->notifierStderr->setEnabled( TRUE ); |
1112 | } else { | 1112 | } else { |
1113 | if ( d->notifierStdout ) | 1113 | if ( d->notifierStdout ) |
1114 | d->notifierStdout->setEnabled( FALSE ); | 1114 | d->notifierStdout->setEnabled( FALSE ); |
1115 | if ( d->notifierStderr ) | 1115 | if ( d->notifierStderr ) |
1116 | d->notifierStderr->setEnabled( FALSE ); | 1116 | d->notifierStderr->setEnabled( FALSE ); |
1117 | } | 1117 | } |
1118 | } | 1118 | } |
1119 | 1119 | ||
@@ -1152,21 +1152,21 @@ void QProcess::setWroteStdinConnected( bool value ) | |||
1152 | QProcess::PID QProcess::processIdentifier() | 1152 | QProcess::PID QProcess::processIdentifier() |
1153 | { | 1153 | { |
1154 | if ( d->proc == 0 ) | 1154 | if ( d->proc == 0 ) |
1155 | return -1; | 1155 | return -1; |
1156 | return d->proc->pid; | 1156 | return d->proc->pid; |
1157 | } | 1157 | } |
1158 | 1158 | ||
1159 | int QProcess::priority() const | 1159 | int QProcess::priority() const |
1160 | { | 1160 | { |
1161 | if ( d->proc ) | 1161 | if ( d->proc ) |
1162 | return getpriority(PRIO_PROCESS,d->proc->pid); | 1162 | return getpriority(PRIO_PROCESS,d->proc->pid); |
1163 | return 0; | 1163 | return 0; |
1164 | } | 1164 | } |
1165 | 1165 | ||
1166 | void QProcess::setPriority(int p) | 1166 | void QProcess::setPriority(int p) |
1167 | { | 1167 | { |
1168 | if ( d->proc ) | 1168 | if ( d->proc ) |
1169 | setpriority(PRIO_PROCESS,d->proc->pid,p); | 1169 | setpriority(PRIO_PROCESS,d->proc->pid,p); |
1170 | } | 1170 | } |
1171 | 1171 | ||
1172 | 1172 | ||