diff --git a/Cargo.lock b/Cargo.lock index 03d1846..45b4be7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -224,6 +224,12 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "indoc" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa799dd5ed20a7e349f3b4639aa80d74549c81716d9ec4f994c9b5815598306" + [[package]] name = "instant" version = "0.1.12" @@ -287,6 +293,16 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" +[[package]] +name = "lock_api" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +dependencies = [ + "autocfg", + "scopeguard", +] + [[package]] name = "memchr" version = "2.5.0" @@ -302,6 +318,15 @@ dependencies = [ "autocfg", ] +[[package]] +name = "memoffset" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +dependencies = [ + "autocfg", +] + [[package]] name = "nix" version = "0.26.2" @@ -311,7 +336,7 @@ dependencies = [ "bitflags 1.3.2", "cfg-if", "libc", - "memoffset", + "memoffset 0.7.1", "pin-utils", "static_assertions", ] @@ -335,6 +360,29 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + [[package]] name = "pin-utils" version = "0.1.0" @@ -359,11 +407,72 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "pyo3" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb88ae05f306b4bfcde40ac4a51dc0b05936a9207a4b75b798c7729c4258a59" +dependencies = [ + "cfg-if", + "indoc", + "libc", + "memoffset 0.9.0", + "parking_lot", + "pyo3-build-config", + "pyo3-ffi", + "pyo3-macros", + "unindent", +] + +[[package]] +name = "pyo3-build-config" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "554db24f0b3c180a9c0b1268f91287ab3f17c162e15b54caaae5a6b3773396b0" +dependencies = [ + "once_cell", + "target-lexicon", +] + +[[package]] +name = "pyo3-ffi" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "922ede8759e8600ad4da3195ae41259654b9c55da4f7eec84a0ccc7d067a70a4" +dependencies = [ + "libc", + "pyo3-build-config", +] + +[[package]] +name = "pyo3-macros" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a5caec6a1dd355964a841fcbeeb1b89fe4146c87295573f94228911af3cc5a2" +dependencies = [ + "proc-macro2 1.0.64", + "pyo3-macros-backend", + "quote 1.0.29", + "syn 1.0.109", +] + +[[package]] +name = "pyo3-macros-backend" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0b78ccbb160db1556cdb6fd96c50334c5d4ec44dc5e0a968d0a1208fa0efa8b" +dependencies = [ + "proc-macro2 1.0.64", + "quote 1.0.29", + "syn 1.0.109", +] + [[package]] name = "python_judger" version = "0.1.0" dependencies = [ "libnoj", + "pyo3", ] [[package]] @@ -420,6 +529,12 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + [[package]] name = "serde" version = "1.0.171" @@ -435,6 +550,12 @@ dependencies = [ "serde", ] +[[package]] +name = "smallvec" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" + [[package]] name = "static_assertions" version = "1.1.0" @@ -458,6 +579,17 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2 1.0.64", + "quote 1.0.29", + "unicode-ident", +] + [[package]] name = "syn" version = "2.0.26" @@ -469,6 +601,12 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "target-lexicon" +version = "0.12.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d2faeef5759ab89935255b1a4cd98e0baf99d1085e37d36599c625dac49ae8e" + [[package]] name = "tempfile" version = "3.6.0" @@ -529,6 +667,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" +[[package]] +name = "unindent" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1766d682d402817b5ac4490b3c3002d91dfa0d22812f341609f97b08757359c" + [[package]] name = "utf8parse" version = "0.2.1" diff --git a/src/default_judger.rs b/src/default_judger.rs index 2808701..47ee731 100644 --- a/src/default_judger.rs +++ b/src/default_judger.rs @@ -19,4 +19,4 @@ impl DefaultJudger { pub fn create_instance() -> Box { Box::new(DefaultJudger {}) } -} \ No newline at end of file +} diff --git a/src/lib/src/context.rs b/src/lib/src/context.rs index 3eff471..760de88 100644 --- a/src/lib/src/context.rs +++ b/src/lib/src/context.rs @@ -12,4 +12,4 @@ impl Context { line_num: 0, } } -} \ No newline at end of file +} diff --git a/src/lib/src/env.rs b/src/lib/src/env.rs index d0bf39e..6e628d9 100644 --- a/src/lib/src/env.rs +++ b/src/lib/src/env.rs @@ -22,17 +22,70 @@ impl Env { let table = src_str.parse::()?; Ok(Self { - cwd: table.get("cwd").unwrap_or(&Value::from("./")).as_str().ok_or("cwd should be String type")?.to_string(), - large_stack: table.get("large-stack").unwrap_or(&Value::from(false)).as_bool().ok_or("large-stack should be Boolean type")?, - max_process: table.get("max-process").unwrap_or(&Value::from(1)).as_integer().ok_or("max-process should be Integer type")? as i32, - memory_limit: table.get("memory-limit").unwrap_or(&Value::from(1000000)).as_integer().ok_or("memory-limit should be Integer type")? as u64, - output_file: table.get("output").unwrap_or(&Value::from("./out")).as_str().ok_or("output should be String type")?.to_string(), - output_size_limit: table.get("output-size-limit").unwrap_or(&Value::from(100000)).as_integer().ok_or("output-size-limit should be Integer type")? as u64, - runtime_limit: table.get("runtime-limit").unwrap_or(&Value::from(1000000)).as_integer().ok_or("runtime-limit should be Integer type")? as u64, - stderr: table.get("stderr").ok_or("Stderr don't have default value").unwrap().as_str().ok_or("stderr should be String type")?.to_string(), - stdin: table.get("stdin").ok_or("Stdin don't have default value").unwrap().as_str().ok_or("stdin should be String type")?.to_string(), - stdout: table.get("stdout").ok_or("Stdout don't have default value").unwrap().as_str().ok_or("stdout should be String type")?.to_string(), - lang: table.get("lang").unwrap_or(&Value::from(0)).as_integer().ok_or("lang should be Integer type")? as u64, + cwd: table + .get("cwd") + .unwrap_or(&Value::from("./")) + .as_str() + .ok_or("cwd should be String type")? + .to_string(), + large_stack: table + .get("large-stack") + .unwrap_or(&Value::from(false)) + .as_bool() + .ok_or("large-stack should be Boolean type")?, + max_process: table + .get("max-process") + .unwrap_or(&Value::from(1)) + .as_integer() + .ok_or("max-process should be Integer type")? as i32, + memory_limit: table + .get("memory-limit") + .unwrap_or(&Value::from(1000000)) + .as_integer() + .ok_or("memory-limit should be Integer type")? as u64, + output_file: table + .get("output") + .unwrap_or(&Value::from("./out")) + .as_str() + .ok_or("output should be String type")? + .to_string(), + output_size_limit: table + .get("output-size-limit") + .unwrap_or(&Value::from(100000)) + .as_integer() + .ok_or("output-size-limit should be Integer type")? + as u64, + runtime_limit: table + .get("runtime-limit") + .unwrap_or(&Value::from(1000000)) + .as_integer() + .ok_or("runtime-limit should be Integer type")? as u64, + stderr: table + .get("stderr") + .ok_or("Stderr don't have default value") + .unwrap() + .as_str() + .ok_or("stderr should be String type")? + .to_string(), + stdin: table + .get("stdin") + .ok_or("Stdin don't have default value") + .unwrap() + .as_str() + .ok_or("stdin should be String type")? + .to_string(), + stdout: table + .get("stdout") + .ok_or("Stdout don't have default value") + .unwrap() + .as_str() + .ok_or("stdout should be String type")? + .to_string(), + lang: table + .get("lang") + .unwrap_or(&Value::from(0)) + .as_integer() + .ok_or("lang should be Integer type")? as u64, }) } } @@ -108,4 +161,4 @@ mod tests { stderr = 'path/to/stderr' # The stdout path of the spawned process"; assert!(Env::new(&config_str).is_err()); } -} \ No newline at end of file +} diff --git a/src/lib/src/lang.rs b/src/lib/src/lang.rs index 75efdc9..f591dea 100644 --- a/src/lib/src/lang.rs +++ b/src/lib/src/lang.rs @@ -11,18 +11,10 @@ impl TryFrom for Lang { type Error = &'static str; fn try_from(value: u64) -> Result { match value { - 0 => { - Ok(Self::C) - } - 1 => { - Ok(Self::CPP) - } - 2 => { - Ok(Self::PYTHON) - } - _ => { - Err("Language id not found") - } + 0 => Ok(Self::C), + 1 => Ok(Self::CPP), + 2 => Ok(Self::PYTHON), + _ => Err("Language id not found"), } } } @@ -31,16 +23,33 @@ fn rust_string_vec_to_c_string_vec(vec: Vec<&'static str>) -> Vec { vec.iter().map(|e| CString::new(*e).unwrap()).collect() } - impl Lang { pub fn get_compile_argv(self) -> Vec { match self { - Self::C => { - rust_string_vec_to_c_string_vec(vec!["gcc", "-DONLINE_JUDGE", "-O2", "-w", "-fmax-errors=3", "-std=c11", "main.c", "-lm", "-o", "main"]) - } - Self::CPP => { - rust_string_vec_to_c_string_vec(vec!["g++", "-DONLINE_JUDGE", "-O2", "-w", "-fmax-errors=3", "-std=c++17", "main.cpp", "-lm", "-o", "main"]) - } + Self::C => rust_string_vec_to_c_string_vec(vec![ + "gcc", + "-DONLINE_JUDGE", + "-O2", + "-w", + "-fmax-errors=3", + "-std=c11", + "main.c", + "-lm", + "-o", + "main", + ]), + Self::CPP => rust_string_vec_to_c_string_vec(vec![ + "g++", + "-DONLINE_JUDGE", + "-O2", + "-w", + "-fmax-errors=3", + "-std=c++17", + "main.cpp", + "-lm", + "-o", + "main", + ]), Self::PYTHON => { vec![] } @@ -49,17 +58,9 @@ impl Lang { pub fn get_execute_argv(self) -> Vec { match self { - Self::C => { - rust_string_vec_to_c_string_vec(vec!["./main"]) - } - Self::CPP => { - rust_string_vec_to_c_string_vec(vec!["./main"]) - } - Self::PYTHON => { - rust_string_vec_to_c_string_vec(vec!["/usr/bin/python3", "main.py"]) - } + Self::C => rust_string_vec_to_c_string_vec(vec!["./main"]), + Self::CPP => rust_string_vec_to_c_string_vec(vec!["./main"]), + Self::PYTHON => rust_string_vec_to_c_string_vec(vec!["/usr/bin/python3", "main.py"]), } } } - - diff --git a/src/lib/src/lib.rs b/src/lib/src/lib.rs index febdbfd..c6414bc 100644 --- a/src/lib/src/lib.rs +++ b/src/lib/src/lib.rs @@ -4,12 +4,11 @@ pub use lang::Lang; pub use plugin::find_plugin; pub use plugin::register_plugin; -mod env; mod context; +mod env; mod lang; mod plugin; - pub trait Judger { fn do_before_run(&mut self, e: &mut Env); fn do_in_run(&mut self, c: Context); @@ -18,5 +17,3 @@ pub trait Judger { fn is_interactive(&self) -> bool; fn get_plugin_name(&self) -> &'static str; } - - diff --git a/src/lib/src/plugin.rs b/src/lib/src/plugin.rs index 5d2400e..bd5ee7a 100644 --- a/src/lib/src/plugin.rs +++ b/src/lib/src/plugin.rs @@ -21,4 +21,3 @@ pub fn find_plugin() -> Option> { None } } - diff --git a/src/main.rs b/src/main.rs index 4f0fa76..d44189e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,9 +10,9 @@ use clap::Parser; use libnoj::Env; use runner::run; -mod runner; -mod plugin_manager; mod default_judger; +mod plugin_manager; +mod runner; #[derive(Parser, Debug)] #[command(author, version, about)] @@ -35,4 +35,4 @@ fn main() { let args = Args::parse(); let environment = parse_env_from_file(&args.env_path); run(args.dl_path, environment) -} \ No newline at end of file +} diff --git a/src/plugin/python_judger/Cargo.toml b/src/plugin/python_judger/Cargo.toml index ef5edeb..5305826 100644 --- a/src/plugin/python_judger/Cargo.toml +++ b/src/plugin/python_judger/Cargo.toml @@ -6,4 +6,5 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +pyo3 = "0.19.1" libnoj = { path = "../../lib/" } \ No newline at end of file diff --git a/src/plugin/python_judger/src/lib.rs b/src/plugin/python_judger/src/lib.rs index e69de29..ef9217b 100644 --- a/src/plugin/python_judger/src/lib.rs +++ b/src/plugin/python_judger/src/lib.rs @@ -0,0 +1,36 @@ +use libnoj::Judger; +use libnoj::{register_plugin, Context, Env}; + +struct PythonJudger; + +impl Judger for PythonJudger { + fn do_before_run(&mut self, e: &mut Env) { + todo!() + } + fn do_in_run(&mut self, c: Context) { + todo!() + } + fn do_after_run(&mut self, e: &mut Env) { + todo!() + } + fn judge_result(&mut self, e: &mut Env) { + todo!() + } + fn is_interactive(&self) -> bool { + todo!() + } + fn get_plugin_name(&self) -> &'static str { + todo!() + } +} + +impl PythonJudger { + fn create_instance() -> Box { + Box::new(PythonJudger {}) + } +} + +#[no_mangle] +fn plugin_init() { + register_plugin(PythonJudger::create_instance); +} diff --git a/src/plugin_manager.rs b/src/plugin_manager.rs index 507c648..061e423 100644 --- a/src/plugin_manager.rs +++ b/src/plugin_manager.rs @@ -6,8 +6,7 @@ struct PluginApi { } pub fn load_plugin(path: &str) { - let mut cont: Container = - unsafe { Container::load(path) }.unwrap(); + let mut cont: Container = unsafe { Container::load(path) }.unwrap(); unsafe { cont.plugin_init(); } diff --git a/src/runner.rs b/src/runner.rs index 6943103..ef48fba 100644 --- a/src/runner.rs +++ b/src/runner.rs @@ -1,4 +1,3 @@ -use std::{thread, time}; use std::ffi::CStr; use std::fs::{File, Permissions}; use std::io::{BufWriter, Write}; @@ -6,12 +5,16 @@ use std::os::fd::AsRawFd; use std::os::unix::fs::PermissionsExt; use std::path::Path; use std::sync::{Arc, Mutex}; +use std::{thread, time}; use fork::{daemon, Fork}; -use nix::libc::{execvp, STDERR_FILENO, STDIN_FILENO, STDOUT_FILENO, strsignal, waitpid, WEXITSTATUS, WIFEXITED, WTERMSIG}; -use nix::sys::resource::{getrusage, setrlimit}; +use nix::libc::{ + execvp, strsignal, waitpid, STDERR_FILENO, STDIN_FILENO, STDOUT_FILENO, WEXITSTATUS, WIFEXITED, + WTERMSIG, +}; use nix::sys::resource::Resource::{RLIMIT_AS, RLIMIT_CPU, RLIMIT_FSIZE, RLIMIT_NPROC}; use nix::sys::resource::UsageWho::RUSAGE_CHILDREN; +use nix::sys::resource::{getrusage, setrlimit}; use nix::sys::signal; use nix::sys::signal::{Signal, SIGTERM, SIGXCPU, SIGXFSZ}; use nix::sys::time::TimeValLike; @@ -29,12 +32,16 @@ fn run_inner(mut judger: Box, mut env: Env) { if let Ok(Fork::Parent(pid)) = daemon(true, true) { judger.do_before_run(&mut env); - let mut writer = BufWriter::new(File::options().write(true).open(Path::new(&env.output_file)).unwrap()); + let mut writer = BufWriter::new( + File::options() + .write(true) + .open(Path::new(&env.output_file)) + .unwrap(), + ); let tle_flag_atomic = Arc::new(Mutex::new(false)); let tle_flag_atomic_inner = Arc::clone(&tle_flag_atomic); - let mut stat = 0; thread::spawn(move || { @@ -61,9 +68,19 @@ fn run_inner(mut judger: Box, mut env: Env) { } else if (usage.max_rss() * 1024) as u64 > env.memory_limit { write!(&mut writer, "MLE\nWEXITSTATUS() = {}\n", WEXITSTATUS(stat)).unwrap() } else if WEXITSTATUS(stat) != 0 { - write!(&mut writer, "RE\nWIFEXITED - WEXITSTATUS() = {}\n", WEXITSTATUS(stat)).unwrap(); + write!( + &mut writer, + "RE\nWIFEXITED - WEXITSTATUS() = {}\n", + WEXITSTATUS(stat) + ) + .unwrap(); } else { - write!(&mut writer, "Exited Normally\nWIFEXITED - WEXITSTATUS() = {}\n", WEXITSTATUS(stat)).unwrap(); + write!( + &mut writer, + "Exited Normally\nWIFEXITED - WEXITSTATUS() = {}\n", + WEXITSTATUS(stat) + ) + .unwrap(); } } else { let sig = WTERMSIG(stat); @@ -73,14 +90,35 @@ fn run_inner(mut judger: Box, mut env: Env) { } match Signal::try_from(sig).unwrap() { SIGXCPU => { - write!(&mut writer, "TLE\nWEXITSTATUS() = {}, WTERMSIG() = {} ({})\n", WEXITSTATUS(stat), sig, sig_str).unwrap(); + write!( + &mut writer, + "TLE\nWEXITSTATUS() = {}, WTERMSIG() = {} ({})\n", + WEXITSTATUS(stat), + sig, + sig_str + ) + .unwrap(); tle_flag = true } SIGXFSZ => { - write!(&mut writer, "OLE\nWEXITSTATUS() = {}, WTERMSIG() = {} ({})\n", WEXITSTATUS(stat), sig, sig_str).unwrap(); + write!( + &mut writer, + "OLE\nWEXITSTATUS() = {}, WTERMSIG() = {} ({})\n", + WEXITSTATUS(stat), + sig, + sig_str + ) + .unwrap(); } _ => { - write!(&mut writer, "RE\nWEXITSTATUS() = {}, WTERMSIG() = {} ({})\n", WEXITSTATUS(stat), sig, sig_str).unwrap(); + write!( + &mut writer, + "RE\nWEXITSTATUS() = {}, WTERMSIG() = {} ({})\n", + WEXITSTATUS(stat), + sig, + sig_str + ) + .unwrap(); } } } @@ -93,30 +131,75 @@ fn run_inner(mut judger: Box, mut env: Env) { judger.do_after_run(&mut env); } else { let lang = Lang::try_from(env.lang).unwrap(); - setrlimit(RLIMIT_AS, env.memory_limit * 1024, env.memory_limit * 1024 + 1024).unwrap(); + setrlimit( + RLIMIT_AS, + env.memory_limit * 1024, + env.memory_limit * 1024 + 1024, + ) + .unwrap(); setrlimit(RLIMIT_FSIZE, env.output_size_limit, env.output_size_limit).unwrap(); - setrlimit(RLIMIT_CPU, env.runtime_limit / 1000 + 1 + if env.runtime_limit % 1000 >= 800 { 0 } else { 1 } - , env.runtime_limit / 1000 + 2 + if env.runtime_limit % 1000 >= 800 { 0 } else { 1 }).unwrap(); - setrlimit(RLIMIT_NPROC, (env.max_process + 1) as nix::libc::rlim_t, (env.max_process + 1) as nix::libc::rlim_t).unwrap(); + setrlimit( + RLIMIT_CPU, + env.runtime_limit / 1000 + + 1 + + if env.runtime_limit % 1000 >= 800 { + 0 + } else { + 1 + }, + env.runtime_limit / 1000 + + 2 + + if env.runtime_limit % 1000 >= 800 { + 0 + } else { + 1 + }, + ) + .unwrap(); + setrlimit( + RLIMIT_NPROC, + (env.max_process + 1) as nix::libc::rlim_t, + (env.max_process + 1) as nix::libc::rlim_t, + ) + .unwrap(); { - let input = File::options().read(true).open(Path::new(&env.stdin)).unwrap(); + let input = File::options() + .read(true) + .open(Path::new(&env.stdin)) + .unwrap(); dup2(input.as_raw_fd(), STDIN_FILENO).unwrap(); } { - let output = File::options().write(true).create(true).open(Path::new(&env.stdout)).unwrap(); - output.set_permissions(Permissions::from_mode(0o644)).unwrap(); + let output = File::options() + .write(true) + .create(true) + .open(Path::new(&env.stdout)) + .unwrap(); + output + .set_permissions(Permissions::from_mode(0o644)) + .unwrap(); dup2(output.as_raw_fd(), STDOUT_FILENO).unwrap(); } { - let err = File::options().write(true).create(true).open(Path::new(&env.stderr)).unwrap(); + let err = File::options() + .write(true) + .create(true) + .open(Path::new(&env.stderr)) + .unwrap(); err.set_permissions(Permissions::from_mode(0o644)).unwrap(); dup2(err.as_raw_fd(), STDERR_FILENO).unwrap(); } unsafe { - execvp(lang.get_execute_argv()[0].as_ptr(), - lang.get_execute_argv().iter().map(|m| { m.as_ptr() }).collect::>().as_ptr()); + execvp( + lang.get_execute_argv()[0].as_ptr(), + lang.get_execute_argv() + .iter() + .map(|m| m.as_ptr()) + .collect::>() + .as_ptr(), + ); } } } @@ -136,4 +219,3 @@ pub fn run(dl_path: String, environment: Env) { run_inner(judger, environment); } -