openat/
lib.rs

1//! # Handling Files Relative to File Descriptor
2//!
3//! Main concept here is a `Dir` which holds `O_PATH` file descriptor, you
4//! can create it with:
5//!
6//! * `Dir::open("/some/path")` -- open this directory as a file descriptor
7//! * `Dir::from_raw_fd(fd)` -- uses a file descriptor provided elsewhere
8//!
9//! *Note after opening file descriptors refer to same directory regardless of
10//! where it's moved or mounted (with `pivot_root` or `mount --move`). It may
11//! also be unmounted or be out of chroot and you will still be able to
12//! access files relative to it.*
13//!
14//! *Note2: The constructor `Dir::cwd()` is deprecated, and it's recommended
15//! to use `Dir::open(".")` instead.*
16//!
17//! *Note3: Some OS's (e.g., macOS) do not provide `O_PATH`, in which case the
18//! file descriptor is of regular type.*
19//!
20//! Most other operations are done on `Dir` object and are executed relative
21//! to it:
22//!
23//! * `Dir::list_dir()`
24//! * `Dir::sub_dir()`
25//! * `Dir::read_link()`
26//! * `Dir::open_file()`
27//! * `Dir::create_file()`
28//! * `Dir::update_file()`
29//! * `Dir::create_dir()`
30//! * `Dir::symlink()`
31//! * `Dir::local_rename()`
32//!
33//! Functions that expect path relative to the directory accept both the
34//! traditional path-like objects, such as Path, PathBuf and &str, and
35//! `Entry` type returned from `list_dir()`. The latter is faster as underlying
36//! system call wants `CString` and we keep that in entry.
37//!
38//! Note that if path supplied to any method of dir is absolute the Dir file
39//! descriptor is ignored.
40//!
41//! Also while all methods of dir accept any path if you want to prevent
42//! certain symlink attacks and race condition you should only use
43//! a single-component path. I.e. open one part of a chain at a time.
44//!
45#![warn(missing_docs)]
46
47extern crate libc;
48
49mod dir;
50mod list;
51mod name;
52mod filetype;
53mod metadata;
54
55pub use crate::list::DirIter;
56pub use crate::name::AsPath;
57pub use crate::dir::{rename, hardlink};
58pub use crate::filetype::SimpleType;
59pub use crate::metadata::Metadata;
60
61use std::ffi::CString;
62use std::os::unix::io::RawFd;
63
64/// A safe wrapper around directory file descriptor
65///
66/// Construct it either with ``Dir::cwd()`` or ``Dir::open(path)``
67///
68#[derive(Debug)]
69pub struct Dir(RawFd);
70
71/// Entry returned by iterating over `DirIter` iterator
72#[derive(Debug)]
73pub struct Entry {
74    name: CString,
75    file_type: Option<SimpleType>,
76}
77
78#[cfg(test)]
79mod test {
80    use std::mem;
81    use super::Dir;
82
83    fn assert_sync<T: Sync>(x: T) -> T { x }
84    fn assert_send<T: Send>(x: T) -> T { x }
85
86    #[test]
87    fn test() {
88        let d = Dir(3);
89        let d = assert_sync(d);
90        let d = assert_send(d);
91        // don't execute close for our fake RawFd
92        mem::forget(d);
93    }
94}
95