From a461b7d9759d0727e796763b25c739825c56d7ca 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 | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/lib/Internal/Posix/Runner.php b/lib/Internal/Posix/Runner.php index a1c69dc..f273d1d 100644 --- a/lib/Internal/Posix/Runner.php +++ b/lib/Internal/Posix/Runner.php @@ -23,6 +23,10 @@ final class Runner implements ProcessRunner ["pipe", "w"], // stderr ["pipe", "w"], // exit code pipe ]; + const FD_COUNT = 4; + + /** @var string|null */ + private static $fdPath; public static function onProcessEndExtraDataPipeReadable($watcher, $stream, Handle $handle) { @@ -82,7 +86,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 +131,28 @@ 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(self::FD_COUNT, \count($fds) - self::FD_COUNT, ["file", "/dev/null", "r"]) + ); + } + /** @inheritdoc */ public function join(ProcessHandle $handle): Promise {