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