Exemple #1
0
function complete_exec($command, $stdin = NULL, $timeout = 20, $pass_through = false)
{
    global $opt_verbose;
    if ($opt_verbose) {
        print "Running command: {$command}\n";
    }
    $descriptorspec = array(0 => array("pipe", "r"), 1 => array("pipe", "w"), 2 => array("pipe", "w"));
    $pipes = array();
    $handle = proc_open($command, $descriptorspec, &$pipes, getcwd());
    # read stdin into the process
    if ($stdin !== NULL) {
        fwrite($pipes[0], $stdin);
    }
    fclose($pipes[0]);
    unset($pipes[0]);
    // set non blocking to avoid infinite loops on stuck programs
    stream_set_blocking($pipes[1], 0);
    stream_set_blocking($pipes[2], 0);
    $out = "";
    $err = "";
    $start_time = time();
    do {
        $status = proc_get_status($handle);
        // It seems that with a large amount fo output, the process
        // won't finish unless the buffers are periodically cleared.
        // (This doesn't seem to be the case is async_test. I don't
        // know why).
        $new_out = stream_get_contents($pipes[1]);
        $new_err = stream_get_contents($pipes[2]);
        $out .= $new_out;
        $err .= $new_err;
        if ($pass_through) {
            print $new_out;
            file_put_contents("php://stderr", $new_err);
        }
        if ($timeout != 0 && time() > $start_time + $timeout) {
            $out = stream_get_contents($pipes[1]);
            $err = stream_get_contents($pipes[2]);
            kill_properly($handle, $pipes);
            return array("Timeout", $out, $err);
        }
        // Since we use non-blocking, the for loop could well take 100%
        // CPU. time of 1000 - 10000 seems OK. 100000 slows down the
        // program by 50%.
        usleep(10000);
    } while ($status["running"]);
    stream_set_blocking($pipes[1], 1);
    stream_set_blocking($pipes[2], 1);
    $out .= stream_get_contents($pipes[1]);
    $err .= stream_get_contents($pipes[2]);
    $exit_code = $status["exitcode"];
    kill_properly($handle, $pipes);
    return array($out, $err, $exit_code);
}
Exemple #2
0
 function check_running_procs()
 {
     // try to keep this really lightweight
     #		inst ("Check running");
     foreach ($this->running_procs as $index => $bundle) {
         $status = proc_get_status($bundle->handle);
         // read the streams in case they block
         $bundle->read_streams();
         if ($status["running"] !== true) {
             $bundle->exit = $status["exitcode"];
             unset($this->running_procs[$index]);
             // remove from the running list
             $bundle->continuation();
             // start the next bit straight away
         } else {
             if ($this->max_time != 0 && time() > $bundle->start_time + $this->max_time) {
                 kill_properly($bundle->handle, $bundle->pipes);
                 $bundle->exits[] = "Timeout";
                 $bundle->out .= "\n--- TIMEOUT ---";
                 $bundle->outs[] = $bundle->out;
                 $bundle->errs[] = $bundle->err;
                 $this->async_timeout("Timeout", $bundle);
                 unset($this->running_procs[$index]);
                 // remove from the running list
             } else {
                 // let it keep running
             }
         }
     }
 }