judge_core/run/
executor.rs1use crate::error::{path_not_exist, JudgeCoreError};
2use crate::{compiler::Language, utils::get_pathbuf_str};
3use nix::unistd::execve;
4use serde_derive::Serialize;
5use std::{convert::Infallible, ffi::CString, path::PathBuf};
6
7#[derive(Debug, Clone, Serialize)]
8pub struct Executor {
9 pub language: Language,
10 pub path: PathBuf,
11 pub additional_args: Vec<String>,
12}
13
14impl Executor {
15 pub fn new(language: Language, path: PathBuf) -> Result<Self, JudgeCoreError> {
16 if !path.exists() {
17 return Err(path_not_exist(&path));
18 }
19
20 Ok(Self {
21 language,
22 path,
23 additional_args: vec![],
24 })
25 }
26
27 pub fn set_additional_args(&mut self, args: Vec<String>) {
28 self.additional_args = args;
29 }
30
31 pub fn exec(&self) -> Result<Infallible, JudgeCoreError> {
32 let (command, args) = self.build_execute_cmd_with_args()?;
33 let mut final_args = args;
34 final_args.extend(self.additional_args.clone());
35 let c_args = final_args
36 .iter()
37 .map(|s| CString::new(s.as_bytes()))
38 .collect::<Result<Vec<_>, _>>()?;
39 log::debug!("execve: {:?} {:?}", command, c_args);
40 Ok(execve(
41 &CString::new(command)?,
42 c_args.as_slice(),
43 &[CString::new("")?],
44 )?)
45 }
46
47 fn build_execute_cmd_with_args(&self) -> Result<(String, Vec<String>), JudgeCoreError> {
48 let path_string = get_pathbuf_str(&self.path)?;
49 let command = match self.language {
50 Language::Rust => &path_string,
51 Language::Cpp => &path_string,
52 Language::Python => "/usr/bin/python3",
53 }
54 .to_owned();
55 let args = match self.language {
56 Language::Rust => vec![],
57 Language::Cpp => vec![],
58 Language::Python => {
59 vec![path_string]
60 }
61 };
62 Ok((command, args))
63 }
64}
65
66