1
+ //! file control options
1
2
use crate :: errno:: Errno ;
2
3
#[ cfg( all( target_os = "freebsd" , target_arch = "x86_64" ) ) ]
3
4
use core:: slice;
@@ -45,15 +46,29 @@ pub use self::posix_fadvise::{posix_fadvise, PosixFadviseAdvice};
45
46
#[ cfg( not( target_os = "redox" ) ) ]
46
47
#[ cfg( any( feature = "fs" , feature = "process" , feature = "user" ) ) ]
47
48
libc_bitflags ! {
49
+ /// Flags that control how the various *at syscalls behave.
48
50
#[ cfg_attr( docsrs, doc( cfg( any( feature = "fs" , feature = "process" ) ) ) ) ]
49
51
pub struct AtFlags : c_int {
52
+ #[ allow( missing_docs) ]
53
+ #[ doc( hidden) ]
54
+ // Should not be used by the public API, but only internally.
50
55
AT_REMOVEDIR ;
56
+ /// Used with [`linkat`](crate::unistd::linkat`) to create a link to a symbolic link's
57
+ /// target, instead of to the symbolic link itself.
51
58
AT_SYMLINK_FOLLOW ;
59
+ /// Used with functions like [`fstatat`](crate::sys::stat::fstatat`) to operate on a link
60
+ /// itself, instead of the symbolic link's target.
52
61
AT_SYMLINK_NOFOLLOW ;
62
+ /// Don't automount the terminal ("basename") component of pathname if it is a directory
63
+ /// that is an automount point.
53
64
#[ cfg( linux_android) ]
54
65
AT_NO_AUTOMOUNT ;
66
+ /// If the provided path is an empty string, operate on the provided directory file
67
+ /// descriptor instead.
55
68
#[ cfg( any( linux_android, target_os = "freebsd" , target_os = "hurd" ) ) ]
56
69
AT_EMPTY_PATH ;
70
+ /// Used with [`faccessat`](crate::unistd::faccessat), the checks for accessibility are
71
+ /// performed using the effective user and group IDs instead of the real user and group ID
57
72
#[ cfg( not( target_os = "android" ) ) ]
58
73
AT_EACCESS ;
59
74
}
@@ -186,6 +201,10 @@ pub(crate) fn at_rawfd(fd: Option<RawFd>) -> raw::c_int {
186
201
feature ! {
187
202
#![ feature = "fs" ]
188
203
204
+ /// open or create a file for reading, writing or executing
205
+ ///
206
+ /// # See Also
207
+ /// [`open`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html)
189
208
// The conversion is not identical on all operating systems.
190
209
#[ allow( clippy:: useless_conversion) ]
191
210
pub fn open<P : ?Sized + NixPath >(
@@ -200,6 +219,14 @@ pub fn open<P: ?Sized + NixPath>(
200
219
Errno :: result( fd)
201
220
}
202
221
222
+ /// open or create a file for reading, writing or executing
223
+ ///
224
+ /// The `openat` function is equivalent to the [`open`] function except in the case where the path
225
+ /// specifies a relative path. In that case, the file to be opened is determined relative to the
226
+ /// directory associated with the file descriptor `fd`.
227
+ ///
228
+ /// # See Also
229
+ /// [`openat`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/openat.html)
203
230
// The conversion is not identical on all operating systems.
204
231
#[ allow( clippy:: useless_conversion) ]
205
232
#[ cfg( not( target_os = "redox" ) ) ]
@@ -215,6 +242,14 @@ pub fn openat<P: ?Sized + NixPath>(
215
242
Errno :: result( fd)
216
243
}
217
244
245
+ /// Change the name of a file.
246
+ ///
247
+ /// The `renameat` function is equivalent to `rename` except in the case where either `old_path`
248
+ /// or `new_path` specifies a relative path. In such cases, the file to be renamed (or the its new
249
+ /// name, respectively) is located relative to `old_dirfd` or `new_dirfd`, respectively
250
+ ///
251
+ /// # See Also
252
+ /// [`renameat`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/rename.html)
218
253
#[ cfg( not( target_os = "redox" ) ) ]
219
254
pub fn renameat<P1 : ?Sized + NixPath , P2 : ?Sized + NixPath >(
220
255
old_dirfd: Option <RawFd >,
@@ -239,16 +274,30 @@ pub fn renameat<P1: ?Sized + NixPath, P2: ?Sized + NixPath>(
239
274
#[ cfg( all( target_os = "linux" , target_env = "gnu" ) ) ]
240
275
#[ cfg( feature = "fs" ) ]
241
276
libc_bitflags ! {
277
+ /// Flags for use with [`renameat2`].
242
278
#[ cfg_attr( docsrs, doc( cfg( feature = "fs" ) ) ) ]
243
279
pub struct RenameFlags : u32 {
280
+ /// Atomically exchange `old_path` and `new_path`.
244
281
RENAME_EXCHANGE ;
282
+ /// Don't overwrite `new_path` of the rename. Return an error if `new_path` already
283
+ /// exists.
245
284
RENAME_NOREPLACE ;
285
+ /// creates a "whiteout" object at the source of the rename at the same time as performing
286
+ /// the rename.
287
+ ///
288
+ /// This operation makes sense only for overlay/union filesystem implementations.
246
289
RENAME_WHITEOUT ;
247
290
}
248
291
}
249
292
250
293
feature ! {
251
294
#![ feature = "fs" ]
295
+ /// Like [`renameat`], but with an additional `flags` argument.
296
+ ///
297
+ /// A `renameat2` call with an empty flags argument is equivalent to `renameat`.
298
+ ///
299
+ /// # See Also
300
+ /// * [`rename`](https://man7.org/linux/man-pages/man2/rename.2.html)
252
301
#[ cfg( all( target_os = "linux" , target_env = "gnu" ) ) ]
253
302
pub fn renameat2<P1 : ?Sized + NixPath , P2 : ?Sized + NixPath >(
254
303
old_dirfd: Option <RawFd >,
@@ -389,10 +438,21 @@ fn inner_readlink<P: ?Sized + NixPath>(
389
438
}
390
439
}
391
440
441
+ /// Read value of a symbolic link
442
+ ///
443
+ /// # See Also
444
+ /// * [`readlink`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/readlink.html)
392
445
pub fn readlink<P : ?Sized + NixPath >( path: & P ) -> Result <OsString > {
393
446
inner_readlink( None , path)
394
447
}
395
448
449
+ /// Read value of a symbolic link.
450
+ ///
451
+ /// Equivalent to [`readlink` ] except where `path` specifies a relative path. In that case,
452
+ /// interpret `path` relative to open file specified by `dirfd`.
453
+ ///
454
+ /// # See Also
455
+ /// * [`readlink`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/readlink.html)
396
456
#[ cfg( not( target_os = "redox" ) ) ]
397
457
pub fn readlinkat<P : ?Sized + NixPath >(
398
458
dirfd: Option <RawFd >,
@@ -437,69 +497,105 @@ libc_bitflags!(
437
497
feature ! {
438
498
#![ feature = "fs" ]
439
499
500
+ /// Commands for use with [`fcntl`].
440
501
#[ cfg( not( target_os = "redox" ) ) ]
441
502
#[ derive( Debug , Eq , Hash , PartialEq ) ]
442
503
#[ non_exhaustive]
443
504
pub enum FcntlArg <' a> {
505
+ /// Duplicate the provided file descriptor
444
506
F_DUPFD ( RawFd ) ,
507
+ /// Duplicate the provided file descriptor and set the `FD_CLOEXEC` flag on it.
445
508
F_DUPFD_CLOEXEC ( RawFd ) ,
509
+ /// Get the close-on-exec flag associated with the file descriptor
446
510
F_GETFD ,
511
+ /// Set the close-on-exec flag associated with the file descriptor
447
512
F_SETFD ( FdFlag ) , // FD_FLAGS
513
+ /// Get descriptor status flags
448
514
F_GETFL ,
515
+ /// Set descriptor status flags
449
516
F_SETFL ( OFlag ) , // O_NONBLOCK
517
+ /// Set or clear a file segment lock
450
518
F_SETLK ( & ' a libc:: flock) ,
519
+ /// Like [`F_SETLK`](FcntlArg::F_SETLK) except that if a shared or exclusive lock is blocked by
520
+ /// other locks, the process waits until the request can be satisfied.
451
521
F_SETLKW ( & ' a libc:: flock) ,
522
+ /// Get the first lock that blocks the lock description
452
523
F_GETLK ( & ' a mut libc:: flock) ,
524
+ /// Acquire or release an open file description lock
453
525
#[ cfg( linux_android) ]
454
526
F_OFD_SETLK ( & ' a libc:: flock) ,
527
+ /// Like [`F_OFD_SETLK`](FcntlArg::F_OFD_SETLK) except that if a conflicting lock is held on
528
+ /// the file, then wait for that lock to be released.
455
529
#[ cfg( linux_android) ]
456
530
F_OFD_SETLKW ( & ' a libc:: flock) ,
531
+ /// Determine whether it would be possible to create the given lock. If not, return details
532
+ /// about one existing lock that would prevent it.
457
533
#[ cfg( linux_android) ]
458
534
F_OFD_GETLK ( & ' a mut libc:: flock) ,
535
+ /// Add seals to the file
459
536
#[ cfg( any(
460
537
linux_android,
461
538
target_os = "freebsd"
462
539
) ) ]
463
540
F_ADD_SEALS ( SealFlag ) ,
541
+ /// Get seals associated with the file
464
542
#[ cfg( any(
465
543
linux_android,
466
544
target_os = "freebsd"
467
545
) ) ]
468
546
F_GET_SEALS ,
547
+ /// Asks the drive to flush all buffered data to permanent storage.
469
548
#[ cfg( apple_targets) ]
470
549
F_FULLFSYNC ,
550
+ /// fsync + issue barrier to drive
471
551
#[ cfg( apple_targets) ]
472
552
F_BARRIERFSYNC ,
553
+ /// Return the capacity of a pipe
473
554
#[ cfg( linux_android) ]
474
555
F_GETPIPE_SZ ,
556
+ /// Change the capacity of a pipe
475
557
#[ cfg( linux_android) ]
476
558
F_SETPIPE_SZ ( c_int) ,
559
+ /// Look up the path of an open file descriptor, if possible.
477
560
#[ cfg( any(
478
561
target_os = "netbsd" ,
479
562
target_os = "dragonfly" ,
480
563
apple_targets,
481
564
) ) ]
482
565
F_GETPATH ( & ' a mut PathBuf ) ,
566
+ /// Look up the path of an open file descriptor, if possible.
483
567
#[ cfg( all( target_os = "freebsd" , target_arch = "x86_64" ) ) ]
484
568
F_KINFO ( & ' a mut PathBuf ) ,
569
+ /// Return the full path without firmlinks of the fd.
485
570
#[ cfg( apple_targets) ]
486
571
F_GETPATH_NOFIRMLINK ( & ' a mut PathBuf ) ,
487
572
// TODO: Rest of flags
488
573
}
489
574
575
+ /// Commands for use with [`fcntl`].
490
576
#[ cfg( target_os = "redox" ) ]
491
577
#[ derive( Debug , Clone , Copy , Eq , Hash , PartialEq ) ]
492
578
#[ non_exhaustive]
493
579
pub enum FcntlArg {
580
+ /// Duplicate the provided file descriptor
494
581
F_DUPFD ( RawFd ) ,
582
+ /// Duplicate the provided file descriptor and set the `FD_CLOEXEC` flag on it.
495
583
F_DUPFD_CLOEXEC ( RawFd ) ,
584
+ /// Get the close-on-exec flag associated with the file descriptor
496
585
F_GETFD ,
586
+ /// Set the close-on-exec flag associated with the file descriptor
497
587
F_SETFD ( FdFlag ) , // FD_FLAGS
588
+ /// Get descriptor status flags
498
589
F_GETFL ,
590
+ /// Set descriptor status flags
499
591
F_SETFL ( OFlag ) , // O_NONBLOCK
500
592
}
501
593
pub use self :: FcntlArg :: * ;
502
594
595
+ /// Perform various operations on open file descriptors.
596
+ ///
597
+ /// # See Also
598
+ /// * [`fcntl`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fcntl.html)
503
599
// TODO: Figure out how to handle value fcntl returns
504
600
pub fn fcntl( fd: RawFd , arg: FcntlArg ) -> Result <c_int> {
505
601
let res = unsafe {
@@ -584,17 +680,27 @@ pub fn fcntl(fd: RawFd, arg: FcntlArg) -> Result<c_int> {
584
680
Errno :: result( res)
585
681
}
586
682
683
+ /// Operations for use with [`Flock::lock`].
684
+ #[ cfg( not( any( target_os = "redox" , target_os = "solaris" ) ) ) ]
587
685
#[ derive( Clone , Copy , Debug , Eq , Hash , PartialEq ) ]
588
686
#[ non_exhaustive]
589
687
pub enum FlockArg {
688
+ /// shared file lock
590
689
LockShared ,
690
+ /// exclusive file lock
591
691
LockExclusive ,
692
+ /// Unlock file
592
693
Unlock ,
694
+ /// Shared lock. Do not block when locking.
593
695
LockSharedNonblock ,
696
+ /// Exclusive lock. Do not block when locking.
594
697
LockExclusiveNonblock ,
698
+ #[ allow( missing_docs) ]
699
+ #[ deprecated( since = "0.28.0" , note = "Use FlockArg::Unlock instead" ) ]
595
700
UnlockNonblock ,
596
701
}
597
702
703
+ #[ allow( missing_docs) ]
598
704
#[ cfg( not( any( target_os = "redox" , target_os = "solaris" ) ) ) ]
599
705
#[ deprecated( since = "0.28.0" , note = "`fcntl::Flock` should be used instead." ) ]
600
706
pub fn flock( fd: RawFd , arg: FlockArg ) -> Result <( ) > {
@@ -611,6 +717,7 @@ pub fn flock(fd: RawFd, arg: FlockArg) -> Result<()> {
611
717
LockExclusiveNonblock => {
612
718
libc:: flock( fd, libc:: LOCK_EX | libc:: LOCK_NB )
613
719
}
720
+ #[ allow( deprecated) ]
614
721
UnlockNonblock => libc:: flock( fd, libc:: LOCK_UN | libc:: LOCK_NB ) ,
615
722
}
616
723
} ;
@@ -683,6 +790,7 @@ impl<T: Flockable> Flock<T> {
683
790
FlockArg :: LockExclusive => libc:: LOCK_EX ,
684
791
FlockArg :: LockSharedNonblock => libc:: LOCK_SH | libc:: LOCK_NB ,
685
792
FlockArg :: LockExclusiveNonblock => libc:: LOCK_EX | libc:: LOCK_NB ,
793
+ #[ allow( deprecated) ]
686
794
FlockArg :: Unlock | FlockArg :: UnlockNonblock => return Err ( ( t, Errno :: EINVAL ) ) ,
687
795
} ;
688
796
match Errno :: result( unsafe { libc:: flock( t. as_raw_fd( ) , flags) } ) {
@@ -827,6 +935,10 @@ pub fn copy_file_range<Fd1: AsFd, Fd2: AsFd>(
827
935
Errno :: result( ret) . map( |r| r as usize )
828
936
}
829
937
938
+ /// Splice data to/from a pipe
939
+ ///
940
+ /// # See Also
941
+ /// *[`splice`](https://man7.org/linux/man-pages/man2/splice.2.html)
830
942
#[ cfg( linux_android) ]
831
943
pub fn splice(
832
944
fd_in: RawFd ,
@@ -849,6 +961,10 @@ pub fn splice(
849
961
Errno :: result( ret) . map( |r| r as usize )
850
962
}
851
963
964
+ /// Duplicate pipe content
965
+ ///
966
+ /// # See Also
967
+ /// *[`tee`](https://man7.org/linux/man-pages/man2/tee.2.html)
852
968
#[ cfg( linux_android) ]
853
969
pub fn tee(
854
970
fd_in: RawFd ,
@@ -860,6 +976,10 @@ pub fn tee(
860
976
Errno :: result( ret) . map( |r| r as usize )
861
977
}
862
978
979
+ /// Splice user pages to/from a pipe
980
+ ///
981
+ /// # See Also
982
+ /// *[`vmsplice`](https://man7.org/linux/man-pages/man2/vmsplice.2.html)
863
983
#[ cfg( linux_android) ]
864
984
pub fn vmsplice(
865
985
fd: RawFd ,
@@ -938,16 +1058,22 @@ pub struct SpacectlRange(pub libc::off_t, pub libc::off_t);
938
1058
939
1059
#[ cfg( any( target_os = "freebsd" ) ) ]
940
1060
impl SpacectlRange {
1061
+ /// Is the range empty?
1062
+ ///
1063
+ /// After a successful call to [`fspacectl`], A value of `true` for `SpacectlRange::is_empty`
1064
+ /// indicates that the operation is complete.
941
1065
#[ inline]
942
1066
pub fn is_empty( & self ) -> bool {
943
1067
self . 1 == 0
944
1068
}
945
1069
1070
+ /// Remaining length of the range
946
1071
#[ inline]
947
1072
pub fn len( & self ) -> libc:: off_t {
948
1073
self . 1
949
1074
}
950
1075
1076
+ /// Next file offset to operate on
951
1077
#[ inline]
952
1078
pub fn offset( & self ) -> libc:: off_t {
953
1079
self . 0
@@ -1083,21 +1209,34 @@ mod posix_fadvise {
1083
1209
1084
1210
#[ cfg( feature = "fs" ) ]
1085
1211
libc_enum! {
1212
+ /// The specific advice provided to [`posix_fadvise`].
1086
1213
#[ repr( i32 ) ]
1087
1214
#[ non_exhaustive]
1088
1215
#[ cfg_attr( docsrs, doc( cfg( feature = "fs" ) ) ) ]
1089
1216
pub enum PosixFadviseAdvice {
1217
+ /// Revert to the default data access behavior.
1090
1218
POSIX_FADV_NORMAL ,
1219
+ /// The file data will be accessed sequentially.
1091
1220
POSIX_FADV_SEQUENTIAL ,
1221
+ /// A hint that file data will be accessed randomly, and prefetching is likely not
1222
+ /// advantageous.
1092
1223
POSIX_FADV_RANDOM ,
1224
+ /// The specified data will only be accessed once and then not reused.
1093
1225
POSIX_FADV_NOREUSE ,
1226
+ /// The specified data will be accessed in the near future.
1094
1227
POSIX_FADV_WILLNEED ,
1228
+ /// The specified data will not be accessed in the near future.
1095
1229
POSIX_FADV_DONTNEED ,
1096
1230
}
1097
1231
}
1098
1232
1099
1233
feature! {
1100
1234
#![ feature = "fs" ]
1235
+ /// Allows a process to describe to the system its data access behavior for an open file
1236
+ /// descriptor.
1237
+ ///
1238
+ /// # See Also
1239
+ /// * [`posix_fadvise`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_fadvise.html)
1101
1240
pub fn posix_fadvise(
1102
1241
fd: RawFd ,
1103
1242
offset: libc:: off_t,
@@ -1115,6 +1254,10 @@ mod posix_fadvise {
1115
1254
}
1116
1255
}
1117
1256
1257
+ /// Pre-allocate storage for a range in a file
1258
+ ///
1259
+ /// # See Also
1260
+ /// * [`posix_fallocate`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_fallocate.html)
1118
1261
#[ cfg( any(
1119
1262
linux_android,
1120
1263
freebsdlike,
0 commit comments