int main(int argc, char *argv[]) { log_open("./core_log.txt"); //或许写成参数更好,懒得写了 atexit(output_result); //退出程序时的回调函数,用于输出判题结果 //为了构建沙盒,必须要有root权限 if (geteuid() != 0) { FM_LOG_FATAL("You must run this program as root."); exit(JUDGE_CONF::EXIT_UNPRIVILEGED); } parse_arguments(argc, argv); JUDGE_CONF::JUDGE_TIME_LIMIT += PROBLEM::time_limit; if (EXIT_SUCCESS != malarm(ITIMER_REAL, JUDGE_CONF::JUDGE_TIME_LIMIT)) { FM_LOG_WARNING("Set the alarm for this judge program failed, %d: %s", errno, strerror(errno)); exit(JUDGE_CONF::EXIT_VERY_FIRST); } signal(SIGALRM, timeout); compiler_source_code(); judge(); if (PROBLEM::spj) { run_spj(); } else { if (PROBLEM::result == JUDGE_CONF::SE) PROBLEM::result = compare_output(PROBLEM::output_file, PROBLEM::exec_output); } return 0; }
void solution::judge() throw (const char *) { char dir_name[MAXPATHLEN+16], input_filename[MAXPATHLEN+16]; char buffer[MAXPATHLEN*2+16]; puts("judge"); sprintf(dir_name, "%s/%d", DataDir, problem); DIR *dp = opendir(dir_name); if(dp == NULL) { error_code = RES_SE; last_state = "No data files"; throw "Can't open data dir"; } std::vector<std::string> in_files; struct dirent *ep; ep = readdir(dp); while(ep) { int len = strlen(ep->d_name); if(len > 3 && 0 == strcasecmp(ep->d_name + len - 3, ".in")) { in_files.push_back(std::string(ep->d_name)); } ep = readdir(dp); } closedir(dp); if(in_files.empty()) { error_code = RES_SE; last_state = "No data files"; throw "Data folder is empty"; } std::sort(in_files.begin(), in_files.end()); int total_score = 0, total_time = 0, max_memory = 0, dir_len = strlen(dir_name); const int full_score = 100; int case_score = full_score/in_files.size(); if(case_score <= 0) case_score = 1; int status; std::string tips; for(std::string &d_name : in_files) { sprintf(buffer, "%s/%s", dir_name, d_name.c_str()); puts(buffer); execute_info result; int get_score = case_score; if(run_judge(target_path, buffer, "user.out", time_limit, (lang_extra_mem[lang] + mem_limit) << 10 /*to byte*/, &result)) { error_code = RES_SE; last_state = "Cannot run target program"; throw "Cannot run target program"; }else if(result.state == 0) { int len = d_name.size()+dir_len+1; //dir+'/'+file buffer[len-2] = 'o'; buffer[len-1] = 'u'; buffer[len] = 't'; buffer[len+1] = '\0'; FILE *fanswer = fopen(buffer, "rb"); if(fanswer) { FILE *foutput = fopen("user.out", "rb"), *finput; if(foutput) { validator_info info; switch(compare_way >> 16) { case CMP_tra: #ifdef USE_CENA_VALIDATOR info = validator_cena(fanswer, foutput); #else info = validator(fanswer, foutput);//traditional OI comparison (Ignore trailing space) #endif break; case CMP_float: info = validator_float(fanswer, foutput, (compare_way & 0xffff)); //precision comparison break; case CMP_int: info = validator_int(fanswer, foutput); break; case CMP_spj: sprintf(input_filename, "%s/%s", dir_name, d_name.c_str()); info = run_spj(buffer, input_filename, &get_score, dir_name);//in call_ruc.cpp break; default: info.ret = -1; //validator error } fclose(foutput); int s = info.ret; if(!s) { status = RES_AC; tips = "Good Job!"; total_score += get_score; }else if(s == -1) { status = RES_VE; tips = "Please contact administrator."; get_score = 0; }else if(s == 4) { // for spj status = (get_score == case_score) ? RES_AC : RES_WA; total_score += get_score; tips = info.user_mismatch; free(info.user_mismatch); }else { status = RES_WA; get_score = 0; if(s == 1) { tips = "Output mismatch.\n Your: "; tips += info.user_mismatch; tips += "\nAnswer: "; tips += info.std_mismatch; free(info.user_mismatch); free(info.std_mismatch); } else if(s == 2) tips = "Your output is longer than standard output."; else if(s == 3) tips = "Your output is shorter than standard output."; else //unknown result tips = ""; } }else { status = RES_WA; get_score = 0; tips = "Cannot find output file."; } fclose(fanswer); }else {