@@ -13,8 +13,8 @@ use std::sync::Arc;
13
13
14
14
use vmm_sys_util:: fam:: { FamStruct , FamStructWrapper } ;
15
15
16
- use super :: mount_fd:: { MountFd , MountFds , MountId } ;
17
- use super :: util :: enosys ;
16
+ use super :: mount_fd:: { MPRResult , MountFd , MountFds , MountId } ;
17
+ use crate :: api :: EMPTY_CSTR ;
18
18
19
19
/// An arbitrary maximum size for CFileHandle::f_handle.
20
20
///
@@ -243,6 +243,33 @@ impl FileHandle {
243
243
handle : c_fh,
244
244
} ) )
245
245
}
246
+
247
+ /// Create a file handle from a `fd`.
248
+ /// This is a wrapper around `from_name_at()` and so has the same interface.
249
+ pub fn from_fd ( fd : & impl AsRawFd ) -> io:: Result < Option < Self > > {
250
+ // Safe because this is a constant value and a valid C string.
251
+ let empty_path = unsafe { CStr :: from_bytes_with_nul_unchecked ( EMPTY_CSTR ) } ;
252
+ Self :: from_name_at ( fd, empty_path)
253
+ }
254
+
255
+ /// Return an openable copy of the file handle by ensuring that `mount_fd` contains a valid fd
256
+ /// for the mount the file handle is for.
257
+ ///
258
+ /// `reopen_fd` will be invoked to duplicate an `O_PATH` fd with custom `libc::open()` flags.
259
+ pub fn into_openable < F > (
260
+ self ,
261
+ mount_fds : & MountFds ,
262
+ reopen_fd : F ,
263
+ ) -> MPRResult < OpenableFileHandle >
264
+ where
265
+ F : FnOnce ( RawFd , libc:: c_int , u32 ) -> io:: Result < File > ,
266
+ {
267
+ let mount_fd = mount_fds. get ( self . mnt_id , reopen_fd) ?;
268
+ Ok ( OpenableFileHandle {
269
+ handle : Arc :: new ( self ) ,
270
+ mount_fd,
271
+ } )
272
+ }
246
273
}
247
274
248
275
pub struct OpenableFileHandle {
@@ -264,39 +291,6 @@ impl Debug for OpenableFileHandle {
264
291
}
265
292
266
293
impl OpenableFileHandle {
267
- /// Create a file handle for the given file.
268
- ///
269
- /// Also ensure that `mount_fds` contains a valid fd for the mount the file is on (so that
270
- /// `handle.open_with_mount_fds()` will work).
271
- ///
272
- /// If `path` is empty, `reopen_dir` may be invoked to duplicate `dir` with custom
273
- /// `libc::open()` flags.
274
- pub fn from_name_at < F > (
275
- dir_fd : & impl AsRawFd ,
276
- path : & CStr ,
277
- mount_fds : & MountFds ,
278
- reopen_dir : F ,
279
- ) -> io:: Result < OpenableFileHandle >
280
- where
281
- F : FnOnce ( RawFd , libc:: c_int , u32 ) -> io:: Result < File > ,
282
- {
283
- let handle = FileHandle :: from_name_at ( dir_fd, path)
284
- . map_err ( |e| {
285
- error ! ( "from_name_at failed error {:?}" , e) ;
286
- e
287
- } ) ?
288
- . ok_or_else ( enosys) ?;
289
-
290
- let mount_fd = mount_fds
291
- . get ( handle. mnt_id , reopen_dir)
292
- . map_err ( |e| e. into_inner ( ) ) ?;
293
-
294
- Ok ( OpenableFileHandle {
295
- handle : Arc :: new ( handle) ,
296
- mount_fd,
297
- } )
298
- }
299
-
300
294
/// Open a file from an openable file handle.
301
295
pub fn open ( & self , flags : libc:: c_int ) -> io:: Result < File > {
302
296
let ret = unsafe {
@@ -317,10 +311,6 @@ impl OpenableFileHandle {
317
311
}
318
312
}
319
313
320
- pub fn mount_id ( & self ) -> MountId {
321
- self . handle . mnt_id
322
- }
323
-
324
314
pub fn file_handle ( & self ) -> & Arc < FileHandle > {
325
315
& self . handle
326
316
}
@@ -443,29 +433,4 @@ mod tests {
443
433
0
444
434
) ;
445
435
}
446
-
447
- #[ test]
448
- fn test_openable_file_handle ( ) {
449
- let uid = getuid ( ) ;
450
- if !uid. is_root ( ) {
451
- return ;
452
- }
453
-
454
- let topdir = env ! ( "CARGO_MANIFEST_DIR" ) ;
455
- let dir = File :: open ( topdir) . unwrap ( ) ;
456
- let filename = CString :: new ( "build.rs" ) . unwrap ( ) ;
457
- let mount_fds = MountFds :: new ( None ) . unwrap ( ) ;
458
-
459
- let file_handle =
460
- OpenableFileHandle :: from_name_at ( & dir, & filename, & mount_fds, |_fd, _flags, _mode| {
461
- File :: open ( topdir)
462
- } )
463
- . unwrap ( ) ;
464
- assert_eq ! ( file_handle. handle. mnt_id, file_handle. mount_id( ) ) ;
465
-
466
- let mut file = file_handle. open ( libc:: O_RDONLY ) . unwrap ( ) ;
467
- let mut buffer = [ 0u8 ; 1024 ] ;
468
- let res = file. read ( & mut buffer) . unwrap ( ) ;
469
- assert ! ( res > 0 ) ;
470
- }
471
436
}
0 commit comments