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