1
0
mirror of https://github.com/danog/process.git synced 2024-12-02 09:37:55 +01:00

Pass command via STDIN on Windows

This commit is contained in:
Niklas Keller 2017-09-19 13:14:43 +02:00
parent 1ccc4837d4
commit 0e57b8d379
8 changed files with 21 additions and 11 deletions

Binary file not shown.

Binary file not shown.

View File

@ -6,7 +6,10 @@ use Amp\ByteStream\Message;
use Amp\Process\Process;
Amp\Loop::run(function () {
$process = new Process("echo 'Hello, world!'");
// "echo" is a shell internal command on Windows and doesn't work.
$command = DIRECTORY_SEPARATOR === "\\" ? "cmd /c echo Hello World!" : "echo 'Hello, world!'";
$process = new Process($command);
$process->start();
echo yield new Message($process->getStdout());

View File

@ -9,6 +9,7 @@ use function Amp\Promise\all;
function show_process_output(Process $process): \Generator
{
$stream = $process->getStdout();
while (null !== $chunk = yield $stream->read()) {
echo $chunk;
}

View File

@ -9,6 +9,7 @@ Amp\Loop::run(function () {
$process->start();
$stream = $process->getStdout();
while (null !== $chunk = yield $stream->read()) {
echo $chunk;
}

View File

@ -6,7 +6,12 @@ use Amp\ByteStream\Message;
use Amp\Process\Process;
Amp\Loop::run(function () {
$process = new Process('read ; echo "$REPLY"');
if (DIRECTORY_SEPARATOR === "\\") {
echo "This example doesn't work on Windows." . PHP_EOL;
exit(1);
}
$process = new Process('read; echo "$REPLY"');
$process->start();
/* send to stdin */

View File

@ -27,7 +27,7 @@ final class Runner implements ProcessRunner {
private $socketConnector;
private function makeCommand(string $command, string $workingDirectory): string {
private function makeCommand(string $workingDirectory): string {
$result = sprintf(
'%s --address=%s --port=%d --token-size=%d',
\escapeshellarg(self::WRAPPER_EXE_PATH),
@ -40,8 +40,6 @@ final class Runner implements ProcessRunner {
$result .= ' ' . \escapeshellarg('--cwd=' . \rtrim($workingDirectory, '\\'));
}
$result .= ' ' . $command;
return $result;
}
@ -51,12 +49,14 @@ final class Runner implements ProcessRunner {
/** @inheritdoc */
public function start(string $command, string $cwd = null, array $env = [], array $options = []): ProcessHandle {
$command = $this->makeCommand($command, $cwd ?? '');
if (strpos($command, "\0") !== false) {
throw new ProcessException("Can't execute commands that contain null bytes.");
}
$options['bypass_shell'] = true;
$handle = new Handle;
$handle->proc = @\proc_open($command, self::FD_SPEC, $pipes, $cwd ?: null, $env ?: null, $options);
$handle->proc = @\proc_open($this->makeCommand($cwd ?? ''), self::FD_SPEC, $pipes, $cwd ?: null, $env ?: null, $options);
if (!\is_resource($handle->proc)) {
$message = "Could not start process";
@ -74,16 +74,16 @@ final class Runner implements ProcessRunner {
}
$securityTokens = \random_bytes(SocketConnector::SECURITY_TOKEN_SIZE * 6);
$written = \fwrite($pipes[0], $securityTokens);
$written = \fwrite($pipes[0], $securityTokens . "\0" . $command . "\0");
\fclose($pipes[0]);
\fclose($pipes[1]);
if ($written !== SocketConnector::SECURITY_TOKEN_SIZE * 6) {
if ($written !== SocketConnector::SECURITY_TOKEN_SIZE * 6 + \strlen($command) + 2) {
\fclose($pipes[2]);
\proc_close($handle->proc);
throw new ProcessException("Could not send security tokens to process wrapper");
throw new ProcessException("Could not send security tokens / command to process wrapper");
}
$handle->securityTokens = \str_split($securityTokens, SocketConnector::SECURITY_TOKEN_SIZE);

View File

@ -46,7 +46,7 @@ final class SocketConnector {
Loop::unreference(Loop::onReadable($this->server, [$this, 'onServerSocketReadable']));
}
private function failClientHandshake($socket, int $code): void {
private function failClientHandshake($socket, int $code) {
\fwrite($socket, \chr(SignalCode::HANDSHAKE_ACK) . \chr($code));
\fclose($socket);