') { return $arg[0].escapeshellarg($arg[1]); } else { return escapeshellarg("--{$arg[0]}={$arg[1]}"); } } else { return false; } } public static function getCmd($cmd) { if (is_array($cmd)) { return implode(' ', array_map('UOJLocalRun::escapearg', $cmd)); } elseif (is_string($cmd)) { return $cmd; } else { return false; } } public static function exec($cmd, array $runp_options=null) { $cmd = static::getCmd($cmd); if ($cmd === false) { return false; } if ($runp_options) { $res_path = tempnam('/tmp', 'runp'); if ($res_path === false) { UOJLog::error("UOJLocalRun::exec: failed to create res file. cmd: {$cmd}"); return false; } $cmd = implode(' ', [ escapeshellarg(static::$judger_main_path.'/run/run_program'), static::getCmd([['res', $res_path]]), static::getCmd($runp_options), $cmd ]); } $ret = []; if (exec($cmd, $ret['output'], $status) === false || $status != 0) { UOJLog::error("exec failed with status {$status}. cmd: {$cmd}"); foreach ($ret['output'] as $line) { UOJLog::error("exec failed. output: {$line}"); } return false; } if ($runp_options) { $fp = fopen($res_path, "r"); if ($fp === false) { UOJLog::error("UOJLocalRun::exec: failed to open res file ({$res_path}). cmd: {$cmd}"); return false; } if (fscanf($fp, '%d %d %d %d', $ret['rstype'], $ret['used_time'], $ret['used_memory'], $ret['exit_code']) != 4) { $ret['rstype'] = 7; } fclose($fp); unlink($res_path); } return $ret; } public static function execAnd(array $cmds, array $runp_options=null) { return static::exec(implode(' && ', array_map('UOJLocalRun::getCmd', $cmds)), $runp_options); } public static function formatter(string $src, string $dest, array $runp_options=null) { return static::exec([ static::$judger_main_path.'/run/formatter', ['<', $src], ['>', $dest] ], $runp_options); } public static function compile(string $name, array $options, array $runp_options=null) { return static::exec([ static::$judger_main_path.'/run/compile', ...$options, $name ], $runp_options); } } UOJLocalRun::$judger_main_path = realpath('/opt/uoj/judger/uoj_judger'); UOJLocalRun::$judger_include_path = UOJLocalRun::$judger_main_path.'/include'; UOJLocalRun::$judger_run_path = UOJLocalRun::$judger_main_path.'/run';