Skip to content

Commit

Permalink
Issue #20 Add stream_set_blocking() calls for proc_open()
Browse files Browse the repository at this point in the history
  • Loading branch information
mikehaertl committed Aug 10, 2019
1 parent 9754f7d commit 57ba6f1
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 2 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,11 @@ $command->setStdIn('string');
PHP working dir.
* `$procEnv`: An array with environment variables to pass to `proc_open()`. Default is `null` for none.
* `$procOptions`: An array of `other_options` for `proc_open()`. Default is `null` for none.
* `$nonBlockingMode`: Whether to set the stdout/stderr streams to non-blocking
mode when `proc_open()` is used. This can fix issues with long running
commands that hang indefinitely but can cause problems on Windows systems.
The default is `null` in which case non-blocking mode is only enabled on
non-Windows systems.
* `$locale`: The locale to (temporarily) set with `setlocale()` before running the command.
This can be set to e.g. `en_US.UTF-8` if you have issues with UTF-8 encoded arguments.

Expand Down
22 changes: 20 additions & 2 deletions src/Command.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,15 @@ class Command
*/
public $procOptions;

/**
* @var bool|null whether to set the stdout/stderr streams to non-blocking mode
* when `proc_open()` is used. This can fix issues with long running
* commands that hang indefinitely but can cause problems on Windows
* systems. The default is `null` in which case non-blocking mode is only
* enabled on non-Windows systems.
*/
public $nonBlockingMode;

/**
* @var null|string the locale to temporarily set before calling `escapeshellargs()`. Default is `null` for none.
*/
Expand Down Expand Up @@ -345,6 +354,13 @@ public function execute()
$process = proc_open($command, $descriptors, $pipes, $this->procCwd, $this->procEnv, $this->procOptions);

if (is_resource($process)) {
// Issue #20 Set non-blocking mode to fix hanging processes
$nonBlocking = $this->nonBlockingMode === null ?
!$this->getIsWindows() : $this->nonBlockingMode;
if ($nonBlocking) {
stream_set_blocking($pipes[1], false);
stream_set_blocking($pipes[2], false);
}

if ($this->_stdIn!==null) {
if (is_resource($this->_stdIn) &&
Expand All @@ -362,8 +378,10 @@ public function execute()

$this->_exitCode = proc_close($process);

if ($this->_exitCode!==0) {
$this->_error = $this->_stdErr ? $this->_stdErr : "Failed without error message: $command";
if ($this->_exitCode !== 0) {
$this->_error = $this->_stdErr ?
$this->_stdErr :
"Failed without error message: $command (Exit code: {$this->_exitCode})";
return false;
}
} else {
Expand Down

0 comments on commit 57ba6f1

Please sign in to comment.