time/sys/refresh_tz/unix.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
/// Whether the operating system has a thread-safe environment. This allows bypassing the check for
/// if the process is multi-threaded.
// This is the same value as `cfg!(target_os = "x")`.
// Use byte-strings to work around current limitations of const eval.
const OS_HAS_THREAD_SAFE_ENVIRONMENT: bool = match std::env::consts::OS.as_bytes() {
// https://github.com/illumos/illumos-gate/blob/0fb96ba1f1ce26ff8b286f8f928769a6afcb00a6/usr/src/lib/libc/port/gen/getenv.c
b"illumos"
// https://github.com/NetBSD/src/blob/f45028636a44111bc4af44d460924958a4460844/lib/libc/stdlib/getenv.c
// https://github.com/NetBSD/src/blob/f45028636a44111bc4af44d460924958a4460844/lib/libc/stdlib/setenv.c
| b"netbsd"
=> true,
_ => false,
};
/// Update time zone information from the system.
///
/// For safety documentation, see [`time::util::refresh_tz`].
pub(super) unsafe fn refresh_tz_unchecked() {
extern "C" {
#[cfg_attr(target_os = "netbsd", link_name = "__tzset50")]
fn tzset();
}
// Safety: The caller must uphold the safety requirements.
unsafe { tzset() };
}
/// Attempt to update time zone information from the system. Returns `None` if the call is not known
/// to be sound.
pub(super) fn refresh_tz() -> Option<()> {
// Refresh $TZ if and only if the call is known to be sound.
//
// Soundness can be guaranteed either by knowledge of the operating system or knowledge that the
// process is single-threaded. If the process is single-threaded, then the environment cannot
// be mutated by a different thread in the process while execution of this function is taking
// place, which can cause a segmentation fault by dereferencing a dangling pointer.
//
// If the `num_threads` crate is incapable of determining the number of running threads, then
// we conservatively return `None` to avoid a soundness bug.
if OS_HAS_THREAD_SAFE_ENVIRONMENT || num_threads::is_single_threaded() == Some(true) {
// Safety: The caller must uphold the safety requirements.
unsafe { refresh_tz_unchecked() };
Some(())
} else {
None
}
}