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+ #[ expect( clippy:: needless_pass_by_value, reason = "CStr is a borrowed value type" ) ]
14+ pub ( super ) fn openat < R > (
15+ dirfd : BorrowedFd < ' _ > ,
16+ path : CStr < ' _ , R > ,
17+ flags : OFlags ,
18+ mode : Mode ,
19+ ) -> Result < OwnedFd > {
20+ // SAFETY: `dirfd` remains borrowed and `path` is NUL-terminated. The
21+ // kernel receives all four syscall arguments explicitly.
22+ let fd = unsafe {
23+ syscalls:: syscall!(
24+ syscalls:: Sysno :: openat,
25+ dirfd. as_raw_fd( ) ,
26+ path. as_ptr( ) ,
27+ flags. bits( ) ,
28+ mode. bits( )
29+ )
30+ }
31+ . map_err ( |errno| Error :: from_raw_os_error ( errno. into_raw ( ) ) ) ?;
32+
33+ // This should not fail with a well-behaved kernel: `openat` returns a
34+ // nonnegative `c_int` file descriptor.
35+ let fd = i32:: try_from ( fd) . map_err ( |_| Error :: OVERFLOW ) ?;
36+
37+ // SAFETY: a successful `openat` returns a new owned descriptor.
38+ Ok ( unsafe { OwnedFd :: from_raw_fd ( fd) } )
39+ }
40+
41+ #[ expect( clippy:: needless_pass_by_value, reason = "CStr is a borrowed value type" ) ]
42+ pub ( super ) fn unlinkat < R > ( dirfd : BorrowedFd < ' _ > , path : CStr < ' _ , R > , flags : AtFlags ) -> Result < ( ) > {
43+ // SAFETY: `dirfd` remains borrowed and `path` is NUL-terminated for the
44+ // syscall.
45+ unsafe {
46+ syscalls:: syscall!(
47+ syscalls:: Sysno :: unlinkat,
48+ dirfd. as_raw_fd( ) ,
49+ path. as_ptr( ) ,
50+ flags. bits( )
51+ )
52+ }
53+ . map_err ( |errno| Error :: from_raw_os_error ( errno. into_raw ( ) ) ) ?;
54+ Ok ( ( ) )
55+ }
56+
857/// Reads the target of `path` relative to `dirfd` into `buf`.
958///
1059/// The returned bytes borrow the initialized prefix of `buf`. As with the
@@ -25,12 +74,12 @@ pub fn readlinkat<'buf>(
2574 // is writable for `buf.len()` bytes. `readlinkat` returns the initialized
2675 // byte count.
2776 let initialized = unsafe {
28- syscalls:: syscall4 (
77+ syscalls:: syscall! (
2978 syscalls:: Sysno :: readlinkat,
30- ( dirfd. as_raw_fd ( ) as isize ) . cast_unsigned ( ) ,
31- path. as_ptr ( ) . addr ( ) ,
32- buf. as_mut_ptr ( ) . addr ( ) ,
33- buf. len ( ) ,
79+ dirfd. as_raw_fd( ) ,
80+ path. as_ptr( ) ,
81+ buf. as_mut_ptr( ) ,
82+ buf. len( )
3483 )
3584 }
3685 . map_err ( |errno| Error :: from_raw_os_error ( errno. into_raw ( ) ) ) ?;
@@ -46,7 +95,7 @@ pub(super) fn getcwd(buf: &mut [MaybeUninit<u8>]) -> Result<CStr<'_, Fat>> {
4695 // writes no more than that and returns the initialized length including
4796 // its terminating NUL.
4897 let initialized =
49- unsafe { syscalls:: syscall2 ( syscalls:: Sysno :: getcwd, buf. as_mut_ptr ( ) . addr ( ) , buf. len ( ) ) }
98+ unsafe { syscalls:: syscall! ( syscalls:: Sysno :: getcwd, buf. as_mut_ptr( ) , buf. len( ) ) }
5099 . map_err ( |errno| Error :: from_raw_os_error ( errno. into_raw ( ) ) ) ?;
51100
52101 // SAFETY: the syscall initialized this prefix through its terminating NUL.
0 commit comments