/rust/registry/src/index.crates.io-6f17d22bba15001f/rustix-0.38.34/src/fs/fd.rs
Line | Count | Source (jump to first uncovered line) |
1 | | //! Functions which operate on file descriptors. |
2 | | |
3 | | #[cfg(not(target_os = "wasi"))] |
4 | | use crate::fs::Mode; |
5 | | #[cfg(not(target_os = "wasi"))] |
6 | | use crate::fs::{Gid, Uid}; |
7 | | use crate::fs::{OFlags, SeekFrom, Timespec}; |
8 | | use crate::{backend, io}; |
9 | | use backend::fd::{AsFd, BorrowedFd}; |
10 | | #[cfg(not(any( |
11 | | netbsdlike, |
12 | | solarish, |
13 | | target_os = "dragonfly", |
14 | | target_os = "espidf", |
15 | | target_os = "nto", |
16 | | target_os = "redox", |
17 | | target_os = "vita", |
18 | | )))] |
19 | | use backend::fs::types::FallocateFlags; |
20 | | #[cfg(not(any( |
21 | | target_os = "espidf", |
22 | | target_os = "solaris", |
23 | | target_os = "vita", |
24 | | target_os = "wasi" |
25 | | )))] |
26 | | use backend::fs::types::FlockOperation; |
27 | | #[cfg(linux_kernel)] |
28 | | use backend::fs::types::FsWord; |
29 | | use backend::fs::types::Stat; |
30 | | #[cfg(not(any( |
31 | | solarish, |
32 | | target_os = "espidf", |
33 | | target_os = "haiku", |
34 | | target_os = "netbsd", |
35 | | target_os = "nto", |
36 | | target_os = "redox", |
37 | | target_os = "vita", |
38 | | target_os = "wasi", |
39 | | )))] |
40 | | use backend::fs::types::StatFs; |
41 | | #[cfg(not(any(target_os = "haiku", target_os = "redox", target_os = "wasi")))] |
42 | | use backend::fs::types::StatVfs; |
43 | | use core::fmt; |
44 | | |
45 | | /// Timestamps used by [`utimensat`] and [`futimens`]. |
46 | | /// |
47 | | /// [`utimensat`]: crate::fs::utimensat |
48 | | /// [`futimens`]: crate::fs::futimens |
49 | | // This is `repr(C)` and specifically laid out to match the representation used |
50 | | // by `utimensat` and `futimens`, which expect 2-element arrays of timestamps. |
51 | | #[repr(C)] |
52 | | #[derive(Clone)] |
53 | | pub struct Timestamps { |
54 | | /// The timestamp of the last access to a filesystem object. |
55 | | pub last_access: Timespec, |
56 | | |
57 | | /// The timestamp of the last modification of a filesystem object. |
58 | | pub last_modification: Timespec, |
59 | | } |
60 | | |
61 | | impl fmt::Debug for Timestamps { |
62 | 0 | fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
63 | 0 | fmt.debug_struct("Timestamps") |
64 | 0 | .field("last_access.tv_sec", &self.last_access.tv_sec) |
65 | 0 | .field("last_access.tv_nsec", &self.last_access.tv_nsec) |
66 | 0 | .field("last_modification.tv_sec", &self.last_modification.tv_sec) |
67 | 0 | .field("last_modification.tv_nsec", &self.last_modification.tv_nsec) |
68 | 0 | .finish() |
69 | 0 | } |
70 | | } |
71 | | |
72 | | /// The filesystem magic number for procfs. |
73 | | /// |
74 | | /// See [the `fstatfs` manual page] for more information. |
75 | | /// |
76 | | /// [the `fstatfs` manual page]: https://man7.org/linux/man-pages/man2/fstatfs.2.html#DESCRIPTION |
77 | | #[cfg(linux_kernel)] |
78 | | pub const PROC_SUPER_MAGIC: FsWord = backend::c::PROC_SUPER_MAGIC as FsWord; |
79 | | |
80 | | /// The filesystem magic number for NFS. |
81 | | /// |
82 | | /// See [the `fstatfs` manual page] for more information. |
83 | | /// |
84 | | /// [the `fstatfs` manual page]: https://man7.org/linux/man-pages/man2/fstatfs.2.html#DESCRIPTION |
85 | | #[cfg(linux_kernel)] |
86 | | pub const NFS_SUPER_MAGIC: FsWord = backend::c::NFS_SUPER_MAGIC as FsWord; |
87 | | |
88 | | /// `lseek(fd, offset, whence)`—Repositions a file descriptor within a file. |
89 | | /// |
90 | | /// # References |
91 | | /// - [POSIX] |
92 | | /// - [Linux] |
93 | | /// |
94 | | /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/lseek.html |
95 | | /// [Linux]: https://man7.org/linux/man-pages/man2/lseek.2.html |
96 | | #[inline] |
97 | | #[doc(alias = "lseek")] |
98 | 0 | pub fn seek<Fd: AsFd>(fd: Fd, pos: SeekFrom) -> io::Result<u64> { |
99 | 0 | backend::fs::syscalls::seek(fd.as_fd(), pos) |
100 | 0 | } |
101 | | |
102 | | /// `lseek(fd, 0, SEEK_CUR)`—Returns the current position within a file. |
103 | | /// |
104 | | /// Return the current position of the file descriptor. This is a subset of |
105 | | /// the functionality of `seek`, but this interface makes it easier for users |
106 | | /// to declare their intent not to mutate any state. |
107 | | /// |
108 | | /// # References |
109 | | /// - [POSIX] |
110 | | /// - [Linux] |
111 | | /// |
112 | | /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/lseek.html |
113 | | /// [Linux]: https://man7.org/linux/man-pages/man2/lseek.2.html |
114 | | #[inline] |
115 | | #[doc(alias = "lseek")] |
116 | 0 | pub fn tell<Fd: AsFd>(fd: Fd) -> io::Result<u64> { |
117 | 0 | backend::fs::syscalls::tell(fd.as_fd()) |
118 | 0 | } |
119 | | |
120 | | /// `fchmod(fd, mode)`—Sets open file or directory permissions. |
121 | | /// |
122 | | /// This implementation does not support [`OFlags::PATH`] file descriptors, |
123 | | /// even on platforms where the host libc emulates it. |
124 | | /// |
125 | | /// # References |
126 | | /// - [POSIX] |
127 | | /// - [Linux] |
128 | | /// |
129 | | /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/fchmod.html |
130 | | /// [Linux]: https://man7.org/linux/man-pages/man2/fchmod.2.html |
131 | | #[cfg(not(target_os = "wasi"))] |
132 | | #[inline] |
133 | 0 | pub fn fchmod<Fd: AsFd>(fd: Fd, mode: Mode) -> io::Result<()> { |
134 | 0 | backend::fs::syscalls::fchmod(fd.as_fd(), mode) |
135 | 0 | } |
136 | | |
137 | | /// `fchown(fd, owner, group)`—Sets open file or directory ownership. |
138 | | /// |
139 | | /// # References |
140 | | /// - [POSIX] |
141 | | /// - [Linux] |
142 | | /// |
143 | | /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/fchown.html |
144 | | /// [Linux]: https://man7.org/linux/man-pages/man2/fchown.2.html |
145 | | #[cfg(not(target_os = "wasi"))] |
146 | | #[inline] |
147 | 0 | pub fn fchown<Fd: AsFd>(fd: Fd, owner: Option<Uid>, group: Option<Gid>) -> io::Result<()> { |
148 | 0 | backend::fs::syscalls::fchown(fd.as_fd(), owner, group) |
149 | 0 | } |
150 | | |
151 | | /// `fstat(fd)`—Queries metadata for an open file or directory. |
152 | | /// |
153 | | /// [`Mode::from_raw_mode`] and [`FileType::from_raw_mode`] may be used to |
154 | | /// interpret the `st_mode` field. |
155 | | /// |
156 | | /// # References |
157 | | /// - [POSIX] |
158 | | /// - [Linux] |
159 | | /// |
160 | | /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/fstat.html |
161 | | /// [Linux]: https://man7.org/linux/man-pages/man2/fstat.2.html |
162 | | /// [`Mode::from_raw_mode`]: Mode::from_raw_mode |
163 | | /// [`FileType::from_raw_mode`]: crate::fs::FileType::from_raw_mode |
164 | | #[inline] |
165 | 0 | pub fn fstat<Fd: AsFd>(fd: Fd) -> io::Result<Stat> { |
166 | 0 | backend::fs::syscalls::fstat(fd.as_fd()) |
167 | 0 | } |
168 | | |
169 | | /// `fstatfs(fd)`—Queries filesystem statistics for an open file or directory. |
170 | | /// |
171 | | /// Compared to [`fstatvfs`], this function often provides more information, |
172 | | /// though it's less portable. |
173 | | /// |
174 | | /// # References |
175 | | /// - [Linux] |
176 | | /// |
177 | | /// [Linux]: https://man7.org/linux/man-pages/man2/fstatfs.2.html |
178 | | #[cfg(not(any( |
179 | | solarish, |
180 | | target_os = "espidf", |
181 | | target_os = "haiku", |
182 | | target_os = "netbsd", |
183 | | target_os = "nto", |
184 | | target_os = "redox", |
185 | | target_os = "vita", |
186 | | target_os = "wasi", |
187 | | )))] |
188 | | #[inline] |
189 | 0 | pub fn fstatfs<Fd: AsFd>(fd: Fd) -> io::Result<StatFs> { |
190 | 0 | backend::fs::syscalls::fstatfs(fd.as_fd()) |
191 | 0 | } |
192 | | |
193 | | /// `fstatvfs(fd)`—Queries filesystem statistics for an open file or |
194 | | /// directory, POSIX version. |
195 | | /// |
196 | | /// Compared to [`fstatfs`], this function often provides less information, |
197 | | /// but it is more portable. But even so, filesystems are very diverse and not |
198 | | /// all the fields are meaningful for every filesystem. And `f_fsid` doesn't |
199 | | /// seem to have a clear meaning anywhere. |
200 | | /// |
201 | | /// # References |
202 | | /// - [POSIX] |
203 | | /// - [Linux] |
204 | | /// |
205 | | /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/fstatvfs.html |
206 | | /// [Linux]: https://man7.org/linux/man-pages/man2/fstatvfs.2.html |
207 | | #[cfg(not(any(target_os = "haiku", target_os = "redox", target_os = "wasi")))] |
208 | | #[inline] |
209 | 0 | pub fn fstatvfs<Fd: AsFd>(fd: Fd) -> io::Result<StatVfs> { |
210 | 0 | backend::fs::syscalls::fstatvfs(fd.as_fd()) |
211 | 0 | } |
212 | | |
213 | | /// `futimens(fd, times)`—Sets timestamps for an open file or directory. |
214 | | /// |
215 | | /// # References |
216 | | /// - [POSIX] |
217 | | /// - [Linux] |
218 | | /// |
219 | | /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/futimens.html |
220 | | /// [Linux]: https://man7.org/linux/man-pages/man2/utimensat.2.html |
221 | | #[cfg(not(any(target_os = "espidf", target_os = "vita")))] |
222 | | #[inline] |
223 | 0 | pub fn futimens<Fd: AsFd>(fd: Fd, times: &Timestamps) -> io::Result<()> { |
224 | 0 | backend::fs::syscalls::futimens(fd.as_fd(), times) |
225 | 0 | } |
226 | | |
227 | | /// `fallocate(fd, mode, offset, len)`—Adjusts file allocation. |
228 | | /// |
229 | | /// This is a more general form of `posix_fallocate`, adding a `mode` argument |
230 | | /// which modifies the behavior. On platforms which only support |
231 | | /// `posix_fallocate` and not the more general form, no `FallocateFlags` values |
232 | | /// are defined so it will always be empty. |
233 | | /// |
234 | | /// # References |
235 | | /// - [POSIX] |
236 | | /// - [Linux `fallocate`] |
237 | | /// - [Linux `posix_fallocate`] |
238 | | /// |
239 | | /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_fallocate.html |
240 | | /// [Linux `fallocate`]: https://man7.org/linux/man-pages/man2/fallocate.2.html |
241 | | /// [Linux `posix_fallocate`]: https://man7.org/linux/man-pages/man3/posix_fallocate.3.html |
242 | | #[cfg(not(any( |
243 | | netbsdlike, |
244 | | solarish, |
245 | | target_os = "dragonfly", |
246 | | target_os = "espidf", |
247 | | target_os = "nto", |
248 | | target_os = "redox", |
249 | | target_os = "vita", |
250 | | )))] // not implemented in libc for netbsd yet |
251 | | #[inline] |
252 | | #[doc(alias = "posix_fallocate")] |
253 | 0 | pub fn fallocate<Fd: AsFd>(fd: Fd, mode: FallocateFlags, offset: u64, len: u64) -> io::Result<()> { |
254 | 0 | backend::fs::syscalls::fallocate(fd.as_fd(), mode, offset, len) |
255 | 0 | } |
256 | | |
257 | | /// `fcntl(fd, F_GETFL) & O_ACCMODE` |
258 | | /// |
259 | | /// Returns a pair of booleans indicating whether the file descriptor is |
260 | | /// readable and/or writable, respectively. This is only reliable on files; for |
261 | | /// example, it doesn't reflect whether sockets have been shut down; for |
262 | | /// general I/O handle support, use [`io::is_read_write`]. |
263 | | #[inline] |
264 | 0 | pub fn is_file_read_write<Fd: AsFd>(fd: Fd) -> io::Result<(bool, bool)> { |
265 | 0 | _is_file_read_write(fd.as_fd()) |
266 | 0 | } |
267 | | |
268 | 0 | pub(crate) fn _is_file_read_write(fd: BorrowedFd<'_>) -> io::Result<(bool, bool)> { |
269 | 0 | let mode = backend::fs::syscalls::fcntl_getfl(fd)?; |
270 | | |
271 | | // Check for `O_PATH`. |
272 | | #[cfg(any(linux_kernel, target_os = "emscripten", target_os = "fuchsia"))] |
273 | 0 | if mode.contains(OFlags::PATH) { |
274 | 0 | return Ok((false, false)); |
275 | 0 | } |
276 | 0 |
|
277 | 0 | // Use `RWMODE` rather than `ACCMODE` as `ACCMODE` may include `O_PATH`. |
278 | 0 | // We handled `O_PATH` above. |
279 | 0 | match mode & OFlags::RWMODE { |
280 | 0 | OFlags::RDONLY => Ok((true, false)), |
281 | 0 | OFlags::RDWR => Ok((true, true)), |
282 | 0 | OFlags::WRONLY => Ok((false, true)), |
283 | 0 | _ => unreachable!(), |
284 | | } |
285 | 0 | } |
286 | | |
287 | | /// `fsync(fd)`—Ensures that file data and metadata is written to the |
288 | | /// underlying storage device. |
289 | | /// |
290 | | /// On iOS and macOS this isn't sufficient to ensure that data has reached |
291 | | /// persistent storage; use [`fcntl_fullfsync`] to ensure that. |
292 | | /// |
293 | | /// # References |
294 | | /// - [POSIX] |
295 | | /// - [Linux] |
296 | | /// |
297 | | /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/fsync.html |
298 | | /// [Linux]: https://man7.org/linux/man-pages/man2/fsync.2.html |
299 | | /// [`fcntl_fullfsync`]: https://docs.rs/rustix/*/x86_64-apple-darwin/rustix/fs/fn.fcntl_fullfsync.html |
300 | | #[inline] |
301 | 0 | pub fn fsync<Fd: AsFd>(fd: Fd) -> io::Result<()> { |
302 | 0 | backend::fs::syscalls::fsync(fd.as_fd()) |
303 | 0 | } |
304 | | |
305 | | /// `fdatasync(fd)`—Ensures that file data is written to the underlying |
306 | | /// storage device. |
307 | | /// |
308 | | /// # References |
309 | | /// - [POSIX] |
310 | | /// - [Linux] |
311 | | /// |
312 | | /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/fdatasync.html |
313 | | /// [Linux]: https://man7.org/linux/man-pages/man2/fdatasync.2.html |
314 | | #[cfg(not(any( |
315 | | apple, |
316 | | target_os = "dragonfly", |
317 | | target_os = "espidf", |
318 | | target_os = "haiku", |
319 | | target_os = "redox", |
320 | | target_os = "vita", |
321 | | )))] |
322 | | #[inline] |
323 | 0 | pub fn fdatasync<Fd: AsFd>(fd: Fd) -> io::Result<()> { |
324 | 0 | backend::fs::syscalls::fdatasync(fd.as_fd()) |
325 | 0 | } |
326 | | |
327 | | /// `ftruncate(fd, length)`—Sets the length of a file. |
328 | | /// |
329 | | /// # References |
330 | | /// - [POSIX] |
331 | | /// - [Linux] |
332 | | /// |
333 | | /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/ftruncate.html |
334 | | /// [Linux]: https://man7.org/linux/man-pages/man2/ftruncate.2.html |
335 | | #[inline] |
336 | 0 | pub fn ftruncate<Fd: AsFd>(fd: Fd, length: u64) -> io::Result<()> { |
337 | 0 | backend::fs::syscalls::ftruncate(fd.as_fd(), length) |
338 | 0 | } |
339 | | |
340 | | /// `flock(fd, operation)`—Acquire or release an advisory lock on an open file. |
341 | | /// |
342 | | /// # References |
343 | | /// - [Linux] |
344 | | /// |
345 | | /// [Linux]: https://man7.org/linux/man-pages/man2/flock.2.html |
346 | | #[cfg(not(any( |
347 | | target_os = "espidf", |
348 | | target_os = "solaris", |
349 | | target_os = "vita", |
350 | | target_os = "wasi" |
351 | | )))] |
352 | | #[inline] |
353 | 0 | pub fn flock<Fd: AsFd>(fd: Fd, operation: FlockOperation) -> io::Result<()> { |
354 | 0 | backend::fs::syscalls::flock(fd.as_fd(), operation) |
355 | 0 | } Unexecuted instantiation: rustix::fs::fd::flock::<&std::os::fd::owned::BorrowedFd> Unexecuted instantiation: rustix::fs::fd::flock::<_> |
356 | | |
357 | | /// `syncfs(fd)`—Flush cached filesystem data. |
358 | | /// |
359 | | /// # References |
360 | | /// - [Linux] |
361 | | /// |
362 | | /// [Linux]: https://man7.org/linux/man-pages/man2/syncfs.2.html |
363 | | #[cfg(linux_kernel)] |
364 | | #[inline] |
365 | 0 | pub fn syncfs<Fd: AsFd>(fd: Fd) -> io::Result<()> { |
366 | 0 | backend::fs::syscalls::syncfs(fd.as_fd()) |
367 | 0 | } |