Skip to content

Commit d2a1c8d

Browse files
committed
implement clock_gettime, clock_getres, clock_settime
1 parent 1f8f594 commit d2a1c8d

File tree

6 files changed

+206
-0
lines changed

6 files changed

+206
-0
lines changed

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ All notable changes to this project will be documented in this file.
44
This project adheres to [Semantic Versioning](http://semver.org/).
55

66
## [Unreleased] - ReleaseDate
7+
### Added
8+
- Add `clock_gettime`, `clock_settime`, `clock_getres`
9+
([#1100](https://github.com/nix-rust/nix/pull/1100))
710

811
## [0.16.0] - 1 December 2019
912
### Added

src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ pub mod poll;
6464
pub mod pty;
6565
pub mod sched;
6666
pub mod sys;
67+
pub mod time;
6768
// This can be implemented for other platforms as soon as libc
6869
// provides bindings for them.
6970
#[cfg(all(target_os = "linux",

src/sys/time.rs

+6
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,12 @@ impl AsRef<timespec> for TimeSpec {
6767
}
6868
}
6969

70+
impl From<timespec> for TimeSpec {
71+
fn from(ts: timespec) -> Self {
72+
TimeSpec(ts)
73+
}
74+
}
75+
7076
impl Ord for TimeSpec {
7177
// The implementation of cmp is simplified by assuming that the struct is
7278
// normalized. That is, tv_nsec must always be within [0, 1_000_000_000)

src/time.rs

+184
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
use sys::time::TimeSpec;
2+
use std::mem::MaybeUninit;
3+
use {Result, Errno};
4+
use libc;
5+
6+
libc_enum! {
7+
#[cfg_attr(any(
8+
target_env = "uclibc",
9+
target_os = "fuchsia",
10+
target_os = "redox",
11+
target_os = "freebsd",
12+
target_os = "netbsd",
13+
target_os = "openbsd",
14+
target_os = "haiku",
15+
all(not(target_env = "newlib"),
16+
any(target_os = "linux",
17+
target_os = "android",
18+
target_os = "emscripten",
19+
target_os = "solaris",
20+
target_os = "illumos")),
21+
), repr(i32))]
22+
#[cfg_attr(any(
23+
all(target_env = "newlib", target_arch = "arm"),
24+
target_os = "macos",
25+
target_os = "ios",
26+
), repr(u32))]
27+
#[cfg_attr(any(
28+
all(target_env = "newlib", target_arch = "aarch64"),
29+
all(not(any(target_env = "newlib", target_env = "uclibc")), target_os = "hermit"),
30+
target_os = "dragonfly",
31+
), repr(u64))]
32+
pub enum ClockId {
33+
#[cfg(any(target_os = "fuchsia",
34+
all(not(any(target_env = "uclibc",
35+
target_env = "newlib")),
36+
any(target_os = "linux",
37+
target_os = "android",
38+
target_os = "emscripten"),
39+
)
40+
))]
41+
CLOCK_BOOTTIME,
42+
#[cfg(any(target_os = "fuchsia",
43+
all(not(any(target_env = "uclibc",
44+
target_env = "newlib")),
45+
any(target_os = "linux",
46+
target_os = "android",
47+
target_os = "emscripten"))))]
48+
CLOCK_BOOTTIME_ALARM,
49+
CLOCK_MONOTONIC,
50+
#[cfg(any(target_os = "fuchsia",
51+
all(not(any(target_env = "uclibc",
52+
target_env = "newlib")),
53+
any(target_os = "linux",
54+
target_os = "android",
55+
target_os = "emscripten"))))]
56+
CLOCK_MONOTONIC_COARSE,
57+
#[cfg(any(target_os = "freebsd",
58+
target_os = "dragonfly"))]
59+
CLOCK_MONOTONIC_FAST,
60+
#[cfg(any(target_os = "freebsd",
61+
target_os = "dragonfly"))]
62+
CLOCK_MONOTONIC_PRECISE,
63+
#[cfg(any(target_os = "fuchsia",
64+
all(not(any(target_env = "uclibc",
65+
target_env = "newlib")),
66+
any(target_os = "linux",
67+
target_os = "android",
68+
target_os = "emscripten"))))]
69+
CLOCK_MONOTONIC_RAW,
70+
#[cfg(any(target_os = "fuchsia",
71+
target_env = "uclibc",
72+
target_os = "macos",
73+
target_os = "ios",
74+
target_os = "freebsd",
75+
target_os = "dragonfly",
76+
all(not(target_env = "newlib"),
77+
any(target_os = "linux",
78+
target_os = "android",
79+
target_os = "emscripten"))))]
80+
CLOCK_PROCESS_CPUTIME_ID,
81+
#[cfg(any(target_os = "freebsd",
82+
target_os = "dragonfly"))]
83+
CLOCK_PROF,
84+
CLOCK_REALTIME,
85+
#[cfg(any(target_os = "fuchsia",
86+
all(not(any(target_env = "uclibc",
87+
target_env = "newlib")),
88+
any(target_os = "linux",
89+
target_os = "android",
90+
target_os = "emscripten"))))]
91+
CLOCK_REALTIME_ALARM,
92+
#[cfg(any(target_os = "fuchsia",
93+
all(not(any(target_env = "uclibc",
94+
target_env = "newlib")),
95+
any(target_os = "linux",
96+
target_os = "android",
97+
target_os = "emscripten"))))]
98+
CLOCK_REALTIME_COARSE,
99+
#[cfg(any(target_os = "freebsd",
100+
target_os = "dragonfly"))]
101+
CLOCK_REALTIME_FAST,
102+
#[cfg(any(target_os = "freebsd",
103+
target_os = "dragonfly"))]
104+
CLOCK_REALTIME_PRECISE,
105+
#[cfg(any(target_os = "freebsd",
106+
target_os = "dragonfly"))]
107+
CLOCK_SECOND,
108+
#[cfg(any(target_os = "fuchsia",
109+
all(not(any(target_env = "uclibc", target_env = "newlib")),
110+
any(target_os = "emscripten",
111+
all(target_os = "linux", target_env = "musl")))))]
112+
CLOCK_SGI_CYCLE,
113+
#[cfg(any(target_os = "fuchsia",
114+
all(not(any(target_env = "uclibc", target_env = "newlib")),
115+
any(target_os = "emscripten",
116+
all(target_os = "linux", target_env = "musl")))))]
117+
CLOCK_TAI,
118+
#[cfg(any(
119+
target_env = "uclibc",
120+
target_os = "fuchsia",
121+
target_os = "ios",
122+
target_os = "macos",
123+
target_os = "freebsd",
124+
target_os = "dragonfly",
125+
all(
126+
not(target_env = "newlib"),
127+
any(
128+
target_os = "linux",
129+
target_os = "android",
130+
target_os = "emscripten",
131+
),
132+
),
133+
)
134+
)]
135+
CLOCK_THREAD_CPUTIME_ID,
136+
#[cfg(any(target_os = "freebsd",
137+
target_os = "dragonfly"))]
138+
CLOCK_UPTIME,
139+
#[cfg(any(target_os = "freebsd",
140+
target_os = "dragonfly"))]
141+
CLOCK_UPTIME_FAST,
142+
#[cfg(any(target_os = "freebsd",
143+
target_os = "dragonfly"))]
144+
CLOCK_UPTIME_PRECISE,
145+
#[cfg(any(target_os = "freebsd",
146+
target_os = "dragonfly"))]
147+
CLOCK_VIRTUAL,
148+
}
149+
}
150+
151+
pub fn clock_getres(clk_id: ClockId) -> Result<TimeSpec> {
152+
let mut c_time: MaybeUninit<libc::timespec> = MaybeUninit::uninit();
153+
let errno = unsafe { libc::clock_getres(clk_id as libc::clockid_t, c_time.as_mut_ptr()) };
154+
Errno::result(errno)?;
155+
let res = unsafe { c_time.assume_init() };
156+
Ok(TimeSpec::from(res))
157+
}
158+
159+
pub fn clock_gettime(clk_id: ClockId) -> Result<TimeSpec> {
160+
let mut c_time: MaybeUninit<libc::timespec> = MaybeUninit::uninit();
161+
let errno = unsafe { libc::clock_gettime(clk_id as libc::clockid_t, c_time.as_mut_ptr()) };
162+
Errno::result(errno)?;
163+
let res = unsafe { c_time.assume_init() };
164+
Ok(TimeSpec::from(res))
165+
}
166+
167+
#[cfg(not(
168+
any(
169+
target_os = "macos",
170+
target_os = "ios",
171+
all(
172+
not(any(target_env = "uclibc", target_env = "newlibc")),
173+
any(
174+
target_os = "redox",
175+
target_os = "hermit",
176+
),
177+
),
178+
)
179+
)
180+
)]
181+
pub fn clock_settime(clk_id: ClockId, timespec: TimeSpec) -> Result<()> {
182+
let res = unsafe { libc::clock_settime(clk_id as libc::clockid_t, timespec.as_ref()) };
183+
Errno::result(res).map(drop)
184+
}

test/test.rs

+1
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ mod test_sched;
126126
target_os = "macos"))]
127127
mod test_sendfile;
128128
mod test_stat;
129+
mod test_time;
129130
mod test_unistd;
130131

131132
use std::os::unix::io::RawFd;

test/test_time.rs

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
use nix::time::{clock_getres, clock_gettime, ClockId};
2+
3+
#[test]
4+
pub fn test_clock_getres() {
5+
assert!(clock_getres(ClockId::CLOCK_REALTIME).is_ok());
6+
}
7+
8+
#[test]
9+
pub fn test_clock_gettime() {
10+
assert!(clock_gettime(ClockId::CLOCK_REALTIME).is_ok());
11+
}

0 commit comments

Comments
 (0)