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