Coverage Report

Created: 2026-11-11 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/rustix-1.1.6/src/fs/at.rs
Line
Count
Source
1
//! POSIX-style `*at` functions.
2
//!
3
//! The `dirfd` argument to these functions may be a file descriptor for a
4
//! directory, the special value [`CWD`], or the special value [`ABS`].
5
//!
6
//! [`CWD`]: crate::fs::CWD
7
//! [`ABS`]: crate::fs::ABS
8
9
#![allow(unsafe_code)]
10
11
use crate::buffer::Buffer;
12
use crate::fd::OwnedFd;
13
#[cfg(not(any(target_os = "espidf", target_os = "horizon", target_os = "vita")))]
14
use crate::fs::Access;
15
#[cfg(not(any(target_os = "espidf", target_os = "redox")))]
16
use crate::fs::AtFlags;
17
#[cfg(apple)]
18
use crate::fs::CloneFlags;
19
#[cfg(any(linux_kernel, apple, target_os = "redox"))]
20
use crate::fs::RenameFlags;
21
#[cfg(not(target_os = "espidf"))]
22
use crate::fs::Stat;
23
#[cfg(not(any(
24
    apple,
25
    target_os = "espidf",
26
    target_os = "horizon",
27
    target_os = "vita",
28
    target_os = "wasi"
29
)))]
30
use crate::fs::{Dev, FileType};
31
#[cfg(not(any(target_os = "espidf", target_os = "wasi")))]
32
use crate::fs::{Gid, Uid};
33
use crate::fs::{Mode, OFlags};
34
use crate::{backend, io, path};
35
use backend::fd::AsFd;
36
#[cfg(feature = "alloc")]
37
use {
38
    crate::ffi::{CStr, CString},
39
    crate::path::SMALL_PATH_BUFFER_SIZE,
40
    alloc::vec::Vec,
41
    backend::fd::BorrowedFd,
42
};
43
#[cfg(not(any(target_os = "espidf", target_os = "horizon", target_os = "vita")))]
44
use {crate::fs::Timestamps, crate::timespec::Nsecs};
45
46
/// `UTIME_NOW` for use with [`utimensat`].
47
///
48
/// [`utimensat`]: crate::fs::utimensat
49
#[cfg(not(any(
50
    target_os = "espidf",
51
    target_os = "horizon",
52
    target_os = "redox",
53
    target_os = "vita"
54
)))]
55
pub const UTIME_NOW: Nsecs = backend::c::UTIME_NOW as Nsecs;
56
57
/// `UTIME_OMIT` for use with [`utimensat`].
58
///
59
/// [`utimensat`]: crate::fs::utimensat
60
#[cfg(not(any(
61
    target_os = "espidf",
62
    target_os = "horizon",
63
    target_os = "redox",
64
    target_os = "vita"
65
)))]
66
pub const UTIME_OMIT: Nsecs = backend::c::UTIME_OMIT as Nsecs;
67
68
/// `openat(dirfd, path, oflags, mode)`—Opens a file.
69
///
70
/// POSIX guarantees that `openat` will use the lowest unused file descriptor,
71
/// however it is not safe in general to rely on this, as file descriptors may
72
/// be unexpectedly allocated on other threads or in libraries.
73
///
74
/// The `Mode` argument is only significant when creating a file.
75
///
76
/// # References
77
///  - [POSIX]
78
///  - [Linux]
79
///
80
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/openat.html
81
/// [Linux]: https://man7.org/linux/man-pages/man2/openat.2.html
82
#[cfg(not(target_os = "redox"))]
83
#[inline]
84
0
pub fn openat<P: path::Arg, Fd: AsFd>(
85
0
    dirfd: Fd,
86
0
    path: P,
87
0
    oflags: OFlags,
88
0
    create_mode: Mode,
89
0
) -> io::Result<OwnedFd> {
90
0
    path.into_with_c_str(|path| {
91
0
        backend::fs::syscalls::openat(dirfd.as_fd(), path, oflags, create_mode)
92
0
    })
Unexecuted instantiation: rustix::fs::at::openat::<&std::path::Path, &std::fs::File>::{closure#0}
Unexecuted instantiation: rustix::fs::at::openat::<&core::ffi::c_str::CStr, std::os::fd::owned::BorrowedFd>::{closure#0}
Unexecuted instantiation: rustix::fs::at::openat::<&[u8], std::os::fd::owned::BorrowedFd>::{closure#0}
Unexecuted instantiation: rustix::fs::at::openat::<_, _>::{closure#0}
93
0
}
Unexecuted instantiation: rustix::fs::at::openat::<&std::path::Path, &std::fs::File>
Unexecuted instantiation: rustix::fs::at::openat::<&core::ffi::c_str::CStr, std::os::fd::owned::BorrowedFd>
Unexecuted instantiation: rustix::fs::at::openat::<&[u8], std::os::fd::owned::BorrowedFd>
Unexecuted instantiation: rustix::fs::at::openat::<_, _>
94
95
/// `readlinkat(fd, path)`—Reads the contents of a symlink.
96
///
97
/// If `reuse` already has available capacity, reuse it if possible.
98
///
99
/// # References
100
///  - [POSIX]
101
///  - [Linux]
102
///
103
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/readlinkat.html
104
/// [Linux]: https://man7.org/linux/man-pages/man2/readlinkat.2.html
105
#[cfg(all(feature = "alloc", not(target_os = "redox")))]
106
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
107
#[inline]
108
0
pub fn readlinkat<P: path::Arg, Fd: AsFd, B: Into<Vec<u8>>>(
109
0
    dirfd: Fd,
110
0
    path: P,
111
0
    reuse: B,
112
0
) -> io::Result<CString> {
113
0
    path.into_with_c_str(|path| _readlinkat(dirfd.as_fd(), path, reuse.into()))
Unexecuted instantiation: rustix::fs::at::readlinkat::<&std::path::Path, &std::fs::File, alloc::vec::Vec<u8>>::{closure#0}
Unexecuted instantiation: rustix::fs::at::readlinkat::<_, _, _>::{closure#0}
114
0
}
Unexecuted instantiation: rustix::fs::at::readlinkat::<&std::path::Path, &std::fs::File, alloc::vec::Vec<u8>>
Unexecuted instantiation: rustix::fs::at::readlinkat::<_, _, _>
115
116
#[cfg(all(feature = "alloc", not(target_os = "redox")))]
117
#[allow(unsafe_code)]
118
0
fn _readlinkat(dirfd: BorrowedFd<'_>, path: &CStr, mut buffer: Vec<u8>) -> io::Result<CString> {
119
0
    buffer.clear();
120
0
    buffer.reserve(SMALL_PATH_BUFFER_SIZE);
121
122
    loop {
123
0
        let buf = buffer.spare_capacity_mut();
124
125
        // SAFETY: `readlinkat` behaves.
126
0
        let nread = unsafe {
127
0
            backend::fs::syscalls::readlinkat(
128
0
                dirfd.as_fd(),
129
0
                path,
130
0
                (buf.as_mut_ptr().cast(), buf.len()),
131
0
            )?
132
        };
133
134
0
        debug_assert!(nread <= buffer.capacity());
135
0
        if nread < buffer.capacity() {
136
            // SAFETY: From the [documentation]: “On success, these calls
137
            // return the number of bytes placed in buf.”
138
            //
139
            // [documentation]: https://man7.org/linux/man-pages/man2/readlinkat.2.html
140
0
            unsafe {
141
0
                buffer.set_len(nread);
142
0
            }
143
144
            // SAFETY:
145
            // - “readlink places the contents of the symbolic link pathname
146
            //   in the buffer buf”
147
            // - [POSIX definition 3.271: Pathname]: “A string that is used
148
            //   to identify a file.”
149
            // - [POSIX definition 3.375: String]: “A contiguous sequence of
150
            //   bytes terminated by and including the first null byte.”
151
            // - “readlink does not append a terminating null byte to buf.”
152
            //
153
            // Thus, there will be no NUL bytes in the string.
154
            //
155
            // [POSIX definition 3.271: Pathname]: https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap03.html#tag_03_271
156
            // [POSIX definition 3.375: String]: https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap03.html#tag_03_375
157
            unsafe {
158
0
                return Ok(CString::from_vec_unchecked(buffer));
159
            }
160
0
        }
161
162
        // Use `Vec` reallocation strategy to grow capacity exponentially.
163
0
        buffer.reserve(buffer.capacity() + 1);
164
    }
165
0
}
166
167
/// `readlinkat(fd, path)`—Reads the contents of a symlink, without
168
/// allocating.
169
///
170
/// This is the "raw" version which avoids allocating, but which truncates the
171
/// string if it doesn't fit in the provided buffer, and doesn't NUL-terminate
172
/// the string.
173
///
174
/// # References
175
///  - [POSIX]
176
///  - [Linux]
177
///
178
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/readlinkat.html
179
/// [Linux]: https://man7.org/linux/man-pages/man2/readlinkat.2.html
180
#[cfg(not(target_os = "redox"))]
181
#[inline]
182
0
pub fn readlinkat_raw<P: path::Arg, Fd: AsFd, Buf: Buffer<u8>>(
183
0
    dirfd: Fd,
184
0
    path: P,
185
0
    mut buf: Buf,
186
0
) -> io::Result<Buf::Output> {
187
    // SAFETY: `readlinkat` behaves.
188
0
    let len = path.into_with_c_str(|path| unsafe {
189
0
        backend::fs::syscalls::readlinkat(dirfd.as_fd(), path, buf.parts_mut())
190
0
    })?;
Unexecuted instantiation: rustix::fs::at::readlinkat_raw::<&core::ffi::c_str::CStr, std::os::fd::owned::OwnedFd, &mut [core::mem::maybe_uninit::MaybeUninit<u8>; 20]>::{closure#0}
Unexecuted instantiation: rustix::fs::at::readlinkat_raw::<&core::ffi::c_str::CStr, std::os::fd::owned::BorrowedFd, &mut [core::mem::maybe_uninit::MaybeUninit<u8>]>::{closure#0}
191
    // SAFETY: `readlinkat` behaves.
192
0
    unsafe { Ok(buf.assume_init(len)) }
193
0
}
Unexecuted instantiation: rustix::fs::at::readlinkat_raw::<&core::ffi::c_str::CStr, std::os::fd::owned::OwnedFd, &mut [core::mem::maybe_uninit::MaybeUninit<u8>; 20]>
Unexecuted instantiation: rustix::fs::at::readlinkat_raw::<&core::ffi::c_str::CStr, std::os::fd::owned::BorrowedFd, &mut [core::mem::maybe_uninit::MaybeUninit<u8>]>
194
195
/// `mkdirat(fd, path, mode)`—Creates a directory.
196
///
197
/// # References
198
///  - [POSIX]
199
///  - [Linux]
200
///
201
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/mkdirat.html
202
/// [Linux]: https://man7.org/linux/man-pages/man2/mkdirat.2.html
203
#[cfg(not(target_os = "redox"))]
204
#[inline]
205
374k
pub fn mkdirat<P: path::Arg, Fd: AsFd>(dirfd: Fd, path: P, mode: Mode) -> io::Result<()> {
206
374k
    path.into_with_c_str(|path| backend::fs::syscalls::mkdirat(dirfd.as_fd(), path, mode))
rustix::fs::at::mkdirat::<&std::path::Path, &std::fs::File>::{closure#0}
Line
Count
Source
206
373k
    path.into_with_c_str(|path| backend::fs::syscalls::mkdirat(dirfd.as_fd(), path, mode))
Unexecuted instantiation: rustix::fs::at::mkdirat::<_, _>::{closure#0}
207
374k
}
rustix::fs::at::mkdirat::<&std::path::Path, &std::fs::File>
Line
Count
Source
205
374k
pub fn mkdirat<P: path::Arg, Fd: AsFd>(dirfd: Fd, path: P, mode: Mode) -> io::Result<()> {
206
374k
    path.into_with_c_str(|path| backend::fs::syscalls::mkdirat(dirfd.as_fd(), path, mode))
207
374k
}
Unexecuted instantiation: rustix::fs::at::mkdirat::<_, _>
208
209
/// `linkat(old_dirfd, old_path, new_dirfd, new_path, flags)`—Creates a hard
210
/// link.
211
///
212
/// # References
213
///  - [POSIX]
214
///  - [Linux]
215
///
216
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/linkat.html
217
/// [Linux]: https://man7.org/linux/man-pages/man2/linkat.2.html
218
#[cfg(not(any(target_os = "espidf", target_os = "redox")))]
219
#[inline]
220
0
pub fn linkat<P: path::Arg, Q: path::Arg, PFd: AsFd, QFd: AsFd>(
221
0
    old_dirfd: PFd,
222
0
    old_path: P,
223
0
    new_dirfd: QFd,
224
0
    new_path: Q,
225
0
    flags: AtFlags,
226
0
) -> io::Result<()> {
227
0
    old_path.into_with_c_str(|old_path| {
228
0
        new_path.into_with_c_str(|new_path| {
229
0
            backend::fs::syscalls::linkat(
230
0
                old_dirfd.as_fd(),
231
0
                old_path,
232
0
                new_dirfd.as_fd(),
233
0
                new_path,
234
0
                flags,
235
            )
236
0
        })
Unexecuted instantiation: rustix::fs::at::linkat::<&std::path::Path, &std::path::Path, &std::fs::File, &std::fs::File>::{closure#0}::{closure#0}
Unexecuted instantiation: rustix::fs::at::linkat::<_, _, _, _>::{closure#0}::{closure#0}
237
0
    })
Unexecuted instantiation: rustix::fs::at::linkat::<&std::path::Path, &std::path::Path, &std::fs::File, &std::fs::File>::{closure#0}
Unexecuted instantiation: rustix::fs::at::linkat::<_, _, _, _>::{closure#0}
238
0
}
Unexecuted instantiation: rustix::fs::at::linkat::<&std::path::Path, &std::path::Path, &std::fs::File, &std::fs::File>
Unexecuted instantiation: rustix::fs::at::linkat::<_, _, _, _>
239
240
/// `unlinkat(fd, path, flags)`—Unlinks a file or remove a directory.
241
///
242
/// With the [`REMOVEDIR`] flag, this removes a directory. This is in place of
243
/// a `rmdirat` function.
244
///
245
/// # References
246
///  - [POSIX]
247
///  - [Linux]
248
///
249
/// [`REMOVEDIR`]: AtFlags::REMOVEDIR
250
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/unlinkat.html
251
/// [Linux]: https://man7.org/linux/man-pages/man2/unlinkat.2.html
252
#[cfg(not(any(target_os = "espidf", target_os = "redox")))]
253
#[inline]
254
0
pub fn unlinkat<P: path::Arg, Fd: AsFd>(dirfd: Fd, path: P, flags: AtFlags) -> io::Result<()> {
255
0
    path.into_with_c_str(|path| backend::fs::syscalls::unlinkat(dirfd.as_fd(), path, flags))
Unexecuted instantiation: rustix::fs::at::unlinkat::<&std::path::Path, &std::fs::File>::{closure#0}
Unexecuted instantiation: rustix::fs::at::unlinkat::<_, _>::{closure#0}
256
0
}
Unexecuted instantiation: rustix::fs::at::unlinkat::<&std::path::Path, &std::fs::File>
Unexecuted instantiation: rustix::fs::at::unlinkat::<_, _>
257
258
/// `renameat(old_dirfd, old_path, new_dirfd, new_path)`—Renames a file or
259
/// directory.
260
///
261
/// See [`renameat_with`] to pass additional flags.
262
///
263
/// # References
264
///  - [POSIX]
265
///  - [Linux]
266
///
267
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/renameat.html
268
/// [Linux]: https://man7.org/linux/man-pages/man2/renameat.2.html
269
#[inline]
270
0
pub fn renameat<P: path::Arg, Q: path::Arg, PFd: AsFd, QFd: AsFd>(
271
0
    old_dirfd: PFd,
272
0
    old_path: P,
273
0
    new_dirfd: QFd,
274
0
    new_path: Q,
275
0
) -> io::Result<()> {
276
0
    old_path.into_with_c_str(|old_path| {
277
0
        new_path.into_with_c_str(|new_path| {
278
0
            backend::fs::syscalls::renameat(
279
0
                old_dirfd.as_fd(),
280
0
                old_path,
281
0
                new_dirfd.as_fd(),
282
0
                new_path,
283
            )
284
0
        })
Unexecuted instantiation: rustix::fs::at::renameat::<&std::path::Path, &std::path::Path, &std::fs::File, &std::fs::File>::{closure#0}::{closure#0}
Unexecuted instantiation: rustix::fs::at::renameat::<&core::ffi::c_str::CStr, &core::ffi::c_str::CStr, std::os::fd::owned::BorrowedFd, std::os::fd::owned::BorrowedFd>::{closure#0}::{closure#0}
Unexecuted instantiation: rustix::fs::at::renameat::<_, _, _, _>::{closure#0}::{closure#0}
285
0
    })
Unexecuted instantiation: rustix::fs::at::renameat::<&std::path::Path, &std::path::Path, &std::fs::File, &std::fs::File>::{closure#0}
Unexecuted instantiation: rustix::fs::at::renameat::<&core::ffi::c_str::CStr, &core::ffi::c_str::CStr, std::os::fd::owned::BorrowedFd, std::os::fd::owned::BorrowedFd>::{closure#0}
Unexecuted instantiation: rustix::fs::at::renameat::<_, _, _, _>::{closure#0}
286
0
}
Unexecuted instantiation: rustix::fs::at::renameat::<&std::path::Path, &std::path::Path, &std::fs::File, &std::fs::File>
Unexecuted instantiation: rustix::fs::at::renameat::<&core::ffi::c_str::CStr, &core::ffi::c_str::CStr, std::os::fd::owned::BorrowedFd, std::os::fd::owned::BorrowedFd>
Unexecuted instantiation: rustix::fs::at::renameat::<_, _, _, _>
287
288
/// `renameat2(old_dirfd, old_path, new_dirfd, new_path, flags)`—Renames a
289
/// file or directory.
290
///
291
/// `renameat_with` is the same as [`renameat`] but adds an additional
292
/// flags operand.
293
///
294
/// # References
295
///  - [Linux]
296
///
297
/// [Linux]: https://man7.org/linux/man-pages/man2/renameat2.2.html
298
#[cfg(any(apple, linux_kernel, target_os = "redox"))]
299
#[inline]
300
#[doc(alias = "renameat2")]
301
#[doc(alias = "renameatx_np")]
302
0
pub fn renameat_with<P: path::Arg, Q: path::Arg, PFd: AsFd, QFd: AsFd>(
303
0
    old_dirfd: PFd,
304
0
    old_path: P,
305
0
    new_dirfd: QFd,
306
0
    new_path: Q,
307
0
    flags: RenameFlags,
308
0
) -> io::Result<()> {
309
0
    old_path.into_with_c_str(|old_path| {
310
0
        new_path.into_with_c_str(|new_path| {
311
0
            backend::fs::syscalls::renameat2(
312
0
                old_dirfd.as_fd(),
313
0
                old_path,
314
0
                new_dirfd.as_fd(),
315
0
                new_path,
316
0
                flags,
317
            )
318
0
        })
Unexecuted instantiation: rustix::fs::at::renameat_with::<&std::path::Path, &std::path::Path, std::os::fd::owned::BorrowedFd, std::os::fd::owned::BorrowedFd>::{closure#0}::{closure#0}
Unexecuted instantiation: rustix::fs::at::renameat_with::<_, _, _, _>::{closure#0}::{closure#0}
319
0
    })
Unexecuted instantiation: rustix::fs::at::renameat_with::<&std::path::Path, &std::path::Path, std::os::fd::owned::BorrowedFd, std::os::fd::owned::BorrowedFd>::{closure#0}
Unexecuted instantiation: rustix::fs::at::renameat_with::<_, _, _, _>::{closure#0}
320
0
}
Unexecuted instantiation: rustix::fs::at::renameat_with::<&std::path::Path, &std::path::Path, std::os::fd::owned::BorrowedFd, std::os::fd::owned::BorrowedFd>
Unexecuted instantiation: rustix::fs::at::renameat_with::<_, _, _, _>
321
322
/// `symlinkat(old_path, new_dirfd, new_path)`—Creates a symlink.
323
///
324
/// # References
325
///  - [POSIX]
326
///  - [Linux]
327
///
328
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/symlinkat.html
329
/// [Linux]: https://man7.org/linux/man-pages/man2/symlinkat.2.html
330
#[cfg(not(target_os = "redox"))]
331
#[inline]
332
0
pub fn symlinkat<P: path::Arg, Q: path::Arg, Fd: AsFd>(
333
0
    old_path: P,
334
0
    new_dirfd: Fd,
335
0
    new_path: Q,
336
0
) -> io::Result<()> {
337
0
    old_path.into_with_c_str(|old_path| {
338
0
        new_path.into_with_c_str(|new_path| {
339
0
            backend::fs::syscalls::symlinkat(old_path, new_dirfd.as_fd(), new_path)
340
0
        })
Unexecuted instantiation: rustix::fs::at::symlinkat::<&std::path::Path, &std::path::Path, &std::fs::File>::{closure#0}::{closure#0}
Unexecuted instantiation: rustix::fs::at::symlinkat::<_, _, _>::{closure#0}::{closure#0}
341
0
    })
Unexecuted instantiation: rustix::fs::at::symlinkat::<&std::path::Path, &std::path::Path, &std::fs::File>::{closure#0}
Unexecuted instantiation: rustix::fs::at::symlinkat::<_, _, _>::{closure#0}
342
0
}
Unexecuted instantiation: rustix::fs::at::symlinkat::<&std::path::Path, &std::path::Path, &std::fs::File>
Unexecuted instantiation: rustix::fs::at::symlinkat::<_, _, _>
343
344
/// `fstatat(dirfd, path, flags)`—Queries metadata for a file or directory.
345
///
346
/// [`Mode::from_raw_mode`] and [`FileType::from_raw_mode`] may be used to
347
/// interpret the `st_mode` field.
348
///
349
/// # References
350
///  - [POSIX]
351
///  - [Linux]
352
///
353
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/fstatat.html
354
/// [Linux]: https://man7.org/linux/man-pages/man2/fstatat.2.html
355
/// [`Mode::from_raw_mode`]: crate::fs::Mode::from_raw_mode
356
/// [`FileType::from_raw_mode`]: crate::fs::FileType::from_raw_mode
357
#[cfg(not(any(target_os = "espidf", target_os = "redox")))]
358
#[inline]
359
#[doc(alias = "fstatat")]
360
0
pub fn statat<P: path::Arg, Fd: AsFd>(dirfd: Fd, path: P, flags: AtFlags) -> io::Result<Stat> {
361
0
    path.into_with_c_str(|path| backend::fs::syscalls::statat(dirfd.as_fd(), path, flags))
Unexecuted instantiation: rustix::fs::at::statat::<&std::path::Path, &std::fs::File>::{closure#0}
Unexecuted instantiation: rustix::fs::at::statat::<&str, &std::fs::File>::{closure#0}
Unexecuted instantiation: rustix::fs::at::statat::<_, _>::{closure#0}
362
0
}
Unexecuted instantiation: rustix::fs::at::statat::<&std::path::Path, &std::fs::File>
Unexecuted instantiation: rustix::fs::at::statat::<&str, &std::fs::File>
Unexecuted instantiation: rustix::fs::at::statat::<_, _>
363
364
/// `faccessat(dirfd, path, access, flags)`—Tests permissions for a file or
365
/// directory.
366
///
367
/// On Linux before 5.8, this function uses the `faccessat` system call which
368
/// doesn't support any flags. This function emulates support for the
369
/// [`AtFlags::EACCESS`] flag by checking whether the uid and gid of the
370
/// process match the effective uid and gid, in which case the `EACCESS` flag
371
/// can be ignored. In Linux 5.8 and beyond `faccessat2` is used, which
372
/// supports flags.
373
///
374
/// # References
375
///  - [POSIX]
376
///  - [Linux]
377
///
378
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/faccessat.html
379
/// [Linux]: https://man7.org/linux/man-pages/man2/faccessat.2.html
380
#[cfg(not(any(
381
    target_os = "espidf",
382
    target_os = "horizon",
383
    target_os = "vita",
384
    target_os = "redox"
385
)))]
386
#[inline]
387
#[doc(alias = "faccessat")]
388
0
pub fn accessat<P: path::Arg, Fd: AsFd>(
389
0
    dirfd: Fd,
390
0
    path: P,
391
0
    access: Access,
392
0
    flags: AtFlags,
393
0
) -> io::Result<()> {
394
0
    path.into_with_c_str(|path| backend::fs::syscalls::accessat(dirfd.as_fd(), path, access, flags))
Unexecuted instantiation: rustix::fs::at::accessat::<&std::path::Path, &std::fs::File>::{closure#0}
Unexecuted instantiation: rustix::fs::at::accessat::<&std::ffi::os_str::OsStr, &std::fs::File>::{closure#0}
Unexecuted instantiation: rustix::fs::at::accessat::<_, _>::{closure#0}
395
0
}
Unexecuted instantiation: rustix::fs::at::accessat::<&std::path::Path, &std::fs::File>
Unexecuted instantiation: rustix::fs::at::accessat::<&std::ffi::os_str::OsStr, &std::fs::File>
Unexecuted instantiation: rustix::fs::at::accessat::<_, _>
396
397
/// `utimensat(dirfd, path, times, flags)`—Sets file or directory timestamps.
398
///
399
/// # References
400
///  - [POSIX]
401
///  - [Linux]
402
///
403
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/utimensat.html
404
/// [Linux]: https://man7.org/linux/man-pages/man2/utimensat.2.html
405
#[cfg(not(any(
406
    target_os = "espidf",
407
    target_os = "horizon",
408
    target_os = "vita",
409
    target_os = "redox"
410
)))]
411
#[inline]
412
0
pub fn utimensat<P: path::Arg, Fd: AsFd>(
413
0
    dirfd: Fd,
414
0
    path: P,
415
0
    times: &Timestamps,
416
0
    flags: AtFlags,
417
0
) -> io::Result<()> {
418
0
    path.into_with_c_str(|path| backend::fs::syscalls::utimensat(dirfd.as_fd(), path, times, flags))
Unexecuted instantiation: rustix::fs::at::utimensat::<&std::path::Path, &std::fs::File>::{closure#0}
Unexecuted instantiation: rustix::fs::at::utimensat::<&std::path::Path, std::os::fd::owned::BorrowedFd>::{closure#0}
Unexecuted instantiation: rustix::fs::at::utimensat::<_, _>::{closure#0}
419
0
}
Unexecuted instantiation: rustix::fs::at::utimensat::<&std::path::Path, &std::fs::File>
Unexecuted instantiation: rustix::fs::at::utimensat::<&std::path::Path, std::os::fd::owned::BorrowedFd>
Unexecuted instantiation: rustix::fs::at::utimensat::<_, _>
420
421
/// `fchmodat(dirfd, path, mode, flags)`—Sets file or directory permissions.
422
///
423
/// Platform support for flags varies widely, for example on Linux
424
/// [`AtFlags::SYMLINK_NOFOLLOW`] is not implemented and therefore
425
/// [`io::Errno::OPNOTSUPP`] will be returned.
426
///
427
/// # References
428
///  - [POSIX]
429
///  - [Linux]
430
///
431
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/fchmodat.html
432
/// [Linux]: https://man7.org/linux/man-pages/man2/fchmodat.2.html
433
#[cfg(not(any(target_os = "espidf", target_os = "wasi", target_os = "redox")))]
434
#[inline]
435
#[doc(alias = "fchmodat")]
436
0
pub fn chmodat<P: path::Arg, Fd: AsFd>(
437
0
    dirfd: Fd,
438
0
    path: P,
439
0
    mode: Mode,
440
0
    flags: AtFlags,
441
0
) -> io::Result<()> {
442
0
    path.into_with_c_str(|path| backend::fs::syscalls::chmodat(dirfd.as_fd(), path, mode, flags))
Unexecuted instantiation: rustix::fs::at::chmodat::<rustix::path::dec_int::DecInt, std::os::fd::owned::BorrowedFd>::{closure#0}
Unexecuted instantiation: rustix::fs::at::chmodat::<&std::path::Path, &std::fs::File>::{closure#0}
Unexecuted instantiation: rustix::fs::at::chmodat::<_, _>::{closure#0}
443
0
}
Unexecuted instantiation: rustix::fs::at::chmodat::<rustix::path::dec_int::DecInt, std::os::fd::owned::BorrowedFd>
Unexecuted instantiation: rustix::fs::at::chmodat::<&std::path::Path, &std::fs::File>
Unexecuted instantiation: rustix::fs::at::chmodat::<_, _>
444
445
/// `fclonefileat(src, dst_dir, dst, flags)`—Efficiently copies between files.
446
///
447
/// # References
448
///  - [Apple]
449
///
450
/// [Apple]: https://github.com/apple-oss-distributions/xnu/blob/main/bsd/man/man2/clonefile.2
451
#[cfg(apple)]
452
#[inline]
453
pub fn fclonefileat<Fd: AsFd, DstFd: AsFd, P: path::Arg>(
454
    src: Fd,
455
    dst_dir: DstFd,
456
    dst: P,
457
    flags: CloneFlags,
458
) -> io::Result<()> {
459
    dst.into_with_c_str(|dst| {
460
        backend::fs::syscalls::fclonefileat(src.as_fd(), dst_dir.as_fd(), dst, flags)
461
    })
462
}
463
464
/// `mknodat(dirfd, path, mode, dev)`—Creates special or normal files.
465
///
466
/// # References
467
///  - [POSIX]
468
///  - [Linux]
469
///  - [FreeBSD]
470
///
471
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/mknodat.html
472
/// [Linux]: https://man7.org/linux/man-pages/man2/mknodat.2.html
473
/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=mknodat&sektion=2
474
#[cfg(not(any(
475
    apple,
476
    target_os = "espidf",
477
    target_os = "horizon",
478
    target_os = "vita",
479
    target_os = "wasi",
480
    target_os = "redox",
481
)))]
482
#[inline]
483
0
pub fn mknodat<P: path::Arg, Fd: AsFd>(
484
0
    dirfd: Fd,
485
0
    path: P,
486
0
    file_type: FileType,
487
0
    mode: Mode,
488
0
    dev: Dev,
489
0
) -> io::Result<()> {
490
0
    path.into_with_c_str(|path| {
491
0
        backend::fs::syscalls::mknodat(dirfd.as_fd(), path, file_type, mode, dev)
492
0
    })
493
0
}
494
495
/// `mkfifoat(dirfd, path, mode)`—Make a FIFO special file.
496
///
497
/// # References
498
///  - [POSIX]
499
///  - [Linux]
500
///  - [FreeBSD]
501
///
502
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/mkfifoat.html
503
/// [Linux]: https://www.man7.org/linux/man-pages/man3/mkfifo.3.html
504
/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=mkfifoat&sektion=2
505
#[cfg(not(any(
506
    apple,
507
    target_os = "espidf",
508
    target_os = "horizon",
509
    target_os = "vita",
510
    target_os = "wasi",
511
    target_os = "redox",
512
)))]
513
#[inline]
514
0
pub fn mkfifoat<P: path::Arg, Fd: AsFd>(dirfd: Fd, path: P, mode: Mode) -> io::Result<()> {
515
0
    mknodat(dirfd, path, FileType::Fifo, mode, 0)
516
0
}
517
518
/// `fchownat(dirfd, path, owner, group, flags)`—Sets file or directory
519
/// ownership.
520
///
521
/// # References
522
///  - [POSIX]
523
///  - [Linux]
524
///
525
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/fchownat.html
526
/// [Linux]: https://man7.org/linux/man-pages/man2/fchownat.2.html
527
#[cfg(not(any(target_os = "espidf", target_os = "wasi", target_os = "redox")))]
528
#[inline]
529
#[doc(alias = "fchownat")]
530
0
pub fn chownat<P: path::Arg, Fd: AsFd>(
531
0
    dirfd: Fd,
532
0
    path: P,
533
0
    owner: Option<Uid>,
534
0
    group: Option<Gid>,
535
0
    flags: AtFlags,
536
0
) -> io::Result<()> {
537
0
    path.into_with_c_str(|path| {
538
0
        backend::fs::syscalls::chownat(dirfd.as_fd(), path, owner, group, flags)
539
0
    })
540
0
}