use evalbox_sys::last_errno;
use rustix::io::Errno;
use crate::plan::Plan;
pub fn apply_rlimits(plan: &Plan) -> Result<(), Errno> {
let cpu_secs = plan.timeout.as_secs().saturating_mul(2).saturating_add(60);
set_rlimit(libc::RLIMIT_DATA, plan.memory_limit)?;
set_rlimit(libc::RLIMIT_CPU, cpu_secs)?;
set_rlimit(libc::RLIMIT_FSIZE, plan.max_output)?;
set_rlimit(libc::RLIMIT_NOFILE, 256)?;
set_rlimit(libc::RLIMIT_NPROC, u64::from(plan.max_pids))?;
set_rlimit(libc::RLIMIT_CORE, 0)?;
set_rlimit(libc::RLIMIT_STACK, 8 * 1024 * 1024)?;
Ok(())
}
#[inline]
fn set_rlimit(resource: libc::__rlimit_resource_t, limit: u64) -> Result<(), Errno> {
let rlim = libc::rlimit {
rlim_cur: limit,
rlim_max: limit,
};
if unsafe { libc::setrlimit(resource, &rlim) } != 0 {
Err(last_errno())
} else {
Ok(())
}
}
#[cfg(test)]
mod tests {
#[test]
fn get_current_nofile() {
let mut rlim = libc::rlimit {
rlim_cur: 0,
rlim_max: 0,
};
assert_eq!(
unsafe { libc::getrlimit(libc::RLIMIT_NOFILE, &mut rlim) },
0
);
assert!(rlim.rlim_cur > 0);
}
}