From bc9c2209adcda89a5505789753c2f3ccf3c76e07 Mon Sep 17 00:00:00 2001 From: Aaron Piotrowski Date: Wed, 23 Jan 2019 12:44:43 -0600 Subject: [PATCH] Close unnecessary file descriptors in child process --- lib/Internal/Posix/Runner.php | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/lib/Internal/Posix/Runner.php b/lib/Internal/Posix/Runner.php index a1c69dc..42d627e 100644 --- a/lib/Internal/Posix/Runner.php +++ b/lib/Internal/Posix/Runner.php @@ -24,6 +24,9 @@ final class Runner implements ProcessRunner ["pipe", "w"], // exit code pipe ]; + /** @var string|null */ + private static $fdPath; + public static function onProcessEndExtraDataPipeReadable($watcher, $stream, Handle $handle) { Loop::cancel($watcher); @@ -82,7 +85,7 @@ final class Runner implements ProcessRunner ); $handle = new Handle; - $handle->proc = @\proc_open($command, self::FD_SPEC, $pipes, $cwd ?: null, $env ?: null, $options); + $handle->proc = @\proc_open($command, $this->generateFds(), $pipes, $cwd ?: null, $env ?: null, $options); if (!\is_resource($handle->proc)) { $message = "Could not start process"; @@ -127,6 +130,25 @@ final class Runner implements ProcessRunner return $handle; } + private function generateFds(): array + { + if (self::$fdPath === null) { + self::$fdPath = \file_exists("/dev/fd") ? "/dev/fd" : "/proc/self/fd"; + } + + $fds = @\scandir(self::$fdPath, \SCANDIR_SORT_NONE); + + if ($fds === false) { + throw new ProcessException("Unable to list open file descriptors"); + } + + $fds = \array_filter($fds, function (string $path): bool { + return $path !== "." && $path !== ".."; + }); + + return \array_merge(self::FD_SPEC, \array_fill(4, \count($fds) - 4, ["file", "/dev/null", "r"])); + } + /** @inheritdoc */ public function join(ProcessHandle $handle): Promise {