Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions libc-test/tests/windows_time.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//! Ensures Windows `time`-related routines align with `libc`'s interface. By
//! default, both MSVC and GNU (under `mingw`) expose 64-bit symbols, but in
//! stable we need to cope with a 32-bit `time-t`, so the routines should link
//! to their 32-bit variants.

#![cfg(windows)]

/// Ensures a 64-bit write is performed on values that should always be 64 bits,
/// and that a corresponding 32-bit write is performed on values that should be
/// 32 bits. This basically makes sure `time_t`'s bit-width aligns with those of
/// functions that expect it as a parameter.
#[test]
fn test_bitwidth_store() {
#[cfg(all(target_arch = "x86", target_env = "gnu"))]
assert_eq!(size_of::<libc::time_t>(), 4);
#[cfg(not(all(target_arch = "x86", target_env = "gnu")))]
assert_eq!(size_of::<libc::time_t>(), 8);

let mut time_values: [libc::time_t; 2] = [123, 456];
let ptr = time_values.as_mut_ptr();

unsafe { libc::time(ptr) };

assert!(time_values[0] != 123);
assert_eq!(time_values[1], 456);
}
35 changes: 27 additions & 8 deletions src/windows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -390,10 +390,6 @@ extern "C" {
pub fn raise(signum: c_int) -> c_int;

pub fn clock() -> clock_t;
pub fn ctime(sourceTime: *const time_t) -> *mut c_char;
pub fn difftime(timeEnd: time_t, timeStart: time_t) -> c_double;
#[link_name = "_gmtime64_s"]
pub fn gmtime_s(destTime: *mut tm, srcTime: *const time_t) -> c_int;
#[link_name = "_get_daylight"]
pub fn get_daylight(hours: *mut c_int) -> errno_t;
#[link_name = "_get_dstbias"]
Expand All @@ -407,10 +403,6 @@ extern "C" {
size_in_bytes: size_t,
index: c_int,
) -> errno_t;
#[link_name = "_localtime64_s"]
pub fn localtime_s(tmDest: *mut tm, sourceTime: *const time_t) -> crate::errno_t;
#[link_name = "_time64"]
pub fn time(destTime: *mut time_t) -> time_t;
#[link_name = "_tzset"]
pub fn tzset();
#[link_name = "_chmod"]
Expand Down Expand Up @@ -549,6 +541,33 @@ extern "C" {
) -> crate::errno_t;
}

// By default, the following link to 64-bit variants where the expected `time_t`
// is also 64-bits.
#[cfg(not(all(target_arch = "x86", target_env = "gnu")))]
extern "C" {
pub fn ctime(sourceTime: *const time_t) -> *mut c_char;
pub fn difftime(timeEnd: time_t, timeStart: time_t) -> c_double;
pub fn gmtime_s(destTime: *mut tm, srcTime: *const time_t) -> c_int;
pub fn localtime_s(tmDest: *mut tm, sourceTime: *const time_t) -> crate::errno_t;
pub fn time(destTime: *mut time_t) -> time_t;
}

// Under Windows x86 with GNU, `time_t` is still 32-bit wide on stable, so the
// above routines have to link with their 32-bit variants.
#[cfg(all(target_arch = "x86", target_env = "gnu"))]
extern "C" {
#[link_name = "_ctime32"]
pub fn ctime(sourceTime: *const time_t) -> *mut c_char;
#[link_name = "_difftime32"]
pub fn difftime(timeEnd: time_t, timeStart: time_t) -> c_double;
#[link_name = "_gmtime32_s"]
pub fn gmtime_s(destTime: *mut tm, srcTime: *const time_t) -> c_int;
#[link_name = "_localtime32_s"]
pub fn localtime_s(tmDest: *mut tm, sourceTime: *const time_t) -> crate::errno_t;
#[link_name = "_time32"]
pub fn time(destTime: *mut time_t) -> time_t;
}

extern "system" {
pub fn listen(s: SOCKET, backlog: c_int) -> c_int;
pub fn accept(s: SOCKET, addr: *mut crate::sockaddr, addrlen: *mut c_int) -> SOCKET;
Expand Down
Loading