Want to use PHP as part of your toolchain? It’s a bit painful. If you want to pipe in some data from memory, and read it back into memory (why not! using tmp files is for wimps).
here’s the solution, thanks to richard at 2006 dot atterer dot net
// $command is the command to run, $stdin is your input. You get back $stdout and $stderr and $returnValue // you'll probably want to wrap this in a function ;) $descriptorSpec = array(0 => array("pipe", "r"), 1 => array('pipe', 'w'), 2 => array('pipe', 'w')); $process = proc_open($command, $descriptorSpec, $pipes); $txOff = 0; $txLen = strlen($stdin); $stdout = ''; $stdoutDone = FALSE; $stderr = ''; $stderrDone = FALSE; stream_set_blocking($pipes[0], 0); // Make stdin/stdout/stderr non-blocking stream_set_blocking($pipes[1], 0); stream_set_blocking($pipes[2], 0); if ($txLen == 0) fclose($pipes[0]); while (TRUE) { $rx = array(); // The program's stdout/stderr if (!$stdoutDone) $rx[] = $pipes[1]; if (!$stderrDone) $rx[] = $pipes[2]; $tx = array(); // The program's stdin if ($txOff < $txLen) $tx[] = $pipes[0]; $ex = NULL; stream_select($rx, $tx, $ex, NULL, NULL); // Block til r/w possible if (!empty($tx)) { $txRet = fwrite($pipes[0], substr($stdin, $txOff, 8192)); if ($txRet !== FALSE) $txOff += $txRet; if ($txOff >= $txLen) fclose($pipes[0]); } foreach ($rx as $r) { if ($r == $pipes[1]) { $stdout .= fread($pipes[1], 8192); if (feof($pipes[1])) { fclose($pipes[1]); $stdoutDone = TRUE; } } else if ($r == $pipes[2]) { $stderr .= fread($pipes[2], 8192); if (feof($pipes[2])) { fclose($pipes[2]); $stderrDone = TRUE; } } } if (!is_resource($process)) break; if ($txOff >= $txLen && $stdoutDone && $stderrDone) break; } $returnValue = proc_close($process);
I previously had an implementation using `fwrite` and `stream_get_contents` as some other people, and the docs suggested, which works fine for small inputs, but once you get something bigger than ~200k input, it can completely deadlock.
This implementation is better as it reads and writes the data when needed, keeping everything flowing and alive.
nice code!
thanks!
A fix on the code… https://andrea.brancatelli.it/2018/10/05/php-proc_open-and-stdin-stdout-stderr/