Coverage Report

Created: 2025-07-18 06:03

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