Skip to content

Commit 4ca7899

Browse files
committed
Support type-safe path FDs
Signed-off-by: Alex Saveau <[email protected]>
1 parent 782a424 commit 4ca7899

17 files changed

+193
-168
lines changed

src/dir.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@
22
33
use crate::errno::Errno;
44
use crate::fcntl::{self, OFlag};
5-
use crate::sys;
5+
use crate::{sys, AsPathFd};
66
use crate::{Error, NixPath, Result};
77
use cfg_if::cfg_if;
88
use std::ffi;
9-
use std::os::unix::io::AsFd;
109
use std::os::unix::io::{AsRawFd, IntoRawFd, RawFd};
1110
use std::ptr;
1211

@@ -44,8 +43,8 @@ impl Dir {
4443
}
4544

4645
/// Opens the given path as with `fcntl::openat`.
47-
pub fn openat<Fd: AsFd, P: ?Sized + NixPath>(
48-
dirfd: &Fd,
46+
pub fn openat<Fd: AsPathFd, P: ?Sized + NixPath>(
47+
dirfd: Fd,
4948
path: &P,
5049
oflag: OFlag,
5150
mode: sys::stat::Mode,

src/fcntl.rs

+29-27
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ use std::os::unix::io::FromRawFd;
99
use std::os::unix::io::OwnedFd;
1010
use std::os::unix::io::RawFd;
1111

12+
#[cfg(not(target_os = "redox"))]
13+
use crate::AsPathFd;
1214
#[cfg(feature = "fs")]
1315
use crate::{sys::stat::Mode, NixPath, Result};
1416
#[cfg(any(target_os = "android", target_os = "linux"))]
@@ -211,15 +213,15 @@ pub fn open<P: ?Sized + NixPath>(
211213
// The conversion is not identical on all operating systems.
212214
#[allow(clippy::useless_conversion)]
213215
#[cfg(not(target_os = "redox"))]
214-
pub fn openat<Fd: AsFd, P: ?Sized + NixPath>(
215-
dirfd: &Fd,
216+
pub fn openat<Fd: AsPathFd, P: ?Sized + NixPath>(
217+
dirfd: Fd,
216218
path: &P,
217219
oflag: OFlag,
218220
mode: Mode,
219221
) -> Result<OwnedFd> {
220222
let fd = path.with_nix_path(|cstr| unsafe {
221223
libc::openat(
222-
dirfd.as_fd().as_raw_fd(),
224+
dirfd.as_path_fd(),
223225
cstr.as_ptr(),
224226
oflag.bits(),
225227
mode.bits() as c_uint,
@@ -230,18 +232,18 @@ pub fn openat<Fd: AsFd, P: ?Sized + NixPath>(
230232
}
231233

232234
#[cfg(not(target_os = "redox"))]
233-
pub fn renameat<Fd1: AsFd, P1: ?Sized + NixPath, Fd2: AsFd, P2: ?Sized + NixPath>(
234-
old_dirfd: &Fd1,
235+
pub fn renameat<Fd1: AsPathFd, P1: ?Sized + NixPath, Fd2: AsPathFd, P2: ?Sized + NixPath>(
236+
old_dirfd: Fd1,
235237
old_path: &P1,
236-
new_dirfd: &Fd2,
238+
new_dirfd: Fd2,
237239
new_path: &P2,
238240
) -> Result<()> {
239241
let res = old_path.with_nix_path(|old_cstr| {
240242
new_path.with_nix_path(|new_cstr| unsafe {
241243
libc::renameat(
242-
old_dirfd.as_fd().as_raw_fd(),
244+
old_dirfd.as_path_fd(),
243245
old_cstr.as_ptr(),
244-
new_dirfd.as_fd().as_raw_fd(),
246+
new_dirfd.as_path_fd(),
245247
new_cstr.as_ptr(),
246248
)
247249
})
@@ -264,19 +266,19 @@ libc_bitflags! {
264266
feature! {
265267
#![feature = "fs"]
266268
#[cfg(all(target_os = "linux", target_env = "gnu"))]
267-
pub fn renameat2<Fd1: AsFd, P1: ?Sized + NixPath, Fd2: AsFd, P2: ?Sized + NixPath>(
268-
old_dirfd: &Fd1,
269+
pub fn renameat2<Fd1: AsPathFd, P1: ?Sized + NixPath, Fd2: AsPathFd, P2: ?Sized + NixPath>(
270+
old_dirfd: Fd1,
269271
old_path: &P1,
270-
new_dirfd: &Fd2,
272+
new_dirfd: Fd2,
271273
new_path: &P2,
272274
flags: RenameFlags,
273275
) -> Result<()> {
274276
let res = old_path.with_nix_path(|old_cstr| {
275277
new_path.with_nix_path(|new_cstr| unsafe {
276278
libc::renameat2(
277-
old_dirfd.as_fd().as_raw_fd(),
279+
old_dirfd.as_path_fd(),
278280
old_cstr.as_ptr(),
279-
new_dirfd.as_fd().as_raw_fd(),
281+
new_dirfd.as_path_fd(),
280282
new_cstr.as_ptr(),
281283
flags.bits(),
282284
)
@@ -404,10 +406,10 @@ pub fn readlink<P: ?Sized + NixPath>(path: &P) -> Result<OsString> {
404406

405407
#[cfg(not(target_os = "redox"))]
406408
pub fn readlinkat<Fd: AsFd, P: ?Sized + NixPath>(
407-
dirfd: &Fd,
409+
dirfd: Fd,
408410
path: &P,
409411
) -> Result<OsString> {
410-
inner_readlink(Some(dirfd), path)
412+
inner_readlink(Some(&dirfd), path)
411413
}
412414
}
413415

@@ -599,9 +601,9 @@ feature! {
599601
/// returned.
600602
#[cfg(any(target_os = "android", target_os = "linux"))]
601603
pub fn copy_file_range<Fd1: AsFd, Fd2: AsFd>(
602-
fd_in: &Fd1,
604+
fd_in: Fd1,
603605
off_in: Option<&mut libc::loff_t>,
604-
fd_out: &Fd2,
606+
fd_out: Fd2,
605607
off_out: Option<&mut libc::loff_t>,
606608
len: usize,
607609
) -> Result<usize> {
@@ -628,9 +630,9 @@ pub fn copy_file_range<Fd1: AsFd, Fd2: AsFd>(
628630

629631
#[cfg(any(target_os = "linux", target_os = "android"))]
630632
pub fn splice<Fd1: AsFd, Fd2: AsFd>(
631-
fd_in: &Fd1,
633+
fd_in: Fd1,
632634
off_in: Option<&mut libc::loff_t>,
633-
fd_out: &Fd2,
635+
fd_out: Fd2,
634636
off_out: Option<&mut libc::loff_t>,
635637
len: usize,
636638
flags: SpliceFFlags,
@@ -657,8 +659,8 @@ pub fn splice<Fd1: AsFd, Fd2: AsFd>(
657659

658660
#[cfg(any(target_os = "linux", target_os = "android"))]
659661
pub fn tee<Fd1: AsFd, Fd2: AsFd>(
660-
fd_in: &Fd1,
661-
fd_out: &Fd2,
662+
fd_in: Fd1,
663+
fd_out: Fd2,
662664
len: usize,
663665
flags: SpliceFFlags,
664666
) -> Result<usize> {
@@ -675,7 +677,7 @@ pub fn tee<Fd1: AsFd, Fd2: AsFd>(
675677

676678
#[cfg(any(target_os = "linux", target_os = "android"))]
677679
pub fn vmsplice<Fd: AsFd>(
678-
fd: &Fd,
680+
fd: Fd,
679681
iov: &[std::io::IoSlice<'_>],
680682
flags: SpliceFFlags,
681683
) -> Result<usize> {
@@ -734,7 +736,7 @@ feature! {
734736
#[cfg(any(target_os = "linux"))]
735737
#[cfg(feature = "fs")]
736738
pub fn fallocate<Fd: AsFd>(
737-
fd: &Fd,
739+
fd: Fd,
738740
mode: FallocateFlags,
739741
offset: libc::off_t,
740742
len: libc::off_t,
@@ -810,7 +812,7 @@ impl SpacectlRange {
810812
/// ```
811813
#[cfg(target_os = "freebsd")]
812814
pub fn fspacectl<Fd: AsFd>(
813-
fd: &Fd,
815+
fd: Fd,
814816
range: SpacectlRange,
815817
) -> Result<SpacectlRange> {
816818
let mut rqsr = libc::spacectl_range {
@@ -861,7 +863,7 @@ pub fn fspacectl<Fd: AsFd>(
861863
/// ```
862864
#[cfg(target_os = "freebsd")]
863865
pub fn fspacectl_all<Fd: AsFd>(
864-
fd: &Fd,
866+
fd: Fd,
865867
offset: libc::off_t,
866868
len: libc::off_t,
867869
) -> Result<()> {
@@ -917,7 +919,7 @@ mod posix_fadvise {
917919
feature! {
918920
#![feature = "fs"]
919921
pub fn posix_fadvise<Fd: AsFd>(
920-
fd: &Fd,
922+
fd: Fd,
921923
offset: libc::off_t,
922924
len: libc::off_t,
923925
advice: PosixFadviseAdvice,
@@ -950,7 +952,7 @@ mod posix_fadvise {
950952
target_os = "freebsd"
951953
))]
952954
pub fn posix_fallocate<Fd: AsFd>(
953-
fd: &Fd,
955+
fd: Fd,
954956
offset: libc::off_t,
955957
len: libc::off_t,
956958
) -> Result<()> {

src/kmod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ libc_bitflags!(
8080
///
8181
/// See [`man init_module(2)`](https://man7.org/linux/man-pages/man2/init_module.2.html) for more information.
8282
pub fn finit_module<Fd: AsFd>(
83-
fd: &Fd,
83+
fd: Fd,
8484
param_values: &CStr,
8585
flags: ModuleInitFlags,
8686
) -> Result<()> {

src/lib.rs

+22-10
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,7 @@ pub mod unistd;
162162
use std::ffi::{CStr, CString, OsStr};
163163
use std::mem::MaybeUninit;
164164
use std::os::unix::ffi::OsStrExt;
165-
#[cfg(not(target_os = "redox"))]
166-
use std::os::unix::io::BorrowedFd;
165+
use std::os::unix::io::{AsFd, AsRawFd, RawFd};
167166
use std::path::{Path, PathBuf};
168167
use std::{ptr, result, slice};
169168

@@ -184,16 +183,29 @@ pub type Result<T> = result::Result<T, Errno>;
184183
/// ones.
185184
pub type Error = Errno;
186185

187-
/// A file descriptor representing the current working directory.
186+
/// A trait that models requirements for path file descriptors.
187+
pub trait AsPathFd {
188+
/// Extracts the raw file descriptor.
189+
fn as_path_fd(&self) -> RawFd;
190+
}
191+
192+
impl<Fd: AsFd> AsPathFd for Fd {
193+
fn as_path_fd(&self) -> RawFd {
194+
self.as_fd().as_raw_fd()
195+
}
196+
}
197+
198+
/// The `AT_FDCWD` marker FD.
199+
#[cfg(not(target_os = "redox"))]
200+
#[derive(Copy, Clone, Debug)]
201+
pub struct Cwd;
202+
188203
#[cfg(not(target_os = "redox"))]
189-
pub const AT_FDCWD: &BorrowedFd<'static> = unsafe {
190-
&BorrowedFd::borrow_raw(if cfg!(target_os = "haiku") {
191-
// Hack to work around BorrowedFd not allowing -1
192-
-2
193-
} else {
204+
impl AsPathFd for Cwd {
205+
fn as_path_fd(&self) -> RawFd {
194206
libc::AT_FDCWD
195-
})
196-
};
207+
}
208+
}
197209

198210
/// Common trait used to represent file system paths by many Nix functions.
199211
pub trait NixPath {

0 commit comments

Comments
 (0)