44use std:: {
55 env:: temp_dir,
66 ffi:: OsStr ,
7- fs:: { self , File , OpenOptions } ,
87 io,
98 num:: NonZeroUsize ,
10- os:: unix:: { ffi:: OsStrExt as _, fs :: OpenOptionsExt as _ , io :: IntoRawFd as _ } ,
9+ os:: unix:: ffi:: OsStrExt as _,
1110 path:: PathBuf ,
1211 ptr:: { self , NonNull } ,
1312} ;
@@ -75,19 +74,20 @@ pub fn create(size: usize) -> io::Result<(ShmKeeper, ShmHandle)> {
7574 let path = std:: path:: absolute ( temp_dir ( ) ) ?
7675 . join ( format ! ( "{BACKING_PREFIX}{}.shm" , Uuid :: new_v4( ) . simple( ) ) ) ;
7776
78- let file = OpenOptions :: new ( )
79- . read ( true )
80- . write ( true )
81- . create_new ( true )
77+ let file = open_file (
78+ path. as_os_str ( ) ,
79+ fspy_nostd:: fs:: OFlags :: RDWR
80+ | fspy_nostd:: fs:: OFlags :: CREATE
81+ | fspy_nostd:: fs:: OFlags :: EXCL
82+ | fspy_nostd:: fs:: OFlags :: CLOEXEC ,
8283 // Only the creating user may open the mapping.
83- . mode ( 0o600 )
84- . open ( & path ) ?;
84+ fspy_nostd :: fs :: Mode :: RUSR | fspy_nostd :: fs :: Mode :: WUSR ,
85+ ) ?;
8586 // The keeper exists from here on, so every error path below cleans up.
8687 let keeper = ShmKeeper { path } ;
8788
8889 // Every byte reads as zero because the file is all holes.
89- file. set_len ( size_u64) ?;
90- let file = into_nostd_fd ( file) ;
90+ fspy_nostd:: fs:: ftruncate ( & file, size_u64) . map_err ( error_to_io) ?;
9191
9292 Ok ( ( keeper, ShmHandle { file, size } ) )
9393}
@@ -102,7 +102,11 @@ pub fn create(size: usize) -> io::Result<(ShmKeeper, ShmHandle)> {
102102/// Returns an error if the shared memory is unavailable, which is the common
103103/// case once its keeper has been dropped.
104104pub fn open ( id : & OsStr ) -> io:: Result < ShmHandle > {
105- let file = open_file ( id) ?;
105+ let file = open_file (
106+ id,
107+ fspy_nostd:: fs:: OFlags :: RDWR | fspy_nostd:: fs:: OFlags :: CLOEXEC ,
108+ fspy_nostd:: fs:: Mode :: empty ( ) ,
109+ ) ?;
106110 // If another process shrinks the file before `map`, mapping fails. If it
107111 // resizes afterwards, nothing here touches the mapped pages. A concurrent
108112 // resize cannot make a mapping access invalid memory.
@@ -113,16 +117,21 @@ pub fn open(id: &OsStr) -> io::Result<ShmHandle> {
113117 Ok ( ShmHandle { file, size } )
114118}
115119
116- fn open_file ( path : & OsStr ) -> io:: Result < fspy_nostd:: OwnedFd > {
120+ fn open_file (
121+ path : & OsStr ,
122+ flags : fspy_nostd:: fs:: OFlags ,
123+ mode : fspy_nostd:: fs:: Mode ,
124+ ) -> io:: Result < fspy_nostd:: OwnedFd > {
117125 let mut buf = [ 0_u8 ; fspy_nostd:: fs:: PATH_MAX ] ;
118126 let path = copy_path ( path, & mut buf) ?;
119- fspy_nostd:: fs:: openat (
120- fspy_nostd:: CWD ,
121- path,
122- fspy_nostd:: fs:: OFlags :: RDWR | fspy_nostd:: fs:: OFlags :: CLOEXEC ,
123- fspy_nostd:: fs:: Mode :: empty ( ) ,
124- )
125- . map_err ( error_to_io)
127+ fspy_nostd:: fs:: openat ( fspy_nostd:: CWD , path, flags, mode) . map_err ( error_to_io)
128+ }
129+
130+ fn remove_file ( path : & OsStr ) -> io:: Result < ( ) > {
131+ let mut buf = [ 0_u8 ; fspy_nostd:: fs:: PATH_MAX ] ;
132+ let path = copy_path ( path, & mut buf) ?;
133+ fspy_nostd:: fs:: unlinkat ( fspy_nostd:: CWD , path, fspy_nostd:: fs:: AtFlags :: empty ( ) )
134+ . map_err ( error_to_io)
126135}
127136
128137fn copy_path < ' buf > (
@@ -150,16 +159,9 @@ fn error_to_io(error: fspy_nostd::Error) -> io::Error {
150159 io:: Error :: from_raw_os_error ( error. raw_os_error ( ) )
151160}
152161
153- fn into_nostd_fd ( file : File ) -> fspy_nostd:: OwnedFd {
154- let fd = file. into_raw_fd ( ) ;
155- // SAFETY: ownership of `file`'s descriptor transfers without closing or
156- // duplicating it.
157- unsafe { fspy_nostd:: FromRawFd :: from_raw_fd ( fd) }
158- }
159-
160162impl Drop for ShmKeeper {
161163 fn drop ( & mut self ) {
162- let _ = fs :: remove_file ( & self . path ) ;
164+ let _ = remove_file ( self . path . as_os_str ( ) ) ;
163165 }
164166}
165167
0 commit comments