Auto merge of #114038 - Stargateur:108277, r=ChrisDenton

unix time module now return result

First try to fix #108277 without break anything.

if anyone who read this know tips to be able to check compilation for different target I could use some help. So far I installed many target with rustup but `./x check --all-targets` doesn't seem to use them.

TODO:

- [x] better error
- [ ] test, how ?

`@rustbot` label -S-waiting-on-author +S-waiting-on-review
This commit is contained in:
bors 2024-03-14 10:05:32 +00:00
commit e69f14b14c
2 changed files with 36 additions and 52 deletions

View File

@ -463,15 +463,15 @@ pub fn file_type(&self) -> FileType {
#[cfg(target_os = "netbsd")] #[cfg(target_os = "netbsd")]
impl FileAttr { impl FileAttr {
pub fn modified(&self) -> io::Result<SystemTime> { pub fn modified(&self) -> io::Result<SystemTime> {
Ok(SystemTime::new(self.stat.st_mtime as i64, self.stat.st_mtimensec as i64)) SystemTime::new(self.stat.st_mtime as i64, self.stat.st_mtimensec as i64)
} }
pub fn accessed(&self) -> io::Result<SystemTime> { pub fn accessed(&self) -> io::Result<SystemTime> {
Ok(SystemTime::new(self.stat.st_atime as i64, self.stat.st_atimensec as i64)) SystemTime::new(self.stat.st_atime as i64, self.stat.st_atimensec as i64)
} }
pub fn created(&self) -> io::Result<SystemTime> { pub fn created(&self) -> io::Result<SystemTime> {
Ok(SystemTime::new(self.stat.st_birthtime as i64, self.stat.st_birthtimensec as i64)) SystemTime::new(self.stat.st_birthtime as i64, self.stat.st_birthtimensec as i64)
} }
} }
@ -503,16 +503,16 @@ pub fn modified(&self) -> io::Result<SystemTime> {
#[cfg(target_pointer_width = "32")] #[cfg(target_pointer_width = "32")]
cfg_has_statx! { cfg_has_statx! {
if let Some(mtime) = self.stx_mtime() { if let Some(mtime) = self.stx_mtime() {
return Ok(SystemTime::new(mtime.tv_sec, mtime.tv_nsec as i64)); return SystemTime::new(mtime.tv_sec, mtime.tv_nsec as i64);
} }
} }
Ok(SystemTime::new(self.stat.st_mtime as i64, self.stat.st_mtime_nsec as i64)) SystemTime::new(self.stat.st_mtime as i64, self.stat.st_mtime_nsec as i64)
} }
#[cfg(any(target_os = "vxworks", target_os = "espidf", target_os = "vita"))] #[cfg(any(target_os = "vxworks", target_os = "espidf", target_os = "vita"))]
pub fn modified(&self) -> io::Result<SystemTime> { pub fn modified(&self) -> io::Result<SystemTime> {
Ok(SystemTime::new(self.stat.st_mtime as i64, 0)) SystemTime::new(self.stat.st_mtime as i64, 0)
} }
#[cfg(any(target_os = "horizon", target_os = "hurd"))] #[cfg(any(target_os = "horizon", target_os = "hurd"))]
@ -531,16 +531,16 @@ pub fn accessed(&self) -> io::Result<SystemTime> {
#[cfg(target_pointer_width = "32")] #[cfg(target_pointer_width = "32")]
cfg_has_statx! { cfg_has_statx! {
if let Some(atime) = self.stx_atime() { if let Some(atime) = self.stx_atime() {
return Ok(SystemTime::new(atime.tv_sec, atime.tv_nsec as i64)); return SystemTime::new(atime.tv_sec, atime.tv_nsec as i64);
} }
} }
Ok(SystemTime::new(self.stat.st_atime as i64, self.stat.st_atime_nsec as i64)) SystemTime::new(self.stat.st_atime as i64, self.stat.st_atime_nsec as i64)
} }
#[cfg(any(target_os = "vxworks", target_os = "espidf", target_os = "vita"))] #[cfg(any(target_os = "vxworks", target_os = "espidf", target_os = "vita"))]
pub fn accessed(&self) -> io::Result<SystemTime> { pub fn accessed(&self) -> io::Result<SystemTime> {
Ok(SystemTime::new(self.stat.st_atime as i64, 0)) SystemTime::new(self.stat.st_atime as i64, 0)
} }
#[cfg(any(target_os = "horizon", target_os = "hurd"))] #[cfg(any(target_os = "horizon", target_os = "hurd"))]
@ -557,7 +557,7 @@ pub fn accessed(&self) -> io::Result<SystemTime> {
target_os = "watchos", target_os = "watchos",
))] ))]
pub fn created(&self) -> io::Result<SystemTime> { pub fn created(&self) -> io::Result<SystemTime> {
Ok(SystemTime::new(self.stat.st_birthtime as i64, self.stat.st_birthtime_nsec as i64)) SystemTime::new(self.stat.st_birthtime as i64, self.stat.st_birthtime_nsec as i64)
} }
#[cfg(not(any( #[cfg(not(any(
@ -573,7 +573,7 @@ pub fn created(&self) -> io::Result<SystemTime> {
cfg_has_statx! { cfg_has_statx! {
if let Some(ext) = &self.statx_extra_fields { if let Some(ext) = &self.statx_extra_fields {
return if (ext.stx_mask & libc::STATX_BTIME) != 0 { return if (ext.stx_mask & libc::STATX_BTIME) != 0 {
Ok(SystemTime::new(ext.stx_btime.tv_sec, ext.stx_btime.tv_nsec as i64)) SystemTime::new(ext.stx_btime.tv_sec, ext.stx_btime.tv_nsec as i64)
} else { } else {
Err(io::const_io_error!( Err(io::const_io_error!(
io::ErrorKind::Unsupported, io::ErrorKind::Unsupported,
@ -592,22 +592,22 @@ pub fn created(&self) -> io::Result<SystemTime> {
#[cfg(target_os = "vita")] #[cfg(target_os = "vita")]
pub fn created(&self) -> io::Result<SystemTime> { pub fn created(&self) -> io::Result<SystemTime> {
Ok(SystemTime::new(self.stat.st_ctime as i64, 0)) SystemTime::new(self.stat.st_ctime as i64, 0)
} }
} }
#[cfg(target_os = "nto")] #[cfg(target_os = "nto")]
impl FileAttr { impl FileAttr {
pub fn modified(&self) -> io::Result<SystemTime> { pub fn modified(&self) -> io::Result<SystemTime> {
Ok(SystemTime::new(self.stat.st_mtim.tv_sec, self.stat.st_mtim.tv_nsec)) SystemTime::new(self.stat.st_mtim.tv_sec, self.stat.st_mtim.tv_nsec)
} }
pub fn accessed(&self) -> io::Result<SystemTime> { pub fn accessed(&self) -> io::Result<SystemTime> {
Ok(SystemTime::new(self.stat.st_atim.tv_sec, self.stat.st_atim.tv_nsec)) SystemTime::new(self.stat.st_atim.tv_sec, self.stat.st_atim.tv_nsec)
} }
pub fn created(&self) -> io::Result<SystemTime> { pub fn created(&self) -> io::Result<SystemTime> {
Ok(SystemTime::new(self.stat.st_ctim.tv_sec, self.stat.st_ctim.tv_nsec)) SystemTime::new(self.stat.st_ctim.tv_sec, self.stat.st_ctim.tv_nsec)
} }
} }

View File

@ -1,5 +1,5 @@
use crate::fmt;
use crate::time::Duration; use crate::time::Duration;
use crate::{fmt, io};
const NSEC_PER_SEC: u64 = 1_000_000_000; const NSEC_PER_SEC: u64 = 1_000_000_000;
pub const UNIX_EPOCH: SystemTime = SystemTime { t: Timespec::zero() }; pub const UNIX_EPOCH: SystemTime = SystemTime { t: Timespec::zero() };
@ -34,8 +34,8 @@ pub(crate) struct Timespec {
impl SystemTime { impl SystemTime {
#[cfg_attr(any(target_os = "horizon", target_os = "hurd"), allow(unused))] #[cfg_attr(any(target_os = "horizon", target_os = "hurd"), allow(unused))]
pub fn new(tv_sec: i64, tv_nsec: i64) -> SystemTime { pub fn new(tv_sec: i64, tv_nsec: i64) -> Result<SystemTime, io::Error> {
SystemTime { t: Timespec::new(tv_sec, tv_nsec) } Ok(SystemTime { t: Timespec::new(tv_sec, tv_nsec)? })
} }
pub fn now() -> SystemTime { pub fn now() -> SystemTime {
@ -55,12 +55,6 @@ pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
} }
} }
impl From<libc::timespec> for SystemTime {
fn from(t: libc::timespec) -> SystemTime {
SystemTime { t: Timespec::from(t) }
}
}
impl fmt::Debug for SystemTime { impl fmt::Debug for SystemTime {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("SystemTime") f.debug_struct("SystemTime")
@ -71,11 +65,15 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
} }
impl Timespec { impl Timespec {
pub const fn zero() -> Timespec { const unsafe fn new_unchecked(tv_sec: i64, tv_nsec: i64) -> Timespec {
Timespec::new(0, 0) Timespec { tv_sec, tv_nsec: unsafe { Nanoseconds(tv_nsec as u32) } }
} }
const fn new(tv_sec: i64, tv_nsec: i64) -> Timespec { pub const fn zero() -> Timespec {
unsafe { Self::new_unchecked(0, 0) }
}
const fn new(tv_sec: i64, tv_nsec: i64) -> Result<Timespec, io::Error> {
// On Apple OS, dates before epoch are represented differently than on other // On Apple OS, dates before epoch are represented differently than on other
// Unix platforms: e.g. 1/10th of a second before epoch is represented as `seconds=-1` // Unix platforms: e.g. 1/10th of a second before epoch is represented as `seconds=-1`
// and `nanoseconds=100_000_000` on other platforms, but is `seconds=0` and // and `nanoseconds=100_000_000` on other platforms, but is `seconds=0` and
@ -100,9 +98,11 @@ const fn new(tv_sec: i64, tv_nsec: i64) -> Timespec {
} else { } else {
(tv_sec, tv_nsec) (tv_sec, tv_nsec)
}; };
assert!(tv_nsec >= 0 && tv_nsec < NSEC_PER_SEC as i64); if tv_nsec >= 0 && tv_nsec < NSEC_PER_SEC as i64 {
// SAFETY: The assert above checks tv_nsec is within the valid range Ok(unsafe { Self::new_unchecked(tv_sec, tv_nsec) })
Timespec { tv_sec, tv_nsec: unsafe { Nanoseconds(tv_nsec as u32) } } } else {
Err(io::const_io_error!(io::ErrorKind::InvalidData, "Invalid timestamp"))
}
} }
pub fn now(clock: libc::clockid_t) -> Timespec { pub fn now(clock: libc::clockid_t) -> Timespec {
@ -126,13 +126,15 @@ pub fn now(clock: libc::clockid_t) -> Timespec {
if let Some(clock_gettime64) = __clock_gettime64.get() { if let Some(clock_gettime64) = __clock_gettime64.get() {
let mut t = MaybeUninit::uninit(); let mut t = MaybeUninit::uninit();
cvt(unsafe { clock_gettime64(clock, t.as_mut_ptr()) }).unwrap(); cvt(unsafe { clock_gettime64(clock, t.as_mut_ptr()) }).unwrap();
return Timespec::from(unsafe { t.assume_init() }); let t = unsafe { t.assume_init() };
return Timespec::new(t.tv_sec as i64, t.tv_nsec as i64).unwrap();
} }
} }
let mut t = MaybeUninit::uninit(); let mut t = MaybeUninit::uninit();
cvt(unsafe { libc::clock_gettime(clock, t.as_mut_ptr()) }).unwrap(); cvt(unsafe { libc::clock_gettime(clock, t.as_mut_ptr()) }).unwrap();
Timespec::from(unsafe { t.assume_init() }) let t = unsafe { t.assume_init() };
Timespec::new(t.tv_sec as i64, t.tv_nsec as i64).unwrap()
} }
pub fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> { pub fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
@ -178,7 +180,7 @@ pub fn checked_add_duration(&self, other: &Duration) -> Option<Timespec> {
nsec -= NSEC_PER_SEC as u32; nsec -= NSEC_PER_SEC as u32;
secs = secs.checked_add(1)?; secs = secs.checked_add(1)?;
} }
Some(Timespec::new(secs, nsec.into())) Some(unsafe { Timespec::new_unchecked(secs, nsec.into()) })
} }
pub fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> { pub fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> {
@ -190,7 +192,7 @@ pub fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> {
nsec += NSEC_PER_SEC as i32; nsec += NSEC_PER_SEC as i32;
secs = secs.checked_sub(1)?; secs = secs.checked_sub(1)?;
} }
Some(Timespec::new(secs, nsec.into())) Some(unsafe { Timespec::new_unchecked(secs, nsec.into()) })
} }
#[allow(dead_code)] #[allow(dead_code)]
@ -226,12 +228,6 @@ pub fn to_timespec64(&self) -> __timespec64 {
} }
} }
impl From<libc::timespec> for Timespec {
fn from(t: libc::timespec) -> Timespec {
Timespec::new(t.tv_sec as i64, t.tv_nsec as i64)
}
}
#[cfg(all( #[cfg(all(
target_os = "linux", target_os = "linux",
target_env = "gnu", target_env = "gnu",
@ -260,18 +256,6 @@ pub(crate) fn new(tv_sec: i64, tv_nsec: i32) -> Self {
} }
} }
#[cfg(all(
target_os = "linux",
target_env = "gnu",
target_pointer_width = "32",
not(target_arch = "riscv32")
))]
impl From<__timespec64> for Timespec {
fn from(t: __timespec64) -> Timespec {
Timespec::new(t.tv_sec, t.tv_nsec.into())
}
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Instant { pub struct Instant {
t: Timespec, t: Timespec,