Skip to content

Commit

Permalink
Add compiler timeout
Browse files Browse the repository at this point in the history
  • Loading branch information
slhmy committed Oct 2, 2024
1 parent 7536349 commit dfd1a2f
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 16 deletions.
1 change: 1 addition & 0 deletions judge-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ serde = "1"
serde_derive = "1"
serde_json = "1"
serde_yaml = "0.9"
wait-timeout = "0.2"

[dev-dependencies]
# Need to lock the version of env_logger to 0.10.0
Expand Down
52 changes: 36 additions & 16 deletions judge-core/src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ use crate::error::JudgeCoreError;
use crate::utils::get_pathbuf_str;
use anyhow::anyhow;
use serde_derive::{Deserialize, Serialize};
use wait_timeout::ChildExt;
use std::path::PathBuf;
use std::process::Stdio;
use std::time::Duration;
use std::{fmt, fs};
use std::{process::Command, str::FromStr};

Expand All @@ -13,6 +16,8 @@ const RUST_COMPILE_COMMAND_TEMPLATE: &str = "rustc {src_path} -o {target_path}";
const CPP_COMPILE_COMMAND_TEMPLATE: &str = "g++ {src_path} -o {target_path} -O2 -static";
const PYTHON_COMPILE_COMMAND_TEMPLATE: &str = "cp {src_path} {target_path}";

const COMPILE_TIMEOUT: Duration = Duration::from_secs(15);

#[derive(Clone)]
struct CommandBuilder {
command_template: String,
Expand Down Expand Up @@ -162,22 +167,37 @@ impl Compiler {
std::fs::remove_file(target_path)?;
}

let output = Command::new("sh")
.arg("-c")
.arg(
self.command_builder
.get_command(vec![src_path_string, target_path_string]),
)
.args(self.compiler_args.iter())
.output()?;
if output.status.success() {
let compile_output = String::from_utf8_lossy(&output.stdout).to_string();
log::debug!("Compile output: {}", compile_output);
Ok(compile_output)
} else {
let error_output = String::from_utf8_lossy(&output.stderr).to_string();
log::error!("Compile error: {}", error_output);
Err(JudgeCoreError::CompileError(error_output))
let mut child = Command::new("sh")
.arg("-c")
.arg(
self.command_builder
.get_command(vec![src_path_string, target_path_string]),
)
.args(self.compiler_args.iter())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()?;

match child.wait_timeout(COMPILE_TIMEOUT)? {
Some(status) => {
if status.success() {
let output = child.wait_with_output()?;
let compile_output = String::from_utf8_lossy(&output.stdout).to_string();
log::debug!("Compile output: {}", compile_output);
Ok(compile_output)
} else {
let output = child.wait_with_output()?;
let error_output = String::from_utf8_lossy(&output.stderr).to_string();
log::error!("Compile error: {}", error_output);
Err(JudgeCoreError::CompileError(error_output))
}
}
None => {
child.kill()?;
let error_output = "Compile process timed out".to_string();
log::error!("Compile error: {}", error_output);
Err(JudgeCoreError::CompileError(error_output))
}
}
}
}

0 comments on commit dfd1a2f

Please sign in to comment.