@@ -300,9 +300,12 @@ public function restart($callback = null)
300300 *
301301 * @throws RuntimeException When process timed out
302302 * @throws RuntimeException When process stopped after receiving signal
303+ * @throws LogicException When process is not yet started
303304 */
304305 public function wait ($ callback = null )
305306 {
307+ $ this ->requireProcessIsStarted (__FUNCTION__ );
308+
306309 $ this ->updateStatus (false );
307310 if (null !== $ callback ) {
308311 $ this ->callback = $ this ->buildCallback ($ callback );
@@ -370,10 +373,14 @@ public function signal($signal)
370373 *
371374 * @return string The process output
372375 *
376+ * @throws LogicException In case the process is not started
377+ *
373378 * @api
374379 */
375380 public function getOutput ()
376381 {
382+ $ this ->requireProcessIsStarted (__FUNCTION__ );
383+
377384 $ this ->readPipes (false , defined ('PHP_WINDOWS_VERSION_BUILD ' ) ? !$ this ->processInformation ['running ' ] : true );
378385
379386 return $ this ->stdout ;
@@ -385,10 +392,14 @@ public function getOutput()
385392 * In comparison with the getOutput method which always return the whole
386393 * output, this one returns the new output since the last call.
387394 *
395+ * @throws LogicException In case the process is not started
396+ *
388397 * @return string The process output since the last call
389398 */
390399 public function getIncrementalOutput ()
391400 {
401+ $ this ->requireProcessIsStarted (__FUNCTION__ );
402+
392403 $ data = $ this ->getOutput ();
393404
394405 $ latest = substr ($ data , $ this ->incrementalOutputOffset );
@@ -402,10 +413,14 @@ public function getIncrementalOutput()
402413 *
403414 * @return string The process error output
404415 *
416+ * @throws LogicException In case the process is not started
417+ *
405418 * @api
406419 */
407420 public function getErrorOutput ()
408421 {
422+ $ this ->requireProcessIsStarted (__FUNCTION__ );
423+
409424 $ this ->readPipes (false , defined ('PHP_WINDOWS_VERSION_BUILD ' ) ? !$ this ->processInformation ['running ' ] : true );
410425
411426 return $ this ->stderr ;
@@ -418,10 +433,14 @@ public function getErrorOutput()
418433 * whole error output, this one returns the new error output since the last
419434 * call.
420435 *
436+ * @throws LogicException In case the process is not started
437+ *
421438 * @return string The process error output since the last call
422439 */
423440 public function getIncrementalErrorOutput ()
424441 {
442+ $ this ->requireProcessIsStarted (__FUNCTION__ );
443+
425444 $ data = $ this ->getErrorOutput ();
426445
427446 $ latest = substr ($ data , $ this ->incrementalErrorOutputOffset );
@@ -433,7 +452,7 @@ public function getIncrementalErrorOutput()
433452 /**
434453 * Returns the exit code returned by the process.
435454 *
436- * @return integer The exit status code
455+ * @return null| integer The exit status code, null if the Process is not terminated
437456 *
438457 * @throws RuntimeException In case --enable-sigchild is activated and the sigchild compatibility mode is disabled
439458 *
@@ -456,14 +475,18 @@ public function getExitCode()
456475 * This method relies on the Unix exit code status standardization
457476 * and might not be relevant for other operating systems.
458477 *
459- * @return string A string representation for the exit status code
478+ * @return null|string A string representation for the exit status code, null if the Process is not terminated.
479+ *
480+ * @throws RuntimeException In case --enable-sigchild is activated and the sigchild compatibility mode is disabled
460481 *
461482 * @see http://tldp.org/LDP/abs/html/exitcodes.html
462483 * @see http://en.wikipedia.org/wiki/Unix_signal
463484 */
464485 public function getExitCodeText ()
465486 {
466- $ exitcode = $ this ->getExitCode ();
487+ if (null === $ exitcode = $ this ->getExitCode ()) {
488+ return ;
489+ }
467490
468491 return isset (self ::$ exitCodes [$ exitcode ]) ? self ::$ exitCodes [$ exitcode ] : 'Unknown error ' ;
469492 }
@@ -488,11 +511,14 @@ public function isSuccessful()
488511 * @return Boolean
489512 *
490513 * @throws RuntimeException In case --enable-sigchild is activated
514+ * @throws LogicException In case the process is not terminated.
491515 *
492516 * @api
493517 */
494518 public function hasBeenSignaled ()
495519 {
520+ $ this ->requireProcessIsTerminated (__FUNCTION__ );
521+
496522 if ($ this ->isSigchildEnabled ()) {
497523 throw new RuntimeException ('This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved. ' );
498524 }
@@ -510,11 +536,14 @@ public function hasBeenSignaled()
510536 * @return integer
511537 *
512538 * @throws RuntimeException In case --enable-sigchild is activated
539+ * @throws LogicException In case the process is not terminated.
513540 *
514541 * @api
515542 */
516543 public function getTermSignal ()
517544 {
545+ $ this ->requireProcessIsTerminated (__FUNCTION__ );
546+
518547 if ($ this ->isSigchildEnabled ()) {
519548 throw new RuntimeException ('This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved. ' );
520549 }
@@ -531,10 +560,14 @@ public function getTermSignal()
531560 *
532561 * @return Boolean
533562 *
563+ * @throws LogicException In case the process is not terminated.
564+ *
534565 * @api
535566 */
536567 public function hasBeenStopped ()
537568 {
569+ $ this ->requireProcessIsTerminated (__FUNCTION__ );
570+
538571 $ this ->updateStatus (false );
539572
540573 return $ this ->processInformation ['stopped ' ];
@@ -547,10 +580,14 @@ public function hasBeenStopped()
547580 *
548581 * @return integer
549582 *
583+ * @throws LogicException In case the process is not terminated.
584+ *
550585 * @api
551586 */
552587 public function getStopSignal ()
553588 {
589+ $ this ->requireProcessIsTerminated (__FUNCTION__ );
590+
554591 $ this ->updateStatus (false );
555592
556593 return $ this ->processInformation ['stopsig ' ];
@@ -938,6 +975,10 @@ public function setEnhanceSigchildCompatibility($enhance)
938975 */
939976 public function checkTimeout ()
940977 {
978+ if ($ this ->status !== self ::STATUS_STARTED ) {
979+ return ;
980+ }
981+
941982 if (null !== $ this ->timeout && $ this ->timeout < microtime (true ) - $ this ->starttime ) {
942983 $ this ->stop (0 );
943984
@@ -1155,4 +1196,32 @@ private function doSignal($signal, $throwException)
11551196
11561197 return true ;
11571198 }
1199+
1200+ /**
1201+ * Ensures the process is running or terminated, throws a LogicException if the process has a not started.
1202+ *
1203+ * @param $functionName The function name that was called.
1204+ *
1205+ * @throws LogicException If the process has not run.
1206+ */
1207+ private function requireProcessIsStarted ($ functionName )
1208+ {
1209+ if (!$ this ->isStarted ()) {
1210+ throw new LogicException (sprintf ('Process must be started before calling %s. ' , $ functionName ));
1211+ }
1212+ }
1213+
1214+ /**
1215+ * Ensures the process is terminated, throws a LogicException if the process has a status different than `terminated`.
1216+ *
1217+ * @param $functionName The function name that was called.
1218+ *
1219+ * @throws LogicException If the process is not yet terminated.
1220+ */
1221+ private function requireProcessIsTerminated ($ functionName )
1222+ {
1223+ if (!$ this ->isTerminated ()) {
1224+ throw new LogicException (sprintf ('Process must be terminated before calling %s. ' , $ functionName ));
1225+ }
1226+ }
11581227}
0 commit comments