diff --git a/Cargo.toml b/Cargo.toml index 31c3d71c19..e5becafc99 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ exclude = [ ] [dependencies] -libc = { version = "0.2.78", features = [ "extra_traits" ] } +libc = { version = "0.2.80", features = [ "extra_traits" ] } bitflags = "1.1" cfg-if = "0.1.10" diff --git a/src/time.rs b/src/time.rs index 54989c2e28..fb14f0a3d4 100644 --- a/src/time.rs +++ b/src/time.rs @@ -1,4 +1,5 @@ -use crate::sys::time::TimeSpec; +use bitflags::bitflags; +use crate::sys::time::{TimeSpec, TimeValLike}; #[cfg(any( target_os = "freebsd", target_os = "dragonfly", @@ -256,3 +257,46 @@ pub fn clock_getcpuclockid(pid: Pid) -> Result { Err(Error::Sys(Errno::from_i32(ret))) } } + +bitflags! { + /// Flags that are used for arming the timer. + pub struct ClockNanosleepFlags: libc::c_int { + const TIMER_ABSTIME = libc::TIMER_ABSTIME; + } +} + +/// Suspend execution of this thread for the amount of time specified by rqtp +/// and measured against the clock speficied by ClockId. If flags is +/// TIMER_ABSTIME, this function will suspend execution until the time value of +/// clock_id reaches the absolute time specified by rqtp. If a signal is caught +/// by a signal-catching function, or a signal causes the process to terminate, +/// this sleep is interrrupted. +/// see also [man 3 clock_nanosleep](https://pubs.opengroup.org/onlinepubs/009695399/functions/clock_nanosleep.html) +#[cfg(any( + target_os = "freebsd", + target_os = "netbsd", + target_os = "linux", + target_os = "android", + target_os = "solaris", + target_os = "illumos", +))] +pub fn clock_nanosleep( + clock_id: ClockId, + flags: ClockNanosleepFlags, + rqtp: &TimeSpec, +) -> Result { + let mut rmtp: TimeSpec = TimeSpec::nanoseconds(0); + let ret = unsafe { + libc::clock_nanosleep( + clock_id.as_raw(), + flags.bits(), + rqtp.as_ref() as *const _, + rmtp.as_mut() as *mut _, + ) + }; + if ret == 0 { + Ok(rmtp) + } else { + Err(Error::Sys(Errno::from_i32(ret))) + } +} diff --git a/test/test_time.rs b/test/test_time.rs index c321352d79..d1c7e3f5e3 100644 --- a/test/test_time.rs +++ b/test/test_time.rs @@ -1,3 +1,4 @@ +use nix::sys::time::{TimeSpec, TimeValLike}; #[cfg(any( target_os = "freebsd", target_os = "dragonfly", @@ -6,7 +7,7 @@ target_os = "emscripten", ))] use nix::time::clock_getcpuclockid; -use nix::time::{clock_getres, clock_gettime, ClockId}; +use nix::time::{clock_getres, clock_gettime, clock_nanosleep, ClockId, ClockNanosleepFlags}; #[test] pub fn test_clock_getres() { @@ -54,3 +55,15 @@ pub fn test_clock_id_pid_cpu_clock_id() { .map(ClockId::now) .is_ok()); } + +#[test] +pub fn test_clock_nanosleep() { + let sleep_time = TimeSpec::microseconds(1); + let res = clock_nanosleep( + ClockId::CLOCK_MONOTONIC, + ClockNanosleepFlags::empty(), + &sleep_time, + ); + let expected = TimeSpec::microseconds(0); + assert_eq!(res, Ok(expected)); +}