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;
}
Exemple #2
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 {