@@ -7,18 +7,21 @@ use libc::{c_char, c_int};
77use sigsafe:: { AsRawFd as _, BorrowedFd , CWD } ;
88
99#[ cfg( target_os = "linux" ) ]
10- fn get_fd_path < A : Allocator > ( fd : BorrowedFd < ' _ > , allocator : A ) -> nix:: Result < Option < Vec < u8 , A > > > {
10+ fn get_fd_path < ' a , A : Allocator > (
11+ fd : BorrowedFd < ' _ > ,
12+ allocator : & ' a A ,
13+ ) -> nix:: Result < Option < & ' a BStr > > {
1114 if fd. as_raw_fd ( ) == CWD . as_raw_fd ( ) {
1215 let path = sigsafe_alloc:: fs:: getcwd ( allocator)
1316 . map_err ( |errno| nix:: errno:: Errno :: from_raw ( errno. raw_os_error ( ) ) ) ?
1417 . into_bytes ( ) ;
15- return Ok ( Some ( path) ) ;
18+ return Ok ( Some ( path. leak ( ) . as_bstr ( ) ) ) ;
1619 }
1720
1821 let mut path = [ 0 ; PROC_FD_PATH_CAPACITY ] ;
1922 let path = proc_fd_path ( fd, & mut path) ;
2023 match sigsafe_alloc:: fs:: readlink ( allocator, path) {
21- Ok ( path) => Ok ( Some ( path) ) ,
24+ Ok ( path) => Ok ( Some ( path. leak ( ) . as_bstr ( ) ) ) ,
2225 Err ( sigsafe:: Errno :: BADF | sigsafe:: Errno :: NOENT ) => Ok ( None ) ,
2326 Err ( errno) => Err ( nix:: errno:: Errno :: from_raw ( errno. raw_os_error ( ) ) ) ,
2427 }
@@ -61,30 +64,35 @@ fn proc_fd_path<'buf>(
6164}
6265
6366#[ cfg( target_os = "macos" ) ]
64- fn get_fd_path < A : Allocator > ( fd : BorrowedFd < ' _ > , allocator : A ) -> nix:: Result < Option < Vec < u8 , A > > > {
67+ fn get_fd_path < ' a , A : Allocator > (
68+ fd : BorrowedFd < ' _ > ,
69+ allocator : & ' a A ,
70+ ) -> nix:: Result < Option < & ' a BStr > > {
6571 if fd. as_raw_fd ( ) == CWD . as_raw_fd ( ) {
6672 let path = sigsafe_alloc:: fs:: getcwd ( allocator)
6773 . map_err ( |errno| nix:: errno:: Errno :: from_raw ( errno. raw_os_error ( ) ) ) ?
6874 . into_bytes ( ) ;
69- return Ok ( Some ( path) ) ;
75+ return Ok ( Some ( path. leak ( ) . as_bstr ( ) ) ) ;
7076 }
7177
7278 match sigsafe_alloc:: fs:: fcntl_getpath ( allocator, fd) {
7379 Ok ( path) => {
7480 // `F_GETPATH` does not return a length. Count at this caller before
7581 // converting its allocation into the returned path.
76- Ok ( Some ( path. count ( ) . into_bytes ( ) ) )
82+ Ok ( Some ( path. count ( ) . into_bytes ( ) . leak ( ) . as_bstr ( ) ) )
7783 }
7884 Err ( sigsafe:: Errno :: BADF | sigsafe:: Errno :: NOENT ) => Ok ( None ) ,
7985 Err ( errno) => Err ( nix:: errno:: Errno :: from_raw ( errno. raw_os_error ( ) ) ) ,
8086 }
8187}
8288
8389pub trait ToAbsolutePath {
84- unsafe fn to_absolute_path < R , F : FnOnce ( Option < & BStr > ) -> nix :: Result < R > > (
90+ unsafe fn to_absolute_path < ' a , A : Allocator > (
8591 self ,
86- f : F ,
87- ) -> nix:: Result < R > ;
92+ allocator : & ' a A ,
93+ ) -> nix:: Result < Option < & ' a BStr > >
94+ where
95+ Self : ' a ;
8896}
8997
9098pub struct Fd < ' fd > ( pub BorrowedFd < ' fd > ) ;
@@ -106,23 +114,14 @@ impl Fd<'_> {
106114}
107115
108116impl ToAbsolutePath for Fd < ' _ > {
109- unsafe fn to_absolute_path < R , F : FnOnce ( Option < & BStr > ) -> nix :: Result < R > > (
117+ unsafe fn to_absolute_path < ' a , A : Allocator > (
110118 self ,
111- f : F ,
112- ) -> nix:: Result < R > {
113- #[ cfg( target_os = "linux" ) ]
114- {
115- let arena = sigsafe_alloc:: arena ( ) ;
116- let path = get_fd_path ( self . 0 , & arena) ?;
117- f ( path. as_ref ( ) . map ( |path| path. as_slice ( ) . as_bstr ( ) ) )
118- }
119-
120- #[ cfg( target_os = "macos" ) ]
121- {
122- let arena = sigsafe_alloc:: arena ( ) ;
123- let path = get_fd_path ( self . 0 , & arena) ?;
124- f ( path. as_ref ( ) . map ( |path| path. as_slice ( ) . as_bstr ( ) ) )
125- }
119+ allocator : & ' a A ,
120+ ) -> nix:: Result < Option < & ' a BStr > >
121+ where
122+ Self : ' a ,
123+ {
124+ get_fd_path ( self . 0 , allocator)
126125 }
127126}
128127
@@ -141,51 +140,52 @@ impl<'path, Repr> PathAt<'_, 'path, Repr> {
141140}
142141
143142impl < Repr > ToAbsolutePath for PathAt < ' _ , ' _ , Repr > {
144- unsafe fn to_absolute_path < R , F : FnOnce ( Option < & BStr > ) -> nix :: Result < R > > (
143+ unsafe fn to_absolute_path < ' a , A : Allocator > (
145144 self ,
146- f : F ,
147- ) -> nix:: Result < R > {
145+ allocator : & ' a A ,
146+ ) -> nix:: Result < Option < & ' a BStr > >
147+ where
148+ Self : ' a ,
149+ {
148150 // SAFETY: self.1 is a valid NUL-terminated string.
149151 let pathname = unsafe { CStr :: from_ptr ( self . 1 . as_ptr ( ) ) } . to_bytes ( ) . as_bstr ( ) ;
150152
151153 if pathname. first ( ) . copied ( ) == Some ( b'/' ) {
152- f ( pathname . into ( ) )
154+ Ok ( Some ( pathname ) )
153155 } else {
154156 // SAFETY: delegates the same caller-provided descriptor to Fd.
155- unsafe {
156- Fd ( self . 0 ) . to_absolute_path ( |base| {
157- let Some ( base) = base else {
158- return f ( None ) ;
159- } ;
160- if pathname. is_empty ( ) {
161- return f ( Some ( base) ) ;
162- }
163-
164- let arena = sigsafe_alloc:: arena ( ) ;
165- let needs_separator = !base. ends_with ( b"/" ) ;
166- let mut abs_path = Vec :: with_capacity_in (
167- base. len ( ) + usize:: from ( needs_separator) + pathname. len ( ) ,
168- & arena,
169- ) ;
170- abs_path. extend_from_slice ( base) ;
171- if needs_separator {
172- abs_path. push ( b'/' ) ;
173- }
174- abs_path. extend_from_slice ( pathname) ;
175- f ( Some ( abs_path. as_slice ( ) . as_bstr ( ) ) )
176- } )
157+ let Some ( base) = ( unsafe { Fd ( self . 0 ) . to_absolute_path ( allocator) } ) ? else {
158+ return Ok ( None ) ;
159+ } ;
160+ if pathname. is_empty ( ) {
161+ return Ok ( Some ( base) ) ;
162+ }
163+
164+ let needs_separator = !base. ends_with ( b"/" ) ;
165+ let mut abs_path = Vec :: with_capacity_in (
166+ base. len ( ) + usize:: from ( needs_separator) + pathname. len ( ) ,
167+ allocator,
168+ ) ;
169+ abs_path. extend_from_slice ( base) ;
170+ if needs_separator {
171+ abs_path. push ( b'/' ) ;
177172 }
173+ abs_path. extend_from_slice ( pathname) ;
174+ Ok ( Some ( abs_path. leak ( ) . as_bstr ( ) ) )
178175 }
179176 }
180177}
181178
182179impl < Repr > ToAbsolutePath for sigsafe:: CStr < ' _ , Repr > {
183- unsafe fn to_absolute_path < R , F : FnOnce ( Option < & BStr > ) -> nix :: Result < R > > (
180+ unsafe fn to_absolute_path < ' a , A : Allocator > (
184181 self ,
185- f : F ,
186- ) -> nix:: Result < R > {
182+ allocator : & ' a A ,
183+ ) -> nix:: Result < Option < & ' a BStr > >
184+ where
185+ Self : ' a ,
186+ {
187187 // SAFETY: delegates the same caller-provided C string to PathAt.
188- unsafe { PathAt ( CWD , self ) . to_absolute_path ( f ) }
188+ unsafe { PathAt ( CWD , self ) . to_absolute_path ( allocator ) }
189189 }
190190}
191191
0 commit comments