Skip to content

Commit 6612f50

Browse files
committed
add safe libc::clock_nanosleep wrapper
1 parent c8e8def commit 6612f50

File tree

2 files changed

+45
-2
lines changed

2 files changed

+45
-2
lines changed

src/time.rs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::sys::time::TimeSpec;
1+
use crate::sys::time::{TimeSpec, TimeValLike};
22
#[cfg(any(
33
target_os = "freebsd",
44
target_os = "dragonfly",
@@ -256,3 +256,33 @@ pub fn clock_getcpuclockid(pid: Pid) -> Result<ClockId> {
256256
Err(Error::Sys(Errno::from_i32(ret)))
257257
}
258258
}
259+
260+
pub type ClockNanosleepFlags = crate::sys::timerfd::TimerSetTimeFlags;
261+
262+
/// Suspend execution of this thread for the amount of time specified by rqtp
263+
/// and measured against the clock speficied by ClockId. If flags is
264+
/// TIMER_ABSTIME, this function will suspend execution until the time value of
265+
/// clock_id reaches the absolute time specified by rqtp. If a signal is caught
266+
/// by a signal-catching function, or a signal causes the process to terminate,
267+
/// this sleep is interrrupted.
268+
/// see also [man 3 clock_nanosleep](https://pubs.opengroup.org/onlinepubs/009695399/functions/clock_nanosleep.html)
269+
pub fn clock_nanosleep(
270+
clock_id: ClockId,
271+
flags: ClockNanosleepFlags,
272+
rqtp: &TimeSpec,
273+
) -> Result<TimeSpec> {
274+
let mut rmtp: TimeSpec = TimeSpec::nanoseconds(0);
275+
let ret = unsafe {
276+
libc::clock_nanosleep(
277+
clock_id.as_raw(),
278+
flags.bits(),
279+
rqtp.as_ref() as *const _,
280+
rmtp.as_mut() as *mut _,
281+
)
282+
};
283+
if ret == 0 {
284+
Ok(rmtp)
285+
} else {
286+
Err(Error::Sys(Errno::from_i32(ret)))
287+
}
288+
}

test/test_time.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use nix::sys::time::{TimeSpec, TimeValLike};
12
#[cfg(any(
23
target_os = "freebsd",
34
target_os = "dragonfly",
@@ -6,7 +7,7 @@
67
target_os = "emscripten",
78
))]
89
use nix::time::clock_getcpuclockid;
9-
use nix::time::{clock_getres, clock_gettime, ClockId};
10+
use nix::time::{clock_getres, clock_gettime, clock_nanosleep, ClockId, ClockNanosleepFlags};
1011

1112
#[test]
1213
pub fn test_clock_getres() {
@@ -54,3 +55,15 @@ pub fn test_clock_id_pid_cpu_clock_id() {
5455
.map(ClockId::now)
5556
.is_ok());
5657
}
58+
59+
#[test]
60+
pub fn test_clock_nanosleep() {
61+
let sleep_time = TimeSpec::microseconds(1);
62+
let res = clock_nanosleep(
63+
ClockId::CLOCK_MONOTONIC,
64+
ClockNanosleepFlags::empty(),
65+
&sleep_time,
66+
);
67+
let expected = TimeSpec::microseconds(0);
68+
assert_eq!(res, Ok(expected));
69+
}

0 commit comments

Comments
 (0)