该模块为编译运行功能,该模块需要使用json库,首先安装json,作用是将结构化的数据转化为字符串,做序列化和反序列化工作
命令:sudo yum install jsoncpp-devel
整体逻辑
Start函数
1
| static void Start(const std::string &in_json, std::string *out_json){}
|
Start函数参数
start函数的两个参数
in_json
: {“code”: “#include …”, “input”: “”, “cpu_limit”: 1, “mem_limit”:10240}
out_json
: {“status”:0, “reason”:“”, “stdout”:“”, “stderr”:“”}
in_json字符串中的内容
code
: 用户提交的代码
input
: 用户给自己提交的代码对应的输入,暂不做处理
cpu_limit
: 时间要求
mem_limit
: 空间要求
out_json字符串中的内容
status
: 状态码 (必填)
reason
: 请求结果 (必填)
stdout
: 程序运行完结果 (选填)
stderr
: 运行完的错误结果
Start函数逻辑
- 反序列化解析
in_json
字符串内容
- 根据
in_json
中的内容(代码、输入、限制条件)编译运行
- 将编译运行期间的状态、结果、错误等信息序列化,通过输出型参数
out_json
输出
具体细节代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
| static void Start(const std::string &in_json, std::string *out_json) { Json::Value in_value; Json::Reader reader; reader.parse(in_json, in_value);
std::string code = in_value["code"].asString(); std::string input = in_value["input"].asString(); int cpu_limit = in_value["cpu_limit"].asInt(); int mem_limit = in_value["mem_limit"].asInt();
int status_code=0; Json::Value out_value; int run_result = 0;
std::string file_name;
if(code.size()==0) { status_code = -1; goto END; }
file_name = FileUtil::UniqFileName();
if(!FileUtil::WriteFile(PathUtil::Src(file_name), code)) { status_code=-2; goto END; }
if(!Compiler::Compile(file_name)) { status_code=-3; goto END; }
run_result=Runner::Run(file_name, cpu_limit, mem_limit); if(run_result<0) { status_code=-2; } else if(run_result>0) { status_code=run_result; } else { status_code=0; } END: out_value["status"]=status_code; out_value["reason"]=CodeToDesc(status_code, file_name);
if(status_code==0) { std::string _stdout; FileUtil::ReadFile(PathUtil::Stdout(file_name), &_stdout, true); out_value["stdout"]=_stdout;
std::string _stderr; FileUtil::ReadFile(PathUtil::Stderr(file_name), &_stderr, true); out_value["stderr"]=_stderr; }
Json::StyledWriter writer; *out_json=writer.write(out_value);
RemoveTempFile(file_name);
}
|
补充工具类函数
状态码解析CodeToDesc
作用:将状态码解析为对应字符串
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| static std::string CodeToDesc(int code, const std::string& file_name) { std::string desc; switch(code) { case 0: desc="编译运行成功"; break; case -1: desc="提交的代码为空"; break; case -2: desc="未知错误"; break; case -3: FileUtil::ReadFile(PathUtil::CompilerError(file_name), &desc, true); break; case SIGABRT: desc="内存超过范围"; break; case SIGXCPU: desc="CPU使用超时"; break; case SIGFPE: desc="浮点数溢出"; break; default: desc="未知"+std::to_string(code); break; } return desc; }
|
形成唯一文件名UniqFileName
1 2 3 4 5 6 7 8 9 10 11 12
|
static std::string UniqFileName() { static std::atomic_uint id(0); id++;
std::string ms = TimeUtil::GetTimeMs(); std::string uniq_id = std::to_string(id); return ms+"_"+uniq_id; }
|
删除临时文件RemoveTempFile
- 判断文件是否存在
- 若存在使用unlink函数进行删除
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| static void RemoveTempFile(const std::string &file_name) { std::string _src = PathUtil::Src(file_name); if(FileUtil::IsFileExists(_src)) unlink(_src.c_str()); std::string _compiler_error=PathUtil::CompilerError(file_name); if(FileUtil::IsFileExists(_compiler_error)) unlink(_compiler_error.c_str()); std::string _execute=PathUtil::Exe(file_name); if(FileUtil::IsFileExists(_execute)) unlink(_execute.c_str()); std::string _stdin=PathUtil::Stdin(file_name); if(FileUtil::IsFileExists(_stdin)) unlink(_stdin.c_str()); std::string _stdout=PathUtil::Stdout(file_name); if(FileUtil::IsFileExists(_stdout)) unlink(_stdout.c_str()); std::string _stderr=PathUtil::Stderr(file_name); if(FileUtil::IsFileExists(_stderr)) unlink(_stderr.c_str()); }
|