X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=src%2Fpharext%2FExecCmd.php;h=5a6ee81f6fdad1be6b6eb4756d3c5cf966de58ae;hb=052ea3008a116f3eb9cc5607f76571b705cb10a7;hp=3ea63d00438f2887c8f69ce9c5ee1e3e008adf3f;hpb=861260c111bff72f60665393660b6f5375559510;p=pharext%2Fpharext diff --git a/src/pharext/ExecCmd.php b/src/pharext/ExecCmd.php index 3ea63d0..5a6ee81 100644 --- a/src/pharext/ExecCmd.php +++ b/src/pharext/ExecCmd.php @@ -57,16 +57,19 @@ class ExecCmd /** * Execute a program with escalated privileges handling interactive password prompt * @param string $command - * @param string $output - * @param int $status + * @param bool $verbose + * @return int exit status */ - private function suExec($command, &$output, &$status) { + private function suExec($command, $verbose = null) { if (!($proc = proc_open($command, [STDIN,["pipe","w"],["pipe","w"]], $pipes))) { - $status = -1; + $this->status = -1; throw new Exception("Failed to run {$command}"); } + $stdout = $pipes[1]; $passwd = 0; + $checks = 10; + while (!feof($stdout)) { $R = [$stdout]; $W = []; $E = []; if (!stream_select($R, $W, $E, null)) { @@ -74,19 +77,59 @@ class ExecCmd } $data = fread($stdout, 0x1000); /* only check a few times */ - if ($passwd++ < 10) { + if ($passwd < $checks) { + $passwd++; if (stristr($data, "password")) { + $passwd = $checks + 1; printf("\n%s", $data); + continue; + } + } elseif ($passwd > $checks) { + /* new line after pw entry */ + printf("\n"); + $passwd = $checks; + } + + if ($verbose === null) { + print $this->progress($data, 0); + } else { + if ($verbose) { + printf("%s", $data); } + $this->output .= $data; } - $output .= $data; } - $status = proc_close($proc); + if ($verbose === null) { + $this->progress("", PHP_OUTPUT_HANDLER_FINAL); + } + return $this->status = proc_close($proc); + } + + /** + * Output handler that displays some progress while soaking output + * @param string $string + * @param int $flags + * @return string + */ + private function progress($string, $flags) { + static $counter = 0; + static $symbols = ["\\","|","/","-"]; + + $this->output .= $string; + + if (false !== strpos($string, "\n")) { + ++$counter; + } + + return $flags & PHP_OUTPUT_HANDLER_FINAL + ? " \r" + : sprintf(" %s\r", $symbols[$counter % 4]); } /** * Run the command * @param array $args + * @return \pharext\ExecCmd self * @throws \pharext\Exception */ public function run(array $args = null) { @@ -96,7 +139,7 @@ class ExecCmd } if ($this->sudo) { - $this->suExec(sprintf($this->sudo." 2>&1", $exec), $this->output, $this->status); + $this->suExec(sprintf($this->sudo." 2>&1", $exec), $this->verbose); } elseif ($this->verbose) { ob_start(function($s) { $this->output .= $s; @@ -104,14 +147,20 @@ class ExecCmd }, 1); passthru($exec, $this->status); ob_end_flush(); + } elseif ($this->verbose !== false /* !quiet */) { + ob_start([$this, "progress"], 1); + passthru($exec . " 2>&1", $this->status); + ob_end_flush(); } else { exec($exec ." 2>&1", $output, $this->status); $this->output = implode("\n", $output); } if ($this->status) { - throw new Exception("Command {$this->command} failed ({$this->status})"); + throw new Exception("Command {$exec} failed ({$this->status})"); } + + return $this; } /**