From d1e617f31c2ed2900845b7ea806ab5ee647d4de0 Mon Sep 17 00:00:00 2001 From: Frederick Muriuki Muriithi Date: Mon, 24 Aug 2026 10:48:03 -0500 Subject: Add a wrapper around `proc_open(...)` to use for terminal commands. --- sourcecodes/terminal_commands.php | 84 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 sourcecodes/terminal_commands.php diff --git a/sourcecodes/terminal_commands.php b/sourcecodes/terminal_commands.php new file mode 100644 index 00000000..fb4f4466 --- /dev/null +++ b/sourcecodes/terminal_commands.php @@ -0,0 +1,84 @@ + ['pipe', 'w'], //stdout + 2 => ['pipe', 'w'], //stderr + ]; + + // Generate `$strcmd` below to use for user notifications. + $strcmd = array_reduce( + array_merge( + [escapeshellcmd($command[0])], + array_map( + 'escapeshellarg', + array_slice($command, 1, sizeof($command)))), + '__command2string__', + ""); + $process = proc_open( + $command, // `proc_open` auto-escapes array command + $descriptors, + $pipes); + + if(!is_resource($process)) { + throw new \RunTimeException(sprintf( + "PHP was not able to spawn the process [%s]. " . + "Check system resources or paths.", + $strcmd + )); + } + + // Read streams: + $stdout = stream_get_contents($pipes[1]); + $stderr = stream_get_contents($pipes[2]); + + // Clean streams and close process resource. + fclose($pipes[1]); + fclose($pipes[2]); + $exitcode = proc_close($process); + + if($exitcode !== 0) { + throw new \RuntimeException(sprintf( + "Command [%s] failed with exit code %d.\n" . + "Stdout: %s\n\nStderr: %s", + $strcmd, + $exitcode, + trim($stdout), + trim($stderr) + )); + } + return [$exitcode, $stdout, $stderr]; +} +?> -- cgit 1.4.1