diff --git a/src/header/sys_timeb/mod.rs b/src/header/sys_timeb/mod.rs index 57c11e1c2b..76ae4bc5b7 100644 --- a/src/header/sys_timeb/mod.rs +++ b/src/header/sys_timeb/mod.rs @@ -10,6 +10,8 @@ // TODO: set this for entire crate when possible #![deny(unsafe_op_in_unsafe_fn)] +use core::ptr::NonNull; + use crate::{ header::sys_time::{gettimeofday, timeval, timezone}, platform::types::*, @@ -26,20 +28,30 @@ pub struct timeb { } /// See . +/// +/// # Safety +/// The caller must ensure that `tp` is convertible to a `&mut +/// MaybeUninit`. #[no_mangle] pub unsafe extern "C" fn ftime(tp: *mut timeb) -> c_int { - let tp_mut = unsafe { &mut *tp }; + // SAFETY: the caller is required to ensure that the pointer is valid. + let tp_maybe_uninit = unsafe { NonNull::new_unchecked(tp).as_uninit_mut() }; let mut tv = timeval::default(); let mut tz = timezone::default(); + + // SAFETY: tv and tz are created above, and thus will coerce to valid + // pointers. if unsafe { gettimeofday(&mut tv, &mut tz) } < 0 { return -1; } - tp_mut.time = tv.tv_sec; - tp_mut.millitm = (tv.tv_usec / 1000) as c_ushort; - tp_mut.timezone = tz.tz_minuteswest as c_short; - tp_mut.dstflag = tz.tz_dsttime as c_short; + tp_maybe_uninit.write(timeb { + time: tv.tv_sec, + millitm: (tv.tv_usec / 1000) as c_ushort, + timezone: tz.tz_minuteswest as c_short, + dstflag: tz.tz_dsttime as c_short, + }); 0 }