<?php
namespace Common;
class Process {
public static function run_process($cmd, $downstream_data = NULL) {
# create tempfile for STDERR
$temp = tempnam('/tmp', 'wp-installer-');
// setup stream handling
$stream_handling = array(
0 => array("pipe", "r"), // stdin (unused)
1 => array("pipe", "w"), // direct stdout to pipe
2 => array("file", $temp, 'a'), // direct stderr to file
);
$process = proc_open($cmd, $stream_handling, $pipes);
$tmp_fh = fopen($temp, 'r');
unlink($temp);
// check that we could start the process
if (!is_resource($process)) {
throw new Exception('Could not start process: ' . $cmd);
}
// pass data to stdin if it's given
if ($downstream_data) {
fwrite($pipes[0], $downstream_data);
}
fclose($pipes[0]);
// get process data
$output = stream_get_contents($pipes[1]);
fclose($pipes[1]);
# gather warnings, close fh
$warnings = stream_get_contents($tmp_fh);
fclose($tmp_fh);
// close process
$return_value = proc_close($process);
// pass STDERR warnings through to the parent process
fwrite(STDERR, $warnings);
// strip empty lines
// array_filter w/ no function removes non-truthy values (empty strings)
$filtered_output = implode("\n", array_filter(explode("\n", $output)));
// attempt to parse as JSON
$json_output = (array) json_decode($filtered_output, true);
$trace = [];
// look for error cases
$error = $return_value > 0 || !$json_output || $json_output['success'] !== true;
// capture the trace if it exists
if($json_output && $json_output['trace']) {
$trace = $json_output['trace'];
unset($json_output['trace']);
}
return array(
'output' => $filtered_output,
'json_output' => $json_output,
'warnings' => $warnings,
'error' => $error,
'trace' => $trace
);
}
public static function su($username) {
$user_info = posix_getpwnam($username);
if( empty($user_info['uid']) ) {
throw new \Exception("User '{$username}' could not be found");
}
$effective_user = posix_getpwuid( posix_geteuid() )['name'];
if ($effective_user == $user_info['name']) {
// Process is running as expected user already
return true;
}
if (posix_setgid($user_info['gid']) !== true) {
throw new \Exception("Failed to set the owning group of this process");
}
if (posix_initgroups($user_info['name'], $user_info['gid']) !== true) {
throw new \Exception("Failed to set the group access list for this process");
}
if (posix_setuid($user_info['uid']) !== true) {
throw new \Exception("Failed to set the owning user of this process");
}
}
}
?>