judge_core/run/
executor.rs

1use 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// Removed executor unit tests, these test should run in sandbox