Skip to content

Commit d9e1146

Browse files
authored
Add docs to the time and fcntl modules (#2289)
* Add docs to the time and fcntl modules Also, deprecate FlockArg::UnlockNonblock. That combination of flags doesn't make sense. And indeed, reviewing the kernel source code shows that the kernel will ignore LOCK_NB when LOCK_UN is set. * Respond to @SteveLauC's review feedback.
1 parent 254ded9 commit d9e1146

File tree

3 files changed

+181
-8
lines changed

3 files changed

+181
-8
lines changed

src/fcntl.rs

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
//! file control options
12
use crate::errno::Errno;
23
#[cfg(all(target_os = "freebsd", target_arch = "x86_64"))]
34
use core::slice;
@@ -45,15 +46,29 @@ pub use self::posix_fadvise::{posix_fadvise, PosixFadviseAdvice};
4546
#[cfg(not(target_os = "redox"))]
4647
#[cfg(any(feature = "fs", feature = "process", feature = "user"))]
4748
libc_bitflags! {
49+
/// Flags that control how the various *at syscalls behave.
4850
#[cfg_attr(docsrs, doc(cfg(any(feature = "fs", feature = "process"))))]
4951
pub struct AtFlags: c_int {
52+
#[allow(missing_docs)]
53+
#[doc(hidden)]
54+
// Should not be used by the public API, but only internally.
5055
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.
5158
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.
5261
AT_SYMLINK_NOFOLLOW;
62+
/// Don't automount the terminal ("basename") component of pathname if it is a directory
63+
/// that is an automount point.
5364
#[cfg(linux_android)]
5465
AT_NO_AUTOMOUNT;
66+
/// If the provided path is an empty string, operate on the provided directory file
67+
/// descriptor instead.
5568
#[cfg(any(linux_android, target_os = "freebsd", target_os = "hurd"))]
5669
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
5772
#[cfg(not(target_os = "android"))]
5873
AT_EACCESS;
5974
}
@@ -186,6 +201,10 @@ pub(crate) fn at_rawfd(fd: Option<RawFd>) -> raw::c_int {
186201
feature! {
187202
#![feature = "fs"]
188203

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)
189208
// The conversion is not identical on all operating systems.
190209
#[allow(clippy::useless_conversion)]
191210
pub fn open<P: ?Sized + NixPath>(
@@ -200,6 +219,14 @@ pub fn open<P: ?Sized + NixPath>(
200219
Errno::result(fd)
201220
}
202221

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)
203230
// The conversion is not identical on all operating systems.
204231
#[allow(clippy::useless_conversion)]
205232
#[cfg(not(target_os = "redox"))]
@@ -215,6 +242,14 @@ pub fn openat<P: ?Sized + NixPath>(
215242
Errno::result(fd)
216243
}
217244

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)
218253
#[cfg(not(target_os = "redox"))]
219254
pub fn renameat<P1: ?Sized + NixPath, P2: ?Sized + NixPath>(
220255
old_dirfd: Option<RawFd>,
@@ -239,16 +274,30 @@ pub fn renameat<P1: ?Sized + NixPath, P2: ?Sized + NixPath>(
239274
#[cfg(all(target_os = "linux", target_env = "gnu"))]
240275
#[cfg(feature = "fs")]
241276
libc_bitflags! {
277+
/// Flags for use with [`renameat2`].
242278
#[cfg_attr(docsrs, doc(cfg(feature = "fs")))]
243279
pub struct RenameFlags: u32 {
280+
/// Atomically exchange `old_path` and `new_path`.
244281
RENAME_EXCHANGE;
282+
/// Don't overwrite `new_path` of the rename. Return an error if `new_path` already
283+
/// exists.
245284
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.
246289
RENAME_WHITEOUT;
247290
}
248291
}
249292

250293
feature! {
251294
#![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)
252301
#[cfg(all(target_os = "linux", target_env = "gnu"))]
253302
pub fn renameat2<P1: ?Sized + NixPath, P2: ?Sized + NixPath>(
254303
old_dirfd: Option<RawFd>,
@@ -389,10 +438,21 @@ fn inner_readlink<P: ?Sized + NixPath>(
389438
}
390439
}
391440

441+
/// Read value of a symbolic link
442+
///
443+
/// # See Also
444+
/// * [`readlink`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/readlink.html)
392445
pub fn readlink<P: ?Sized + NixPath>(path: &P) -> Result<OsString> {
393446
inner_readlink(None, path)
394447
}
395448

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)
396456
#[cfg(not(target_os = "redox"))]
397457
pub fn readlinkat<P: ?Sized + NixPath>(
398458
dirfd: Option<RawFd>,
@@ -437,69 +497,105 @@ libc_bitflags!(
437497
feature! {
438498
#![feature = "fs"]
439499

500+
/// Commands for use with [`fcntl`].
440501
#[cfg(not(target_os = "redox"))]
441502
#[derive(Debug, Eq, Hash, PartialEq)]
442503
#[non_exhaustive]
443504
pub enum FcntlArg<'a> {
505+
/// Duplicate the provided file descriptor
444506
F_DUPFD(RawFd),
507+
/// Duplicate the provided file descriptor and set the `FD_CLOEXEC` flag on it.
445508
F_DUPFD_CLOEXEC(RawFd),
509+
/// Get the close-on-exec flag associated with the file descriptor
446510
F_GETFD,
511+
/// Set the close-on-exec flag associated with the file descriptor
447512
F_SETFD(FdFlag), // FD_FLAGS
513+
/// Get descriptor status flags
448514
F_GETFL,
515+
/// Set descriptor status flags
449516
F_SETFL(OFlag), // O_NONBLOCK
517+
/// Set or clear a file segment lock
450518
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.
451521
F_SETLKW(&'a libc::flock),
522+
/// Get the first lock that blocks the lock description
452523
F_GETLK(&'a mut libc::flock),
524+
/// Acquire or release an open file description lock
453525
#[cfg(linux_android)]
454526
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.
455529
#[cfg(linux_android)]
456530
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.
457533
#[cfg(linux_android)]
458534
F_OFD_GETLK(&'a mut libc::flock),
535+
/// Add seals to the file
459536
#[cfg(any(
460537
linux_android,
461538
target_os = "freebsd"
462539
))]
463540
F_ADD_SEALS(SealFlag),
541+
/// Get seals associated with the file
464542
#[cfg(any(
465543
linux_android,
466544
target_os = "freebsd"
467545
))]
468546
F_GET_SEALS,
547+
/// Asks the drive to flush all buffered data to permanent storage.
469548
#[cfg(apple_targets)]
470549
F_FULLFSYNC,
550+
/// fsync + issue barrier to drive
471551
#[cfg(apple_targets)]
472552
F_BARRIERFSYNC,
553+
/// Return the capacity of a pipe
473554
#[cfg(linux_android)]
474555
F_GETPIPE_SZ,
556+
/// Change the capacity of a pipe
475557
#[cfg(linux_android)]
476558
F_SETPIPE_SZ(c_int),
559+
/// Look up the path of an open file descriptor, if possible.
477560
#[cfg(any(
478561
target_os = "netbsd",
479562
target_os = "dragonfly",
480563
apple_targets,
481564
))]
482565
F_GETPATH(&'a mut PathBuf),
566+
/// Look up the path of an open file descriptor, if possible.
483567
#[cfg(all(target_os = "freebsd", target_arch = "x86_64"))]
484568
F_KINFO(&'a mut PathBuf),
569+
/// Return the full path without firmlinks of the fd.
485570
#[cfg(apple_targets)]
486571
F_GETPATH_NOFIRMLINK(&'a mut PathBuf),
487572
// TODO: Rest of flags
488573
}
489574

575+
/// Commands for use with [`fcntl`].
490576
#[cfg(target_os = "redox")]
491577
#[derive(Debug, Clone, Copy, Eq, Hash, PartialEq)]
492578
#[non_exhaustive]
493579
pub enum FcntlArg {
580+
/// Duplicate the provided file descriptor
494581
F_DUPFD(RawFd),
582+
/// Duplicate the provided file descriptor and set the `FD_CLOEXEC` flag on it.
495583
F_DUPFD_CLOEXEC(RawFd),
584+
/// Get the close-on-exec flag associated with the file descriptor
496585
F_GETFD,
586+
/// Set the close-on-exec flag associated with the file descriptor
497587
F_SETFD(FdFlag), // FD_FLAGS
588+
/// Get descriptor status flags
498589
F_GETFL,
590+
/// Set descriptor status flags
499591
F_SETFL(OFlag), // O_NONBLOCK
500592
}
501593
pub use self::FcntlArg::*;
502594

595+
/// Perform various operations on open file descriptors.
596+
///
597+
/// # See Also
598+
/// * [`fcntl`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/fcntl.html)
503599
// TODO: Figure out how to handle value fcntl returns
504600
pub fn fcntl(fd: RawFd, arg: FcntlArg) -> Result<c_int> {
505601
let res = unsafe {
@@ -584,17 +680,27 @@ pub fn fcntl(fd: RawFd, arg: FcntlArg) -> Result<c_int> {
584680
Errno::result(res)
585681
}
586682

683+
/// Operations for use with [`Flock::lock`].
684+
#[cfg(not(any(target_os = "redox", target_os = "solaris")))]
587685
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
588686
#[non_exhaustive]
589687
pub enum FlockArg {
688+
/// shared file lock
590689
LockShared,
690+
/// exclusive file lock
591691
LockExclusive,
692+
/// Unlock file
592693
Unlock,
694+
/// Shared lock. Do not block when locking.
593695
LockSharedNonblock,
696+
/// Exclusive lock. Do not block when locking.
594697
LockExclusiveNonblock,
698+
#[allow(missing_docs)]
699+
#[deprecated(since = "0.28.0", note = "Use FlockArg::Unlock instead")]
595700
UnlockNonblock,
596701
}
597702

703+
#[allow(missing_docs)]
598704
#[cfg(not(any(target_os = "redox", target_os = "solaris")))]
599705
#[deprecated(since = "0.28.0", note = "`fcntl::Flock` should be used instead.")]
600706
pub fn flock(fd: RawFd, arg: FlockArg) -> Result<()> {
@@ -611,6 +717,7 @@ pub fn flock(fd: RawFd, arg: FlockArg) -> Result<()> {
611717
LockExclusiveNonblock => {
612718
libc::flock(fd, libc::LOCK_EX | libc::LOCK_NB)
613719
}
720+
#[allow(deprecated)]
614721
UnlockNonblock => libc::flock(fd, libc::LOCK_UN | libc::LOCK_NB),
615722
}
616723
};
@@ -683,6 +790,7 @@ impl<T: Flockable> Flock<T> {
683790
FlockArg::LockExclusive => libc::LOCK_EX,
684791
FlockArg::LockSharedNonblock => libc::LOCK_SH | libc::LOCK_NB,
685792
FlockArg::LockExclusiveNonblock => libc::LOCK_EX | libc::LOCK_NB,
793+
#[allow(deprecated)]
686794
FlockArg::Unlock | FlockArg::UnlockNonblock => return Err((t, Errno::EINVAL)),
687795
};
688796
match Errno::result(unsafe { libc::flock(t.as_raw_fd(), flags) }) {
@@ -827,6 +935,10 @@ pub fn copy_file_range<Fd1: AsFd, Fd2: AsFd>(
827935
Errno::result(ret).map(|r| r as usize)
828936
}
829937

938+
/// Splice data to/from a pipe
939+
///
940+
/// # See Also
941+
/// *[`splice`](https://man7.org/linux/man-pages/man2/splice.2.html)
830942
#[cfg(linux_android)]
831943
pub fn splice(
832944
fd_in: RawFd,
@@ -849,6 +961,10 @@ pub fn splice(
849961
Errno::result(ret).map(|r| r as usize)
850962
}
851963

964+
/// Duplicate pipe content
965+
///
966+
/// # See Also
967+
/// *[`tee`](https://man7.org/linux/man-pages/man2/tee.2.html)
852968
#[cfg(linux_android)]
853969
pub fn tee(
854970
fd_in: RawFd,
@@ -860,6 +976,10 @@ pub fn tee(
860976
Errno::result(ret).map(|r| r as usize)
861977
}
862978

979+
/// Splice user pages to/from a pipe
980+
///
981+
/// # See Also
982+
/// *[`vmsplice`](https://man7.org/linux/man-pages/man2/vmsplice.2.html)
863983
#[cfg(linux_android)]
864984
pub fn vmsplice(
865985
fd: RawFd,
@@ -938,16 +1058,22 @@ pub struct SpacectlRange(pub libc::off_t, pub libc::off_t);
9381058

9391059
#[cfg(any(target_os = "freebsd"))]
9401060
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.
9411065
#[inline]
9421066
pub fn is_empty(&self) -> bool {
9431067
self.1 == 0
9441068
}
9451069

1070+
/// Remaining length of the range
9461071
#[inline]
9471072
pub fn len(&self) -> libc::off_t {
9481073
self.1
9491074
}
9501075

1076+
/// Next file offset to operate on
9511077
#[inline]
9521078
pub fn offset(&self) -> libc::off_t {
9531079
self.0
@@ -1083,21 +1209,34 @@ mod posix_fadvise {
10831209

10841210
#[cfg(feature = "fs")]
10851211
libc_enum! {
1212+
/// The specific advice provided to [`posix_fadvise`].
10861213
#[repr(i32)]
10871214
#[non_exhaustive]
10881215
#[cfg_attr(docsrs, doc(cfg(feature = "fs")))]
10891216
pub enum PosixFadviseAdvice {
1217+
/// Revert to the default data access behavior.
10901218
POSIX_FADV_NORMAL,
1219+
/// The file data will be accessed sequentially.
10911220
POSIX_FADV_SEQUENTIAL,
1221+
/// A hint that file data will be accessed randomly, and prefetching is likely not
1222+
/// advantageous.
10921223
POSIX_FADV_RANDOM,
1224+
/// The specified data will only be accessed once and then not reused.
10931225
POSIX_FADV_NOREUSE,
1226+
/// The specified data will be accessed in the near future.
10941227
POSIX_FADV_WILLNEED,
1228+
/// The specified data will not be accessed in the near future.
10951229
POSIX_FADV_DONTNEED,
10961230
}
10971231
}
10981232

10991233
feature! {
11001234
#![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)
11011240
pub fn posix_fadvise(
11021241
fd: RawFd,
11031242
offset: libc::off_t,
@@ -1115,6 +1254,10 @@ mod posix_fadvise {
11151254
}
11161255
}
11171256

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)
11181261
#[cfg(any(
11191262
linux_android,
11201263
freebsdlike,

src/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,6 @@ feature! {
118118
#[deny(missing_docs)]
119119
pub mod features;
120120
}
121-
#[allow(missing_docs)]
122121
pub mod fcntl;
123122
feature! {
124123
#![feature = "net"]
@@ -163,7 +162,6 @@ feature! {
163162
pub mod sys;
164163
feature! {
165164
#![feature = "time"]
166-
#[allow(missing_docs)]
167165
pub mod time;
168166
}
169167
// This can be implemented for other platforms as soon as libc

0 commit comments

Comments
 (0)