Skip to content

Commit 3bfda04

Browse files
committed
library: fs: Factor out the Apple file time to attrlist code for reuse
1 parent 1e6b444 commit 3bfda04

File tree

1 file changed

+52
-23
lines changed

1 file changed

+52
-23
lines changed

library/std/src/sys/fs/unix.rs

Lines changed: 52 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1616,30 +1616,12 @@ impl File {
16161616
))
16171617
}
16181618
target_vendor = "apple" => {
1619-
let mut buf = [mem::MaybeUninit::<libc::timespec>::uninit(); 3];
1620-
let mut num_times = 0;
1621-
let mut attrlist: libc::attrlist = unsafe { mem::zeroed() };
1622-
attrlist.bitmapcount = libc::ATTR_BIT_MAP_COUNT;
1623-
if times.created.is_some() {
1624-
buf[num_times].write(file_time_to_timespec(times.created)?);
1625-
num_times += 1;
1626-
attrlist.commonattr |= libc::ATTR_CMN_CRTIME;
1627-
}
1628-
if times.modified.is_some() {
1629-
buf[num_times].write(file_time_to_timespec(times.modified)?);
1630-
num_times += 1;
1631-
attrlist.commonattr |= libc::ATTR_CMN_MODTIME;
1632-
}
1633-
if times.accessed.is_some() {
1634-
buf[num_times].write(file_time_to_timespec(times.accessed)?);
1635-
num_times += 1;
1636-
attrlist.commonattr |= libc::ATTR_CMN_ACCTIME;
1637-
}
1619+
let ta = TimesAttrlist::from_times(&times)?;
16381620
cvt(unsafe { libc::fsetattrlist(
16391621
self.as_raw_fd(),
1640-
(&raw const attrlist).cast::<libc::c_void>().cast_mut(),
1641-
buf.as_ptr().cast::<libc::c_void>().cast_mut(),
1642-
num_times * size_of::<libc::timespec>(),
1622+
ta.attrlist(),
1623+
ta.times_buf(),
1624+
ta.times_buf_size(),
16431625
0
16441626
) })?;
16451627
Ok(())
@@ -1706,7 +1688,54 @@ fn file_time_to_timespec(time: Option<SystemTime>) -> io::Result<libc::timespec>
17061688
)),
17071689
None => Ok(libc::timespec { tv_sec: 0, tv_nsec: libc::UTIME_OMIT as _ }),
17081690
}
1709-
};
1691+
}
1692+
1693+
#[cfg(target_vendor = "apple")]
1694+
struct TimesAttrlist {
1695+
buf: [mem::MaybeUninit<libc::timespec>; 3],
1696+
attrlist: libc::attrlist,
1697+
num_times: usize,
1698+
}
1699+
1700+
#[cfg(target_vendor = "apple")]
1701+
impl TimesAttrlist {
1702+
fn from_times(times: &FileTimes) -> io::Result<Self> {
1703+
let mut this = Self {
1704+
buf: [mem::MaybeUninit::<libc::timespec>::uninit(); 3],
1705+
attrlist: unsafe { mem::zeroed() },
1706+
num_times: 0,
1707+
};
1708+
this.attrlist.bitmapcount = libc::ATTR_BIT_MAP_COUNT;
1709+
if times.created.is_some() {
1710+
this.buf[this.num_times].write(file_time_to_timespec(times.created)?);
1711+
this.num_times += 1;
1712+
this.attrlist.commonattr |= libc::ATTR_CMN_CRTIME;
1713+
}
1714+
if times.modified.is_some() {
1715+
this.buf[this.num_times].write(file_time_to_timespec(times.modified)?);
1716+
this.num_times += 1;
1717+
this.attrlist.commonattr |= libc::ATTR_CMN_MODTIME;
1718+
}
1719+
if times.accessed.is_some() {
1720+
this.buf[this.num_times].write(file_time_to_timespec(times.accessed)?);
1721+
this.num_times += 1;
1722+
this.attrlist.commonattr |= libc::ATTR_CMN_ACCTIME;
1723+
}
1724+
Ok(this)
1725+
}
1726+
1727+
fn attrlist(&self) -> *mut libc::c_void {
1728+
(&raw const self.attrlist).cast::<libc::c_void>().cast_mut()
1729+
}
1730+
1731+
fn times_buf(&self) -> *mut libc::c_void {
1732+
self.buf.as_ptr().cast::<libc::c_void>().cast_mut()
1733+
}
1734+
1735+
fn times_buf_size(&self) -> usize {
1736+
self.num_times * size_of::<libc::timespec>()
1737+
}
1738+
}
17101739

17111740
impl DirBuilder {
17121741
pub fn new() -> DirBuilder {

0 commit comments

Comments
 (0)