示例#1
0
 /**
  *
  * Exec the command and return code
  *
  * @param string $cmd
  * @param string $stdout
  * @param string $stderr
  * @param int    $timeout
  * @return int|null
  */
 public static function exec($cmd, &$stdout, &$stderr, $timeout = 3600)
 {
     if ($timeout <= 0) {
         $timeout = 3600;
     }
     $descriptors = array(1 => array("pipe", "w"), 2 => array("pipe", "w"));
     $stdout = $stderr = $status = null;
     $process = proc_open($cmd, $descriptors, $pipes);
     $time_end = time() + $timeout;
     if (is_resource($process)) {
         do {
             $time_left = $time_end - time();
             $read = array($pipes[1]);
             stream_select($read, $null, $null, $time_left, NULL);
             $stdout .= fread($pipes[1], 2048);
         } while (!feof($pipes[1]) && $time_left > 0);
         fclose($pipes[1]);
         if ($time_left <= 0) {
             proc_terminate($process);
             $stderr = 'process terminated for timeout.';
             return -1;
         }
         while (!feof($pipes[2])) {
             $stderr .= fread($pipes[2], 2048);
         }
         fclose($pipes[2]);
         $status = proc_close($process);
     }
     return $status;
 }
示例#2
0
function execute($cmd)
{
    $descriptors = array(0 => array('pipe', 'r'), 1 => array('pipe', 'w'), 2 => array('pipe', 'w'));
    $stdout = '';
    $proc = proc_open(escapeshellcmd($cmd), $descriptors, $pipes);
    if (!is_resource($proc)) {
        throw new \Exception('Could not execute process');
    }
    // Set the stdout stream to none-blocking.
    stream_set_blocking($pipes[1], 0);
    $timeout = 3000;
    // miliseconds.
    $forceKill = true;
    while ($timeout > 0) {
        $start = round(microtime(true) * 1000);
        // Wait until we have output or the timer expired.
        $status = proc_get_status($proc);
        $read = array($pipes[1]);
        stream_select($read, $other, $other, 0, $timeout);
        $stdout .= stream_get_contents($pipes[1]);
        if (!$status['running']) {
            // Break from this loop if the process exited before the timeout.
            $forceKill = false;
            break;
        }
        // Subtract the number of microseconds that we waited.
        $timeout -= round(microtime(true) * 1000) - $start;
    }
    if ($forceKill == true) {
        proc_terminate($proc, 9);
    }
    return $stdout;
}
/**
 * Execute a command and kill it if the timeout limit fired to prevent long php execution
 * 
 * @see http://stackoverflow.com/questions/2603912/php-set-timeout-for-script-with-system-call-set-time-limit-not-working
 * 
 * @param string $cmd Command to exec (you should use 2>&1 at the end to pipe all output)
 * @param integer $timeout
 * @return string Returns command output 
 */
function ExecWaitTimeout($cmd, $timeout = 5)
{
    echo $cmd . "\n";
    $descriptorspec = array(0 => array("pipe", "r"), 1 => array("pipe", "w"), 2 => array("pipe", "w"));
    $pipes = array();
    $timeout += time();
    $process = proc_open($cmd, $descriptorspec, $pipes);
    if (!is_resource($process)) {
        throw new Exception("proc_open failed on: " . $cmd);
    }
    $output = '';
    do {
        $timeleft = $timeout - time();
        $read = array($pipes[1]);
        //     if($timeleft > 0)
        stream_select($read, $write = NULL, $exeptions = NULL, $timeleft, NULL);
        if (!empty($read)) {
            $output .= fread($pipes[1], 8192);
        }
    } while (!feof($pipes[1]) && $timeleft > 0);
    if ($timeleft <= 0) {
        proc_terminate($process);
        throw new Exception("command timeout on: " . $cmd);
    } else {
        return $output;
    }
}
示例#4
0
 protected function disposeWorker() : \Generator
 {
     try {
         $this->executor->cancel(new PoolShutdownException('Pool shut down'));
         yield from $this->transmitter->send('', SocketTransmitter::TYPE_EXIT);
         list($type) = (yield from $this->transmitter->receive());
     } catch (\Throwable $e) {
         // Cannot do anything about this...
     }
     $this->transmitter = null;
     try {
         $this->socket->close();
     } finally {
         $this->socket = null;
         if ($this->process !== null) {
             try {
                 if (empty($type) || $type !== SocketTransmitter::TYPE_EXIT) {
                     $status = @\proc_get_status($this->process);
                     if (!empty($status['running']) && empty($status['stopped'])) {
                         @\proc_terminate($this->process);
                     }
                 }
             } finally {
                 @\proc_close($this->process);
                 $this->process = null;
             }
         }
     }
 }
示例#5
0
function proc_exec($cmd)
{
    $descriptorspec = array(0 => array("pipe", "r"), 1 => array("pipe", "w"), 2 => array("pipe", "w"));
    $ptr = proc_open($cmd, $descriptorspec, $pipes, NULL, $_ENV);
    if (!is_resource($ptr)) {
        return false;
    }
    while (!feof($ptr)) {
        $buffer = fgets($ptr);
        $buffer = trim(htmlspecialchars($buffer));
        echo "data: " . $buffer . "<br />";
        echo "data: " . str_pad('', 4096);
        ob_flush();
        flush();
    }
    while (($buffer = fgets($pipes[FD_READ], BUF_SIZ)) != NULL || ($errbuf = fgets($pipes[FD_ERR], BUF_SIZ)) != NULL) {
        if (!isset($flag)) {
            $pstatus = proc_get_status($ptr);
            $first_exitcode = $pstatus["exitcode"];
            $flag = true;
        }
        if (strlen($buffer)) {
            echo "data: INFO: have";
        }
        //. $buffer;
        ob_flush();
        flush();
        if (strlen($errbuf)) {
            ob_flush();
        }
        flush();
        echo "data: ERR: err ";
        // . $errbuf;
    }
    foreach ($pipes as $pipe) {
        fclose($pipe);
    }
    /* Get the expected *exit* code to return the value */
    $pstatus = proc_get_status($ptr);
    if (!strlen($pstatus["exitcode"]) || $pstatus["running"]) {
        /* we can trust the retval of proc_close() */
        if ($pstatus["running"]) {
            proc_terminate($ptr);
        }
        $ret = proc_close($ptr);
    } else {
        if (($first_exitcode + 256) % 256 == 255 && ($pstatus["exitcode"] + 256) % 256 != 255) {
            $ret = $pstatus["exitcode"];
        } elseif (!strlen($first_exitcode)) {
            $ret = $pstatus["exitcode"];
        } elseif (($first_exitcode + 256) % 256 != 255) {
            $ret = $first_exitcode;
        } else {
            $ret = 0;
        }
        /* we "deduce" an EXIT_SUCCESS ;) */
        proc_close($ptr);
    }
    return ($ret + 256) % 256;
}
示例#6
0
 public function terminate($signal = 15)
 {
     $ret = proc_terminate($this->_process, $signal);
     if (!$ret) {
         throw new Kwf_Exception("terminate failed");
     }
 }
示例#7
0
 public function stop()
 {
     if (!$this->process) {
         return;
     }
     $status = proc_get_status($this->process);
     if ($status['running']) {
         fclose($this->pipes[1]);
         //stdout
         fclose($this->pipes[2]);
         //stderr
         //get the parent pid of the process we want to kill
         $pPid = $status['pid'];
         //use ps to get all the children of this process, and kill them
         foreach (array_filter(preg_split('/\\s+/', `ps -o pid --no-heading --ppid {$pPid}`)) as $pid) {
             if (is_numeric($pid)) {
                 posix_kill($pid, 9);
                 // SIGKILL signal
             }
         }
     }
     fclose($this->pipes[0]);
     proc_terminate($this->process);
     $this->process = NULL;
 }
示例#8
0
 public function close()
 {
     @\fclose($this->stdin);
     @\fclose($this->stdout);
     @\proc_terminate($this->process, 15);
     @\proc_close($this->process);
 }
示例#9
0
function execute($cmd, $stdin = null, &$stdout, &$stderr, $timeout = false)
{
    $pipes = array();
    $process = proc_open($cmd, array(array('pipe', 'r'), array('pipe', 'w'), array('pipe', 'w')), $pipes);
    $start = time();
    $stdout = '';
    $stderr = '';
    if (is_resource($process)) {
        stream_set_blocking($pipes[0], 0);
        stream_set_blocking($pipes[1], 0);
        stream_set_blocking($pipes[2], 0);
        fwrite($pipes[0], $stdin);
        fclose($pipes[0]);
    }
    while (is_resource($process)) {
        $stdout .= stream_get_contents($pipes[1]);
        $stderr .= stream_get_contents($pipes[2]);
        if ($timeout !== false && time() - $start > $timeout) {
            proc_terminate($process, 9);
            return 1;
        }
        $status = proc_get_status($process);
        if (!$status['running']) {
            fclose($pipes[1]);
            fclose($pipes[2]);
            proc_close($process);
            return $status['exitcode'];
        }
        usleep(100000);
    }
    return 1;
}
示例#10
0
文件: Worker.php 项目: exsyst/worker
 /**
  * @param WorkerBootstrapProfile $bootstrapProfile
  * @param string                 $implementationExpression
  */
 protected function __construct(WorkerBootstrapProfile $bootstrapProfile, $implementationExpression)
 {
     $bootstrapProfile->getOrFindPhpExecutablePathAndArguments($php, $phpArgs);
     $bootstrapProfile->compileScriptWithExpression($implementationExpression, null, $scriptPath, $deleteScript);
     try {
         $line = array_merge([$php], $phpArgs, [$scriptPath]);
         $outPath = $bootstrapProfile->getOutputPath();
         $this->process = proc_open(implode(' ', array_map('escapeshellarg', $line)), [0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => $outPath !== null ? ['file', $outPath, 'a'] : STDERR], $pipes);
         $inputSink = Sink::fromStream($pipes[0], true);
         $outputSource = Source::fromStream($pipes[1], true);
         $this->channel = $bootstrapProfile->getChannelFactory()->createChannel($outputSource, $inputSink);
     } catch (\Exception $e) {
         if (isset($pipes[1])) {
             fclose($pipes[1]);
         }
         if (isset($pipes[0])) {
             fclose($pipes[0]);
         }
         if (isset($this->process)) {
             proc_terminate($this->process);
             proc_close($this->process);
         }
         if ($deleteScript) {
             unlink($scriptPath);
         }
         throw $e;
     }
 }
示例#11
0
 public function run($argv)
 {
     // fetch task info
     $taskId = $argv[0];
     $task = $this->taskDao->find($taskId);
     if ($task === false) {
         $this->logger->error('Task not found.');
         return;
     }
     // TODO update pid
     $jobId = $task['job_id'];
     $developTaskId = $this->jobDao->getDevelopTaskId($task['job_id']);
     // open process
     $taskLogsDir = Config::get('taskLogsDir');
     $desc = [1 => ['file', $taskLogsDir . '/scheduler_task_' . $taskId . '.out', 'w'], 2 => ['file', $taskLogsDir . '/scheduler_task_' . $taskId . '.err', 'w']];
     $process = proc_open('php ' . __DIR__ . '/launcher.php develop_run.php ' . $developTaskId, $desc, $pipes);
     $this->logger->info("Run [task_id: {$taskId}, job_id: {$jobId}, develop_task_id: {$developTaskId}]");
     // wait
     while (!$this->taskDao->isInterrupted($taskId)) {
         $processStatus = proc_get_status($process);
         if (!$processStatus['running']) {
             if ($processStatus['exitcode'] == 0) {
                 $taskStatus = SchedulerTaskDao::STATUS_SUCCESS;
             } else {
                 $taskStatus = SchedulerTaskDao::STATUS_FAILURE;
             }
             $this->taskDao->updateStatus($taskId, $taskStatus);
             $this->jobDao->updateTaskStatus($jobId, $taskStatus);
             if ($taskStatus == SchedulerTaskDao::STATUS_SUCCESS) {
                 $this->jobDao->insertSignal($jobId, $this->now->format('Y-m-d'));
             }
             $this->logger->info('Task finished, exitcode ' . $processStatus['exitcode']);
             proc_close($process);
             return;
         }
         sleep(1);
     }
     $this->logger->warn('Task is interrupted, send SIGTERM.');
     proc_terminate($process, SIGTERM);
     // stop gracefully
     $countDown = 5;
     while ($countDown > 0) {
         $processStatus = proc_get_status($process);
         if (!$processStatus['running']) {
             break;
         }
         sleep(1);
         --$countDown;
     }
     if ($countDown == 0) {
         $this->logger->warn('Send SIGKILL.');
         proc_terminate($process, SIGKILL);
     }
     $this->taskDao->updateStatus($taskId, SchedulerTaskDao::STATUS_FAILURE);
     $this->jobDao->updateTaskStatus($jobId, SchedulerTaskDao::STATUS_FAILURE);
     $this->logger->info('Task killed.');
     proc_close($process);
 }
示例#12
0
文件: server.inc.php 项目: 4honor/air
 public function __destruct()
 {
     $status = proc_terminate($this->_server);
     if ($status) {
         echo "local server stopped\n";
     } else {
         echo "stop local server failed";
     }
 }
function proc_terminate($signal)
{
    global $mockProcTerminateFail;
    if ($mockProcTerminateFail) {
        return false;
    } else {
        return \proc_terminate($signal);
    }
}
示例#14
0
 /**
  * @return DriverService
  */
 public function stop()
 {
     if ($this->process === null) {
         return $this;
     }
     proc_terminate($this->process);
     $this->process = null;
     $checker = new URLChecker();
     $checker->waitUntilUnAvailable(3 * 1000, $this->url . '/shutdown');
     return $this;
 }
示例#15
0
 public function shutdown()
 {
     pclose($this->config['proc-server']);
     pclose($this->config['proc-docs-server']);
     pclose($this->config['proc-watcher']);
     pclose($this->config['proc-logs']);
     proc_terminate($this->config['proc-server']);
     proc_terminate($this->config['proc-docs-server']);
     proc_terminate($this->config['proc-watcher']);
     proc_terminate($this->config['proc-logs']);
     exit;
 }
示例#16
0
function handleShutdown()
{
    global $webSocketProcess;
    if (PHP_OS == "Linux") {
        proc_terminate($webSocketProcess, 9);
    }
    $error = error_get_last();
    if (!empty($error)) {
        $info = "[SHUTDOWN] date: " . date("d.m.y H:m", time()) . " file: " . $error['file'] . " | ln: " . $error['line'] . " | msg: " . $error['message'] . PHP_EOL;
        file_put_contents(APP_ROOT . 'logs' . DIRECTORY_SEPARATOR . 'error.log', $info, FILE_APPEND);
    }
}
 protected function stopProcessWithSignal($process, $signal, $callback)
 {
     list($process, $pipes) = $process;
     proc_terminate($process, $signal);
     usleep(100000);
     // Wait until the signal will be dispatched by the supervisor process
     $stdout = stream_get_contents($pipes[1]);
     $stderr = stream_get_contents($pipes[2]);
     fclose($pipes[1]);
     fclose($pipes[2]);
     proc_close($process);
     $callback($stdout, $stderr);
 }
 protected function call_maxima($command)
 {
     $ret = false;
     $err = '';
     $cwd = null;
     $env = array('why' => 'itworks');
     $descriptors = array(0 => array('pipe', 'r'), 1 => array('pipe', 'w'), 2 => array('pipe', 'w'));
     $casprocess = proc_open($this->command, $descriptors, $pipes, $cwd, $env);
     if (!is_resource($casprocess)) {
         throw new stack_exception('stack_cas_connection: could not open a CAS process');
     }
     if (!fwrite($pipes[0], $this->initcommand)) {
         throw new stack_exception('stack_cas_connection: could not write to the CAS process.');
     }
     fwrite($pipes[0], $command);
     fwrite($pipes[0], 'quit();' . "\n\n");
     $ret = '';
     // Read output from stdout.
     $starttime = microtime(true);
     $continue = true;
     if (!stream_set_blocking($pipes[1], false)) {
         $this->debug->log('', 'Warning: could not stream_set_blocking to be FALSE on the CAS process.');
     }
     while ($continue and !feof($pipes[1])) {
         $now = microtime(true);
         if ($now - $starttime > $this->timeout) {
             $procarray = proc_get_status($casprocess);
             if ($procarray['running']) {
                 proc_terminate($casprocess);
             }
             $continue = false;
         } else {
             $out = fread($pipes[1], 1024);
             if ('' == $out) {
                 // Pause.
                 usleep(1000);
             }
             $ret .= $out;
         }
     }
     if ($continue) {
         fclose($pipes[0]);
         fclose($pipes[1]);
         $this->debug->log('Timings', "Start: {$starttime}, End: {$now}, Taken = " . ($now - $starttime));
     } else {
         // Add sufficient closing ]'s to allow something to be un-parsed from the CAS.
         // WARNING: the string 'The CAS timed out' is used by the cache to search for a timeout occurrence.
         $ret .= ' The CAS timed out. ] ] ] ]';
     }
     return $ret;
 }
示例#19
0
 public function exec_timeout($cmd, $timeout, &$output = '')
 {
     $fdSpec = [0 => ['file', '/dev/null', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w', 'a']];
     $pipes = [];
     $proc = proc_open($cmd, $fdSpec, $pipes);
     //        $status = proc_get_status($proc);
     //        var_dump($status);
     stream_set_blocking($pipes[1], false);
     $stop = time() + $timeout;
     while (true === true) {
         $in = [$pipes[1], $pipes[2]];
         $out = [];
         $err = [];
         //stream_select($in, $out, $err, min(1, $stop - time()));
         stream_select($in, $out, $err, 0, 200);
         if (count($in) !== 0) {
             foreach ($in as $socketToRead) {
                 while (feof($socketToRead) !== false) {
                     $output .= stream_get_contents($socketToRead);
                     continue;
                 }
             }
         }
         if ($stop <= time()) {
             break;
         } else {
             if ($this->isLockFileStillValid() === false) {
                 break;
             }
         }
     }
     fclose($pipes[1]);
     //close process's stdout, since we're done with it
     fclose($pipes[2]);
     //close process's stderr, since we're done with it
     //var_dump($output);
     $status = proc_get_status($proc);
     if (intval($status['running']) !== 0) {
         proc_terminate($proc);
         //terminate, since close will block until the process exits itself
         //This is the child process - so just exit
         exit(0);
         return -1;
     } else {
         proc_close($proc);
         //This is the child process - so just exit
         exit(0);
         return $status['exitcode'];
     }
 }
示例#20
0
 /**
  * Executes the given test file, this time no other checking/setup is
  * involved, just run it and get the result.
  * 
  * This is the main bread and butter of the whole test framework. If theres
  * anything that needs to be polished or improved should be this method. 
  *
  * @param  string  $commands to execute the test file
  * @param  mixed   environment variable needed by the test file before firing
  *                 the $commands
  * @param  string  standard input
  * @return mixed   Returns data output after the $commands is invoked
  * 
  * @access public
  */
 public function console($cmd, $env = null, $stdin = null)
 {
     if (!empty($cmd)) {
         $data = "";
         $env = $env == null ? $_ENV : $env;
         $cwd = ($c = getcwd()) != false ? $c : null;
         $pipes = array();
         $descriptor = array(0 => array('pipe', 'r'), 1 => array('pipe', 'w'), 2 => array('pipe', 'w'));
         $proc = proc_open($cmd, $descriptor, $pipes, $cwd, $env, array("suppress_errors" => true));
         if ($proc && is_resource($proc)) {
             if (is_string($stdin)) {
                 fwrite($pipes[0], $stdin);
             }
             fclose($pipes[0]);
             while (true) {
                 /* hide errors from interrupted syscalls */
                 $r = $pipes;
                 $w = null;
                 $e = null;
                 $n = @stream_select($r, $w, $e, 300);
                 if ($n === 0) {
                     /* timed out */
                     $data .= "\n ** ERROR: process timed out **\n";
                     proc_terminate($proc);
                     return $data;
                 } else {
                     if ($n > 0) {
                         $line = fread($pipes[1], 8192);
                         if (strlen($line) == 0) {
                             /* EOF */
                             break;
                         }
                         $data .= $line;
                     }
                 }
             }
             # TODO: add more handler for $stat return value
             $stat = proc_get_status($proc);
             if ($stat['signaled']) {
                 $data .= "\nTermsig=" . $stat['stopsig'];
             }
             # TODO: implement (proc_close($proc) >> 8) & 0xff;
             $code = proc_close($proc);
             return $data;
         }
         /* close pipe */
         fclose($pipes[0]);
     }
     return false;
 }
示例#21
0
 public function stop()
 {
     $s = proc_get_status($this->cmdHandler);
     fclose($this->pipes[0]);
     fclose($this->pipes[1]);
     fclose($this->pipes[2]);
     $pidCmd = 'ps -o pid --no-headers --ppid ' . $s['pid'];
     $cmdOutput = shell_exec($pidCmd);
     proc_terminate($this->cmdHandler);
     if (preg_match_all("~(?<PIDS>\\d+)~m", $cmdOutput, $pids)) {
         foreach ($pids['PIDS'] as $pid) {
             posix_kill((int) $pid, SIGTERM);
         }
     }
     return true;
 }
示例#22
0
 /**
  * @inheritDoc
  *
  * @throws CommandExecutionException on error.
  */
 public function sendSignal($process, $signal)
 {
     switch ($signal) {
         case ProcessInterface::SIGTERM:
             $mappedSignal = SIGTERM;
             break;
         case ProcessInterface::SIGKILL:
             $mappedSignal = SIGKILL;
             break;
         default:
             throw new CommandExecutionException('Unknown signal "' . $signal . '" provided.');
     }
     if (true !== proc_terminate($process, $mappedSignal)) {
         throw new CommandExecutionException('Call to proc_terminate with signal "' . $signal . '" failed for unknown reason.');
     }
 }
示例#23
0
 public static function tearDownAfterClass()
 {
     if (self::$client) {
         try {
             $ctx = VTContext::getDefault()->withDeadlineAfter(5.0);
             $conn = new VTGateconn(self::$client);
             $conn->execute($ctx, 'quit://', array(), 0);
             self::$client->close();
         } catch (Exception $e) {
         }
     }
     if (self::$proc) {
         proc_terminate(self::$proc, 9);
         proc_close(self::$proc);
     }
 }
示例#24
0
文件: hiatus.php 项目: nubs/hiatus
/**
 * Executes the command with the given arguments.  If a timeout is given (in seconds), the command will be terminated if it takes longer.
 *
 * @param string $command The shell command to execute.  This can contain arguments, but make sure to use PHP's escapeshellarg for any arguments
 *     supplied by the user.
 * @param array $arguments The arguments to pass to the command.  These will be passed through PHP's escapeshellarg function so pass the
 *     arguments unescaped.  If a key in the array is not numeric, then it will be included as well in a KEY=VALUE format.
 * @param float $timeout If given, this will terminate the command if it does not finish before the timeout expires.
 * @param string $stdin A string to pass to the command on stdin.
 * @return array A 3-member array is returned.
 *     * int The exit code of the command.
 *     * string The output of the command.
 *     * string The stderr output of the command.
 */
function exec($command, array $arguments = [], $timeout = null, $stdin = null)
{
    $command = addArguments($command, $arguments);
    $pipes = null;
    $pipeSpec = [1 => ['pipe', 'w'], 2 => ['pipe', 'w']];
    if ($stdin !== null) {
        $pipeSpec[0] = ['pipe', 'r'];
    }
    $process = proc_open($command, $pipeSpec, $pipes);
    if ($process === false) {
        throw new \Exception("Error executing command '{$command}' with proc_open.");
    }
    if ($stdin !== null) {
        fwrite($pipes[0], $stdin);
        fclose($pipes[0]);
    }
    if ($timeout !== null) {
        $timeout *= 1000000;
    }
    stream_set_blocking($pipes[1], 0);
    stream_set_blocking($pipes[2], 0);
    $stdout = '';
    $stderr = '';
    $exitCode = null;
    while ($timeout === null || $timeout > 0) {
        $start = microtime(true);
        $read = [$pipes[1], $pipes[2]];
        $other = [];
        stream_select($read, $other, $other, 0, $timeout);
        $status = proc_get_status($process);
        $stdout .= stream_get_contents($pipes[1]);
        $stderr .= stream_get_contents($pipes[2]);
        if (!$status['running']) {
            $exitCode = $status['exitcode'];
            break;
        }
        if ($timeout !== null) {
            $timeout -= (microtime(true) - $start) * 1000000;
        }
    }
    proc_terminate($process, 9);
    $closeStatus = proc_close($process);
    if ($exitCode === null) {
        $exitCode = $closeStatus;
    }
    return [$exitCode, $stdout, $stderr];
}
示例#25
0
/**
 * Execute an external command while applying a timeout
 *
 * @param string $cmd
 * @param int $timeout seconds to execute
 * @return int exit code
 */
function timeout_passthru($cmd, $timeout)
{
    $process = proc_open($cmd, array(0 => STDIN, 1 => STDOUT, 2 => STDERR), $pipes);
    $status = timeout_wait($process, $timeout);
    if (!$status['running']) {
        // We can end this the easy way
        return $status['exitcode'];
    } else {
        // We need to end this the hard way
        proc_terminate($process);
        $status = timeout_wait($process, TIMEOUT_FINAL);
        if ($status['running'] && defined('SIGKILL')) {
            proc_terminate($process, SIGKILL);
        }
        return 255;
    }
}
示例#26
0
function passthru(string $cmd) : \generator
{
    $pipes = [];
    $proc = proc_open($cmd, [0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']], $pipes);
    $cancel = false;
    $contents = '';
    while ($cancel == false && proc_get_status($proc)['running'] === true) {
        $out = [$pipes[1]];
        $err = [$pipes[2]];
        $write = $except = null;
        if (stream_select($out, $write, $except, 0, 1) > 0) {
            $buffer = stream_get_contents($out[0]);
            if ($buffer !== '') {
                $contents .= $buffer;
            }
        }
        if (stream_select($err, $write, $except, 0, 1) > 0) {
            $buffer = stream_get_contents($err[0]);
            if ($buffer !== '') {
                $contents .= $buffer;
            }
        }
        $cancel = yield;
    }
    if ($cancel === true) {
        proc_terminate($proc);
    } else {
        $out = [$pipes[1]];
        $err = [$pipes[2]];
        $write = $except = null;
        if (stream_select($out, $write, $except, 0, 1) > 0) {
            $buffer = stream_get_contents($out[0]);
            if ($buffer !== '') {
                $contents .= $buffer;
            }
        }
        if (stream_select($err, $write, $except, 0, 1) > 0) {
            $buffer = stream_get_contents($err[0]);
            if ($buffer !== '') {
                $contents .= $buffer;
            }
        }
    }
    proc_close($proc);
    return $contents;
}
function proc_exec($cmd)
{
    $descriptorspec = array(0 => array("pipe", "r"), 1 => array("pipe", "w"), 2 => array("pipe", "w"));
    $ptr = proc_open($cmd, $descriptorspec, $pipes, NULL, $_ENV);
    if (!is_resource($ptr)) {
        return false;
    }
    while (($buffer = fgets($pipes[1], 1024)) != NULL || ($errbuf = fgets($pipes[2], 1024)) != NULL) {
        if (!isset($flag)) {
            $pstatus = proc_get_status($ptr);
            $first_exitcode = $pstatus["exitcode"];
            $flag = true;
        }
        if (strlen($buffer)) {
            echo $buffer;
        }
        if (strlen($errbuf)) {
            echo "ERR: " . $errbuf;
        }
    }
    foreach ($pipes as $pipe) {
        fclose($pipe);
    }
    /* Get the expected *exit* code to return the value */
    $pstatus = proc_get_status($ptr);
    if (!strlen($pstatus["exitcode"]) || $pstatus["running"]) {
        /* we can trust the retval of proc_close() */
        if ($pstatus["running"]) {
            proc_terminate($ptr);
        }
        $ret = proc_close($ptr);
    } else {
        if (($first_exitcode + 256) % 256 == 255 && ($pstatus["exitcode"] + 256) % 256 != 255) {
            $ret = $pstatus["exitcode"];
        } elseif (!strlen($first_exitcode)) {
            $ret = $pstatus["exitcode"];
        } elseif (($first_exitcode + 256) % 256 != 255) {
            $ret = $first_exitcode;
        } else {
            $ret = 0;
        }
        /* we "deduce" an EXIT_SUCCESS ;) */
        proc_close($ptr);
    }
    return ($ret + 256) % 256;
}
示例#28
0
function terminate_job($p)
{
    $pstatus = proc_get_status($p);
    $ppid = $pstatus['pid'];
    $ret = `ps -o pid --no-heading --ppid {$ppid}`;
    //echo "parent pid is $ppid\nterninate it\n";
    proc_terminate($p);
    // echo "child process is $ret\n";
    $pids = preg_split('/\\s+/', $ret);
    foreach ($pids as $pid) {
        if (is_numeric($pid)) {
            if ($GLOBALS["debug"]) {
                echo "killing child process {$pid}\n";
            }
            posix_kill($pid, 9);
        }
    }
}
示例#29
0
 /**
  * Taken from php-src/run-tests.php
  *
  * @param string $commandline command name
  * @param array $env
  * @param string $stdin standard input to pass to the command
  * @return unknown
  */
 function system_with_timeout($commandline, $env = null, $stdin = null)
 {
     $data = '';
     $proc = proc_open($commandline, array(0 => array('pipe', 'r'), 1 => array('pipe', 'w'), 2 => array('pipe', 'w')), $pipes, null, $env, array('suppress_errors' => true));
     if (!$proc) {
         return false;
     }
     if (is_string($stdin)) {
         fwrite($pipes[0], $stdin);
     }
     fclose($pipes[0]);
     while (true) {
         /* hide errors from interrupted syscalls */
         $r = $pipes;
         $e = $w = null;
         $n = @stream_select($r, $w, $e, 60);
         if ($n === 0) {
             /* timed out */
             $data .= "\n ** ERROR: process timed out **\n";
             proc_terminate($proc);
             return array(1234567890, $data);
         } else {
             if ($n > 0) {
                 $line = fread($pipes[1], 8192);
                 if (strlen($line) == 0) {
                     /* EOF */
                     break;
                 }
                 $data .= $line;
             }
         }
     }
     if (function_exists('proc_get_status')) {
         $stat = proc_get_status($proc);
         if ($stat['signaled']) {
             $data .= "\nTermsig=" . $stat['stopsig'];
         }
     }
     $code = proc_close($proc);
     if (function_exists('proc_get_status')) {
         $code = $stat['exitcode'];
     }
     return array($code, $data);
 }
示例#30
-1
 private function callFormatter($cmd)
 {
     $cmd = $this->getExecPath() . "  " . escapeshellarg($cmd);
     $proc = proc_open($cmd, [['pipe', 'r'], ['pipe', 'w'], ['pipe', 'w']], $pipes);
     if (!$proc) {
         throw new \RuntimeException("proc_open failed");
     }
     $code = null;
     while (true) {
         $status = proc_get_status($proc);
         if (!$status) {
             proc_terminate($proc);
             throw new \RuntimeException("Failed to get process status");
         }
         if (!$status['running']) {
             $out = stream_get_contents($pipes[1]);
             $err = stream_get_contents($pipes[2]);
             $code = $status['exitcode'];
             break;
         }
     }
     if (null === $code) {
         throw new \RuntimeException("Failed to execute '{$cmd}' - unknown result");
     }
     return ['out' => $out, 'err' => $err, 'code' => $code];
 }