コード例 #1
0
function run_script(&$env, $cmd)
{
    /* Only fork once, if there are many sequential script invocations.
     * The father returns "success", and the son will treat the rest
     * of the action chain.
     */
    if (!@$env["HAS_FORKED"] && !@$env["IS_SON"] && !@$env["IS_GLOBAL"]) {
        global $FORKS;
        // clean the connection cache: mysql seems to be disturbed by fork()
        _db_close();
        flush();
        // fork a process for execution of the script
        $pid = pcntl_fork();
        if ($pid < 0) {
            // error
            engine_error("could not fork() a new process for command '{$cmd}'");
            return false;
        }
        if ($pid > 0) {
            // father
            //echo "FORK.....$pid\n";
            $env["HAS_FORKED"] = true;
            $FORKS[$pid] = $cmd;
            return true;
        }
        // son
        $env["IS_SON"] = true;
        $pid = getmypid();
        check_answer($env, "FORKED {$pid}");
        //global $debug; $debug = true;
    }
    $pipes = array();
    $descr = array(0 => array("file", "/dev/null", "r"), 1 => array("pipe", "w"), 2 => array("pipe", "w"));
    //echo "cmd: $cmd\n";
    $proc = proc_open($cmd, $descr, $pipes);
    if (!$proc) {
        engine_error("proc_open() on command '{$cmd}' failed");
        exit(-1);
    }
    $pid = proc_get_status($proc);
    $pid = @$pid["pid"];
    $ok = true;
    $ok &= check_answer($env, "START {$pid} ({$cmd})");
    $timeout = $env["rule_timeout"];
    if ($timeout < 1) {
        $timeout = 3600 * 24 * 365;
    }
    do {
        $tests = $pipes;
        // create a copy, because stream_select() will modifiy it
        $dummy1 = null;
        $dummy2 = null;
        $status = stream_select($tests, $dummy1, $dummy2, $timeout);
        if (!$status) {
            // timeout
            $ok &= check_answer($env, "TIMEOUT {$pid} {$timeout}");
        }
        $closed = 0;
        foreach ($tests as $stream) {
            if (feof($stream)) {
                $closed++;
                continue;
            }
            $line = chop(fgets($stream));
            $ok &= check_answer($env, $line);
        }
        if (!$ok) {
            // kill it...
            engine_log("killing process {$pid}");
            proc_terminate($proc);
            check_answer($env, "KILL {$pid}");
            exit(1);
        }
    } while ($closed < 2);
    fclose($pipes[1]);
    fclose($pipes[2]);
    $has_reported = false;
    if (true) {
        $code = pcntl_waitpid($pid, $status, 0);
        if ($code > 0) {
            if (pcntl_wifsignaled($status)) {
                $status = pcntl_wtermsig($status);
                check_answer($env, "SIGNALED {$code} {$status}");
            }
            if (pcntl_wifexited($status)) {
                $status = pcntl_wexitstatus($status);
                check_answer($env, "STATUS {$code} {$status}");
                $has_reported = true;
            }
        }
    }
    if (!$has_reported) {
        // after waitpid(), the zombie is lost => proc_close() will no longer work
        $status = proc_close($proc);
        check_answer($env, "STATUS {$pid} {$status}");
    }
    return true;
}
コード例 #2
0
function mysql_multiquery(&$env, $mysqli, $query, $cb_list)
{
    global $ERROR;
    global $debug;
    if (!is_a($mysqli, "mysqli")) {
        echo "internal error: bad mysqli object ";
        print_r($mysqli);
        echo "<br>\n";
        return false;
    }
    $cb = "";
    if ($cb_list) {
        $cb = array_shift($cb_list);
    }
    $next = $mysqli->multi_query($query);
    if (!$next) {
        $ERROR .= $mysqli->error;
        if ($debug) {
            echo "<br>\nmultiquery error '{$ERROR}' on first query ({$query})<br>\n";
            echo "next='";
            print_r($next);
            echo "'<br>\n";
            echo "is_bool(next)='";
            print_r(is_bool($next));
            echo "'<br>\n";
            echo "<br>\n";
        }
        _db_close($mysqli);
        return false;
    } elseif ($cb) {
        $next = $mysqli->use_result();
        //print_r($next);
        if ($debug) {
            echo "first callback '{$cb}'<br>\n";
        }
        $next = $cb($env, $next);
    }
    $env["RES"][] = $next;
    while ($mysqli->more_results() && !@$env["ERROR"]) {
        if ($cb_list) {
            $cb = array_shift($cb_list);
        }
        $next = $mysqli->next_result();
        if (!$next) {
            $ERROR .= $mysqli->error;
            _db_close($mysqli);
            return false;
        } elseif ($cb) {
            $next = $mysqli->use_result();
            if ($debug) {
                echo "next callback '{$cb}'<br>\n";
            }
            $next = $cb($env, $next);
        }
        $env["RES"][] = $next;
    }
    if (@$env["ERROR"]) {
        _db_close($mysqli);
        return false;
    }
    return true;
}