use super::*;
use windows_sys::Win32::Foundation::{GetHandleInformation, HANDLE_FLAG_INHERIT};
use windows_sys::Win32::System::JobObjects::{QueryInformationJobObject, JOB_OBJECT_LIMIT};
fn limit_flags(job: &Job) -> JOB_OBJECT_LIMIT {
let mut limits = JOBOBJECT_EXTENDED_LIMIT_INFORMATION::default();
let mut returned: u32 = 0;
let ok = unsafe {
QueryInformationJobObject(
job.raw_handle(),
JobObjectExtendedLimitInformation,
ptr::addr_of_mut!(limits).cast(),
u32::try_from(size_of::<JOBOBJECT_EXTENDED_LIMIT_INFORMATION>())
.expect("the fixed information structure fits in u32"),
&mut returned,
)
};
assert_ne!(
ok,
0,
"QueryInformationJobObject failed: {}",
io::Error::last_os_error()
);
limits.BasicLimitInformation.LimitFlags
}
#[test]
fn create_without_kill_on_close_sets_no_limits() {
let job = Job::create(false).expect("creating a job must succeed");
assert_eq!(limit_flags(&job), 0);
}
#[test]
fn create_with_kill_on_close_sets_the_limit() {
let job = Job::create(true).expect("creating a job must succeed");
assert_eq!(
limit_flags(&job) & JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE,
JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE
);
}
#[test]
fn the_handle_is_not_inheritable() {
let job = Job::create(true).expect("creating a job must succeed");
let mut flags: u32 = 0;
let ok = unsafe { GetHandleInformation(job.raw_handle(), &mut flags) };
assert_ne!(
ok,
0,
"GetHandleInformation failed: {}",
io::Error::last_os_error()
);
assert_eq!(flags & HANDLE_FLAG_INHERIT, 0);
}
#[test]
fn terminate_succeeds_on_an_empty_job() {
let job = Job::create(false).expect("creating a job must succeed");
job.terminate(1)
.expect("terminating an empty job must succeed");
job.terminate(1)
.expect("terminating an empty job twice must succeed");
}