Skip to content

Commit 44c8940

Browse files
committed
Use custom traits instead of libstd's MetadataExt and PermissionsExt.
Define our own copy of `MetadataExt` and `PermissionsExt` and change the code to use them instead of `std::os::*::fs::MetadataExt` and `std::os::*::fs::PermissionsExt'. In general, we should be moving away from using std's `Ext` traits like this, as they weren't meant to be used in this way. Fixes #342.
1 parent 465c70b commit 44c8940

12 files changed

+150
-73
lines changed

cap-fs-ext/src/metadata_ext.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -75,17 +75,17 @@ impl MetadataExt for std::fs::Metadata {
7575
impl MetadataExt for cap_primitives::fs::Metadata {
7676
#[inline]
7777
fn dev(&self) -> u64 {
78-
std::os::unix::fs::MetadataExt::dev(self)
78+
cap_primitives::fs::MetadataExt::dev(self)
7979
}
8080

8181
#[inline]
8282
fn ino(&self) -> u64 {
83-
std::os::unix::fs::MetadataExt::ino(self)
83+
cap_primitives::fs::MetadataExt::ino(self)
8484
}
8585

8686
#[inline]
8787
fn nlink(&self) -> u64 {
88-
std::os::unix::fs::MetadataExt::nlink(self)
88+
cap_primitives::fs::MetadataExt::nlink(self)
8989
}
9090
}
9191

cap-primitives/src/fs/metadata.rs

+94-32
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::fs::{FileType, ImplFileTypeExt, MetadataExt, Permissions};
1+
use crate::fs::{FileType, ImplFileTypeExt, ImplMetadataExt, Permissions};
22
use crate::time::SystemTime;
33
use std::{fs, io};
44

@@ -18,7 +18,7 @@ pub struct Metadata {
1818
pub(crate) modified: Option<SystemTime>,
1919
pub(crate) accessed: Option<SystemTime>,
2020
pub(crate) created: Option<SystemTime>,
21-
pub(crate) ext: MetadataExt,
21+
pub(crate) ext: ImplMetadataExt,
2222
}
2323

2424
#[allow(clippy::len_without_is_empty)]
@@ -27,7 +27,7 @@ impl Metadata {
2727
#[inline]
2828
pub fn from_file(file: &fs::File) -> io::Result<Self> {
2929
let std = file.metadata()?;
30-
let ext = MetadataExt::from(file, &std)?;
30+
let ext = ImplMetadataExt::from(file, &std)?;
3131
let file_type = ImplFileTypeExt::from(file, &std)?;
3232
Ok(Self::from_parts(std, ext, file_type))
3333
}
@@ -41,13 +41,13 @@ impl Metadata {
4141
/// [`std::fs::Metadata::volume_serial_number`]: https://doc.rust-lang.org/std/os/windows/fs/trait.MetadataExt.html#tymethod.volume_serial_number
4242
#[inline]
4343
pub fn from_just_metadata(std: fs::Metadata) -> Self {
44-
let ext = MetadataExt::from_just_metadata(&std);
44+
let ext = ImplMetadataExt::from_just_metadata(&std);
4545
let file_type = ImplFileTypeExt::from_just_metadata(&std);
4646
Self::from_parts(std, ext, file_type)
4747
}
4848

4949
#[inline]
50-
fn from_parts(std: fs::Metadata, ext: MetadataExt, file_type: FileType) -> Self {
50+
fn from_parts(std: fs::Metadata, ext: ImplMetadataExt, file_type: FileType) -> Self {
5151
Self {
5252
file_type,
5353
len: std.len(),
@@ -198,129 +198,191 @@ impl Metadata {
198198
}
199199
}
200200

201+
/// Unix-specific extensions for [`MetadataExt`].
202+
///
203+
/// This corresponds to [`std::os::unix::fs::MetadataExt`].
204+
#[cfg(any(unix, target_os = "vxworks"))]
205+
pub trait MetadataExt {
206+
/// Returns the ID of the device containing the file.
207+
fn dev(&self) -> u64;
208+
/// Returns the inode number.
209+
fn ino(&self) -> u64;
210+
/// Returns the rights applied to this file.
211+
fn mode(&self) -> u32;
212+
/// Returns the number of hard links pointing to this file.
213+
fn nlink(&self) -> u64;
214+
/// Returns the user ID of the owner of this file.
215+
fn uid(&self) -> u32;
216+
/// Returns the group ID of the owner of this file.
217+
fn gid(&self) -> u32;
218+
/// Returns the device ID of this file (if it is a special one).
219+
fn rdev(&self) -> u64;
220+
/// Returns the total size of this file in bytes.
221+
fn size(&self) -> u64;
222+
/// Returns the last access time of the file, in seconds since Unix Epoch.
223+
fn atime(&self) -> i64;
224+
/// Returns the last access time of the file, in nanoseconds since [`atime`].
225+
fn atime_nsec(&self) -> i64;
226+
/// Returns the last modification time of the file, in seconds since Unix Epoch.
227+
fn mtime(&self) -> i64;
228+
/// Returns the last modification time of the file, in nanoseconds since [`mtime`].
229+
fn mtime_nsec(&self) -> i64;
230+
/// Returns the last status change time of the file, in seconds since Unix Epoch.
231+
fn ctime(&self) -> i64;
232+
/// Returns the last status change time of the file, in nanoseconds since [`ctime`].
233+
fn ctime_nsec(&self) -> i64;
234+
/// Returns the block size for filesystem I/O.
235+
fn blksize(&self) -> u64;
236+
/// Returns the number of blocks allocated to the file, in 512-byte units.
237+
fn blocks(&self) -> u64;
238+
#[cfg(target_os = "vxworks")]
239+
fn attrib(&self) -> u8;
240+
}
241+
242+
/// WASI-specific extensions for [`MetadataExt`].
243+
///
244+
/// This corresponds to [`std::os::wasi::fs::MetadataExt`].
245+
#[cfg(target_os = "wasi")]
246+
pub trait MetadataExt {
247+
/// Returns the ID of the device containing the file.
248+
fn dev(&self) -> u64;
249+
/// Returns the inode number.
250+
fn ino(&self) -> u64;
251+
/// Returns the number of hard links pointing to this file.
252+
fn nlink(&self) -> u64;
253+
/// Returns the total size of this file in bytes.
254+
fn size(&self) -> u64;
255+
/// Returns the last access time of the file, in seconds since Unix Epoch.
256+
fn atim(&self) -> u64;
257+
/// Returns the last modification time of the file, in seconds since Unix Epoch.
258+
fn mtim(&self) -> u64;
259+
/// Returns the last status change time of the file, in seconds since Unix Epoch.
260+
fn ctim(&self) -> u64;
261+
}
262+
201263
#[cfg(unix)]
202-
impl std::os::unix::fs::MetadataExt for Metadata {
264+
impl MetadataExt for Metadata {
203265
#[inline]
204266
fn dev(&self) -> u64 {
205-
self.ext.dev()
267+
rustix::fs::MetadataExt::dev(&self.ext)
206268
}
207269

208270
#[inline]
209271
fn ino(&self) -> u64 {
210-
self.ext.ino()
272+
rustix::fs::MetadataExt::ino(&self.ext)
211273
}
212274

213275
#[inline]
214276
fn mode(&self) -> u32 {
215-
self.ext.mode()
277+
rustix::fs::MetadataExt::mode(&self.ext)
216278
}
217279

218280
#[inline]
219281
fn nlink(&self) -> u64 {
220-
self.ext.nlink()
282+
rustix::fs::MetadataExt::nlink(&self.ext)
221283
}
222284

223285
#[inline]
224286
fn uid(&self) -> u32 {
225-
self.ext.uid()
287+
rustix::fs::MetadataExt::uid(&self.ext)
226288
}
227289

228290
#[inline]
229291
fn gid(&self) -> u32 {
230-
self.ext.gid()
292+
rustix::fs::MetadataExt::gid(&self.ext)
231293
}
232294

233295
#[inline]
234296
fn rdev(&self) -> u64 {
235-
self.ext.rdev()
297+
rustix::fs::MetadataExt::rdev(&self.ext)
236298
}
237299

238300
#[inline]
239301
fn size(&self) -> u64 {
240-
self.ext.size()
302+
rustix::fs::MetadataExt::size(&self.ext)
241303
}
242304

243305
#[inline]
244306
fn atime(&self) -> i64 {
245-
self.ext.atime()
307+
rustix::fs::MetadataExt::atime(&self.ext)
246308
}
247309

248310
#[inline]
249311
fn atime_nsec(&self) -> i64 {
250-
self.ext.atime_nsec()
312+
rustix::fs::MetadataExt::atime_nsec(&self.ext)
251313
}
252314

253315
#[inline]
254316
fn mtime(&self) -> i64 {
255-
self.ext.mtime()
317+
rustix::fs::MetadataExt::mtime(&self.ext)
256318
}
257319

258320
#[inline]
259321
fn mtime_nsec(&self) -> i64 {
260-
self.ext.mtime_nsec()
322+
rustix::fs::MetadataExt::mtime_nsec(&self.ext)
261323
}
262324

263325
#[inline]
264326
fn ctime(&self) -> i64 {
265-
self.ext.ctime()
327+
rustix::fs::MetadataExt::ctime(&self.ext)
266328
}
267329

268330
#[inline]
269331
fn ctime_nsec(&self) -> i64 {
270-
self.ext.ctime_nsec()
332+
rustix::fs::MetadataExt::ctime_nsec(&self.ext)
271333
}
272334

273335
#[inline]
274336
fn blksize(&self) -> u64 {
275-
self.ext.blksize()
337+
rustix::fs::MetadataExt::blksize(&self.ext)
276338
}
277339

278340
#[inline]
279341
fn blocks(&self) -> u64 {
280-
self.ext.blocks()
342+
rustix::fs::MetadataExt::blocks(&self.ext)
281343
}
282344
}
283345

284346
#[cfg(target_os = "wasi")]
285-
impl std::os::wasi::fs::MetadataExt for Metadata {
347+
impl MetadataExt for Metadata {
286348
#[inline]
287349
fn dev(&self) -> u64 {
288-
self.ext.dev()
350+
rustix::fs::MetadataExt::dev(&self.ext)
289351
}
290352

291353
#[inline]
292354
fn ino(&self) -> u64 {
293-
self.ext.ino()
355+
rustix::fs::MetadataExt::ino(&self.ext)
294356
}
295357

296358
#[inline]
297359
fn nlink(&self) -> u64 {
298-
self.ext.nlink()
360+
rustix::fs::MetadataExt::nlink(&self.ext)
299361
}
300362

301363
#[inline]
302364
fn size(&self) -> u64 {
303-
self.ext.size()
365+
rustix::fs::MetadataExt::size(&self.ext)
304366
}
305367

306368
#[inline]
307369
fn atim(&self) -> u64 {
308-
self.ext.atim()
370+
rustix::fs::MetadataExt::atim(&self.ext)
309371
}
310372

311373
#[inline]
312374
fn mtim(&self) -> u64 {
313-
self.ext.mtim()
375+
rustix::fs::MetadataExt::mtim(&self.ext)
314376
}
315377

316378
#[inline]
317379
fn ctim(&self) -> u64 {
318-
self.ext.ctim()
380+
rustix::fs::MetadataExt::ctim(&self.ext)
319381
}
320382
}
321383

322384
#[cfg(target_os = "vxworks")]
323-
impl std::os::vxworks::fs::MetadataExt for Metadata {
385+
impl MetadataExt for Metadata {
324386
#[inline]
325387
fn dev(&self) -> u64 {
326388
self.ext.dev()
@@ -403,7 +465,7 @@ impl std::os::vxworks::fs::MetadataExt for Metadata {
403465
}
404466

405467
#[cfg(all(windows, windows_by_handle))]
406-
impl std::os::windows::fs::MetadataExt for Metadata {
468+
impl MetadataExt for Metadata {
407469
#[inline]
408470
fn file_attributes(&self) -> u32 {
409471
self.ext.file_attributes()

cap-primitives/src/fs/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -75,14 +75,14 @@ pub use file_type::_WindowsFileTypeExt;
7575
pub use follow_symlinks::FollowSymlinks;
7676
pub use hard_link::hard_link;
7777
pub use is_file_read_write::is_file_read_write;
78-
pub use metadata::Metadata;
7978
#[cfg(windows)]
8079
pub use metadata::_WindowsByHandle;
80+
pub use metadata::{Metadata, MetadataExt};
8181
pub use open::open;
8282
pub use open_ambient::open_ambient;
8383
pub use open_dir::*;
8484
pub use open_options::OpenOptions;
85-
pub use permissions::Permissions;
85+
pub use permissions::{Permissions, PermissionsExt};
8686
pub use read_dir::{read_base_dir, read_dir, ReadDir};
8787
pub use read_link::{read_link, read_link_contents};
8888
pub use remove_dir::remove_dir;

cap-primitives/src/fs/permissions.rs

+26-11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#[cfg(not(windows))]
2-
use crate::fs::PermissionsExt;
2+
use crate::fs::ImplPermissionsExt;
33
#[cfg(unix)]
44
use rustix::fs::RawMode;
55
use std::{fs, io};
@@ -17,7 +17,7 @@ pub struct Permissions {
1717
pub(crate) readonly: bool,
1818

1919
#[cfg(any(unix, target_os = "vxworks"))]
20-
pub(crate) ext: PermissionsExt,
20+
pub(crate) ext: ImplPermissionsExt,
2121
}
2222

2323
impl Permissions {
@@ -29,7 +29,7 @@ impl Permissions {
2929
readonly: std.readonly(),
3030

3131
#[cfg(any(unix, target_os = "vxworks"))]
32-
ext: PermissionsExt::from_std(std),
32+
ext: ImplPermissionsExt::from_std(std),
3333
}
3434
}
3535

@@ -90,29 +90,44 @@ impl Permissions {
9090
}
9191
}
9292

93+
/// Unix-specific extensions to [`Permissions`].
9394
#[cfg(unix)]
94-
impl std::os::unix::fs::PermissionsExt for Permissions {
95+
pub trait PermissionsExt {
96+
/// Returns the underlying raw `st_mode` bits that contain the standard
97+
/// Unix permissions for this file.
98+
fn mode(&self) -> u32;
99+
100+
/// Sets the underlying raw bits for this set of permissions.
101+
fn set_mode(&mut self, mode: u32);
102+
103+
/// Creates a new instance of `Permissions` from the given set of Unix
104+
/// permission bits.
105+
fn from_mode(mode: u32) -> Self;
106+
}
107+
108+
#[cfg(unix)]
109+
impl PermissionsExt for Permissions {
95110
#[inline]
96111
fn mode(&self) -> u32 {
97-
self.ext.mode()
112+
std::os::unix::fs::PermissionsExt::mode(&self.ext)
98113
}
99114

100115
#[inline]
101116
fn set_mode(&mut self, mode: u32) {
102-
self.ext.set_mode(mode)
117+
std::os::unix::fs::PermissionsExt::set_mode(&mut self.ext, mode)
103118
}
104119

105120
#[inline]
106121
fn from_mode(mode: u32) -> Self {
107122
Self {
108-
readonly: PermissionsExt::readonly(mode as RawMode),
109-
ext: PermissionsExt::from_mode(mode),
123+
readonly: ImplPermissionsExt::readonly(mode as RawMode),
124+
ext: std::os::unix::fs::PermissionsExt::from_mode(mode),
110125
}
111126
}
112127
}
113128

114129
#[cfg(target_os = "vxworks")]
115-
impl std::os::unix::fs::PermissionsExt for Permissions {
130+
impl PermissionsExt for Permissions {
116131
#[inline]
117132
fn mode(&self) -> u32 {
118133
self.ext.mode()
@@ -126,8 +141,8 @@ impl std::os::unix::fs::PermissionsExt for Permissions {
126141
#[inline]
127142
fn from_mode(mode: u32) -> Self {
128143
Self {
129-
readonly: PermissionsExt::readonly(mode),
130-
ext: PermissionsExt::from(mode),
144+
readonly: ImplPermissionsExt::readonly(mode),
145+
ext: ImplPermissionsExt::from(mode),
131146
}
132147
}
133148
}

0 commit comments

Comments
 (0)