11use core:: { mem:: MaybeUninit , slice} ;
22
3- use crate :: { AsRawFd as _, BorrowedFd , CStr , Error , Fat , Result , Thin } ;
3+ use rustix:: fd:: FromRawFd as _;
4+
5+ use crate :: {
6+ AsRawFd as _, BorrowedFd , CStr , Error , Fat , OwnedFd , Result , Thin ,
7+ fs:: { AtFlags , Mode , OFlags } ,
8+ } ;
49
510// Linux UAPI `PATH_MAX`.
611pub ( super ) const PATH_MAX : usize = 4096 ;
712
13+ fn syscall_fd ( fd : BorrowedFd < ' _ > ) -> Result < usize > {
14+ let fd = isize:: try_from ( fd. as_raw_fd ( ) ) . map_err ( |_| Error :: OVERFLOW ) ?;
15+ Ok ( fd. cast_unsigned ( ) )
16+ }
17+
18+ #[ expect( clippy:: needless_pass_by_value, reason = "CStr is a borrowed value type" ) ]
19+ pub ( super ) fn openat < R > (
20+ dirfd : BorrowedFd < ' _ > ,
21+ path : CStr < ' _ , R > ,
22+ flags : OFlags ,
23+ mode : Mode ,
24+ ) -> Result < OwnedFd > {
25+ // SAFETY: `dirfd` remains borrowed and `path` is NUL-terminated. The
26+ // kernel receives all four syscall arguments explicitly.
27+ let fd = unsafe {
28+ syscalls:: syscall4 (
29+ syscalls:: Sysno :: openat,
30+ syscall_fd ( dirfd) ?,
31+ path. as_ptr ( ) . addr ( ) ,
32+ usize:: try_from ( flags. bits ( ) ) . map_err ( |_| Error :: INVAL ) ?,
33+ usize:: try_from ( mode. bits ( ) ) . map_err ( |_| Error :: INVAL ) ?,
34+ )
35+ }
36+ . map_err ( |errno| Error :: from_raw_os_error ( errno. into_raw ( ) ) ) ?;
37+ let fd = i32:: try_from ( fd) . map_err ( |_| Error :: OVERFLOW ) ?;
38+
39+ // SAFETY: a successful `openat` returns a new owned descriptor.
40+ Ok ( unsafe { OwnedFd :: from_raw_fd ( fd) } )
41+ }
42+
43+ #[ expect( clippy:: needless_pass_by_value, reason = "CStr is a borrowed value type" ) ]
44+ pub ( super ) fn unlinkat < R > ( dirfd : BorrowedFd < ' _ > , path : CStr < ' _ , R > , flags : AtFlags ) -> Result < ( ) > {
45+ // SAFETY: `dirfd` remains borrowed and `path` is NUL-terminated for the
46+ // syscall.
47+ unsafe {
48+ syscalls:: syscall3 (
49+ syscalls:: Sysno :: unlinkat,
50+ syscall_fd ( dirfd) ?,
51+ path. as_ptr ( ) . addr ( ) ,
52+ usize:: try_from ( flags. bits ( ) ) . map_err ( |_| Error :: INVAL ) ?,
53+ )
54+ }
55+ . map_err ( |errno| Error :: from_raw_os_error ( errno. into_raw ( ) ) ) ?;
56+ Ok ( ( ) )
57+ }
58+
859/// Reads the target of `path` relative to `dirfd` into `buf`.
960///
1061/// The returned bytes borrow the initialized prefix of `buf`. As with the
@@ -27,7 +78,7 @@ pub fn readlinkat<'buf>(
2778 let initialized = unsafe {
2879 syscalls:: syscall4 (
2980 syscalls:: Sysno :: readlinkat,
30- ( dirfd. as_raw_fd ( ) as isize ) . cast_unsigned ( ) ,
81+ syscall_fd ( dirfd) ? ,
3182 path. as_ptr ( ) . addr ( ) ,
3283 buf. as_mut_ptr ( ) . addr ( ) ,
3384 buf. len ( ) ,
0 commit comments