Coverage Report

Created: 2025-09-27 06:48

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/rustix-1.1.2/src/fs/abs.rs
Line
Count
Source
1
//! POSIX-style filesystem functions which operate on bare paths.
2
3
use crate::fd::OwnedFd;
4
#[cfg(not(any(target_os = "espidf", target_os = "horizon", target_os = "vita")))]
5
use crate::fs::Access;
6
#[cfg(not(any(
7
    solarish,
8
    target_os = "espidf",
9
    target_os = "haiku",
10
    target_os = "horizon",
11
    target_os = "netbsd",
12
    target_os = "nto",
13
    target_os = "redox",
14
    target_os = "vita",
15
    target_os = "wasi",
16
)))]
17
use crate::fs::StatFs;
18
#[cfg(not(any(target_os = "haiku", target_os = "wasi")))]
19
use crate::fs::StatVfs;
20
use crate::fs::{Mode, OFlags, Stat};
21
#[cfg(not(target_os = "wasi"))]
22
use crate::ugid::{Gid, Uid};
23
use crate::{backend, io, path};
24
#[cfg(feature = "alloc")]
25
use {
26
    crate::ffi::{CStr, CString},
27
    crate::path::SMALL_PATH_BUFFER_SIZE,
28
    alloc::vec::Vec,
29
};
30
31
/// `open(path, oflags, mode)`—Opens a file.
32
///
33
/// POSIX guarantees that `open` will use the lowest unused file descriptor,
34
/// however it is not safe in general to rely on this, as file descriptors may
35
/// be unexpectedly allocated on other threads or in libraries.
36
///
37
/// The `Mode` argument is only significant when creating a file.
38
///
39
/// # References
40
///  - [POSIX]
41
///  - [Linux]
42
///
43
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/open.html
44
/// [Linux]: https://man7.org/linux/man-pages/man2/open.2.html
45
#[inline]
46
0
pub fn open<P: path::Arg>(path: P, flags: OFlags, mode: Mode) -> io::Result<OwnedFd> {
47
0
    path.into_with_c_str(|path| backend::fs::syscalls::open(path, flags, mode))
48
0
}
49
50
/// `chmod(path, mode)`—Sets file or directory permissions.
51
///
52
/// # References
53
///  - [POSIX]
54
///  - [Linux]
55
///
56
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/chmod.html
57
/// [Linux]: https://man7.org/linux/man-pages/man2/chmod.2.html
58
#[cfg(not(target_os = "wasi"))]
59
#[inline]
60
0
pub fn chmod<P: path::Arg>(path: P, mode: Mode) -> io::Result<()> {
61
0
    path.into_with_c_str(|path| backend::fs::syscalls::chmod(path, mode))
62
0
}
63
64
/// `stat(path)`—Queries metadata for a file or directory.
65
///
66
/// [`Mode::from_raw_mode`] and [`FileType::from_raw_mode`] may be used to
67
/// interpret the `st_mode` field.
68
///
69
/// # References
70
///  - [POSIX]
71
///  - [Linux]
72
///
73
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/stat.html
74
/// [Linux]: https://man7.org/linux/man-pages/man2/stat.2.html
75
/// [`Mode::from_raw_mode`]: crate::fs::Mode::from_raw_mode
76
/// [`FileType::from_raw_mode`]: crate::fs::FileType::from_raw_mode
77
#[inline]
78
0
pub fn stat<P: path::Arg>(path: P) -> io::Result<Stat> {
79
0
    path.into_with_c_str(backend::fs::syscalls::stat)
80
0
}
81
82
/// `lstat(path)`—Queries metadata for a file or directory, without following
83
/// symlinks.
84
///
85
/// [`Mode::from_raw_mode`] and [`FileType::from_raw_mode`] may be used to
86
/// interpret the `st_mode` field.
87
///
88
/// # References
89
///  - [POSIX]
90
///  - [Linux]
91
///
92
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/lstat.html
93
/// [Linux]: https://man7.org/linux/man-pages/man2/lstat.2.html
94
/// [`Mode::from_raw_mode`]: crate::fs::Mode::from_raw_mode
95
/// [`FileType::from_raw_mode`]: crate::fs::FileType::from_raw_mode
96
#[inline]
97
0
pub fn lstat<P: path::Arg>(path: P) -> io::Result<Stat> {
98
0
    path.into_with_c_str(backend::fs::syscalls::lstat)
99
0
}
Unexecuted instantiation: rustix::fs::abs::lstat::<_>
Unexecuted instantiation: rustix::fs::abs::lstat::<&std::path::Path>
100
101
/// `readlink(path)`—Reads the contents of a symlink.
102
///
103
/// If `reuse` is non-empty, reuse its buffer to store the result if possible.
104
///
105
/// # References
106
///  - [POSIX]
107
///  - [Linux]
108
///
109
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/readlink.html
110
/// [Linux]: https://man7.org/linux/man-pages/man2/readlink.2.html
111
#[cfg(feature = "alloc")]
112
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
113
#[inline]
114
0
pub fn readlink<P: path::Arg, B: Into<Vec<u8>>>(path: P, reuse: B) -> io::Result<CString> {
115
0
    path.into_with_c_str(|path| _readlink(path, reuse.into()))
116
0
}
117
118
#[cfg(feature = "alloc")]
119
0
fn _readlink(path: &CStr, mut buffer: Vec<u8>) -> io::Result<CString> {
120
    // This code would benefit from having a better way to read into
121
    // uninitialized memory, but that requires `unsafe`.
122
0
    buffer.clear();
123
0
    buffer.reserve(SMALL_PATH_BUFFER_SIZE);
124
0
    buffer.resize(buffer.capacity(), 0_u8);
125
126
    loop {
127
0
        let nread = backend::fs::syscalls::readlink(path, &mut buffer)?;
128
129
0
        let nread = nread as usize;
130
0
        assert!(nread <= buffer.len());
131
0
        if nread < buffer.len() {
132
0
            buffer.resize(nread, 0_u8);
133
0
            return Ok(CString::new(buffer).unwrap());
134
0
        }
135
        // Use `Vec` reallocation strategy to grow capacity exponentially.
136
0
        buffer.reserve(1);
137
0
        buffer.resize(buffer.capacity(), 0_u8);
138
    }
139
0
}
140
141
/// `rename(old_path, new_path)`—Renames a file or directory.
142
///
143
/// # References
144
///  - [POSIX]
145
///  - [Linux]
146
///
147
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/rename.html
148
/// [Linux]: https://man7.org/linux/man-pages/man2/rename.2.html
149
#[inline]
150
0
pub fn rename<P: path::Arg, Q: path::Arg>(old_path: P, new_path: Q) -> io::Result<()> {
151
0
    old_path.into_with_c_str(|old_path| {
152
0
        new_path.into_with_c_str(|new_path| backend::fs::syscalls::rename(old_path, new_path))
Unexecuted instantiation: rustix::fs::abs::rename::<&std::path::Path, &std::path::Path>::{closure#0}::{closure#0}
Unexecuted instantiation: rustix::fs::abs::rename::<_, _>::{closure#0}::{closure#0}
153
0
    })
Unexecuted instantiation: rustix::fs::abs::rename::<&std::path::Path, &std::path::Path>::{closure#0}
Unexecuted instantiation: rustix::fs::abs::rename::<_, _>::{closure#0}
154
0
}
Unexecuted instantiation: rustix::fs::abs::rename::<&std::path::Path, &std::path::Path>
Unexecuted instantiation: rustix::fs::abs::rename::<_, _>
155
156
/// `unlink(path)`—Unlinks a file.
157
///
158
/// # References
159
///  - [POSIX]
160
///  - [Linux]
161
///
162
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/unlink.html
163
/// [Linux]: https://man7.org/linux/man-pages/man2/unlink.2.html
164
#[inline]
165
0
pub fn unlink<P: path::Arg>(path: P) -> io::Result<()> {
166
0
    path.into_with_c_str(backend::fs::syscalls::unlink)
167
0
}
Unexecuted instantiation: rustix::fs::abs::unlink::<&std::path::Path>
Unexecuted instantiation: rustix::fs::abs::unlink::<_>
168
169
/// `rmdir(path)`—Removes a directory.
170
///
171
/// # References
172
///  - [POSIX]
173
///  - [Linux]
174
///
175
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/rmdir.html
176
/// [Linux]: https://man7.org/linux/man-pages/man2/rmdir.2.html
177
#[inline]
178
0
pub fn rmdir<P: path::Arg>(path: P) -> io::Result<()> {
179
0
    path.into_with_c_str(backend::fs::syscalls::rmdir)
180
0
}
181
182
/// `link(old_path, new_path)`—Creates a hard link.
183
///
184
/// POSIX leaves it implementation-defined whether `link` follows a symlink in
185
/// `old_path`, or creates a new link to the symbolic link itself. On platforms
186
/// which have it, [`linkat`] avoids this problem since it has an [`AtFlags`]
187
/// parameter and the [`AtFlags::SYMLINK_FOLLOW`] flag determines whether
188
/// symlinks should be followed.
189
///
190
/// # References
191
///  - [POSIX]
192
///  - [Linux]
193
///
194
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/link.html
195
/// [Linux]: https://man7.org/linux/man-pages/man2/link.2.html
196
/// [`linkat`]: crate::fs::linkat
197
/// [`AtFlags`]: crate::fs::AtFlags
198
/// [`AtFlags::SYMLINK_FOLLOW`]: crate::fs::AtFlags::SYMLINK_FOLLOW
199
#[inline]
200
0
pub fn link<P: path::Arg, Q: path::Arg>(old_path: P, new_path: Q) -> io::Result<()> {
201
0
    old_path.into_with_c_str(|old_path| {
202
0
        new_path.into_with_c_str(|new_path| backend::fs::syscalls::link(old_path, new_path))
203
0
    })
204
0
}
205
206
/// `symlink(old_path, new_path)`—Creates a symlink.
207
///
208
/// # References
209
///  - [POSIX]
210
///  - [Linux]
211
///
212
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/symlink.html
213
/// [Linux]: https://man7.org/linux/man-pages/man2/symlink.2.html
214
#[inline]
215
0
pub fn symlink<P: path::Arg, Q: path::Arg>(old_path: P, new_path: Q) -> io::Result<()> {
216
0
    old_path.into_with_c_str(|old_path| {
217
0
        new_path.into_with_c_str(|new_path| backend::fs::syscalls::symlink(old_path, new_path))
218
0
    })
219
0
}
220
221
/// `mkdir(path, mode)`—Creates a directory.
222
///
223
/// # References
224
///  - [POSIX]
225
///  - [Linux]
226
///
227
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/mkdir.html
228
/// [Linux]: https://man7.org/linux/man-pages/man2/mkdir.2.html
229
#[inline]
230
0
pub fn mkdir<P: path::Arg>(path: P, mode: Mode) -> io::Result<()> {
231
0
    path.into_with_c_str(|path| backend::fs::syscalls::mkdir(path, mode))
232
0
}
233
234
/// `access(path, access)`—Tests permissions for a file or directory.
235
///
236
/// # References
237
///  - [POSIX]
238
///  - [Linux]
239
///
240
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/access.html
241
/// [Linux]: https://man7.org/linux/man-pages/man2/access.2.html
242
#[cfg(not(any(target_os = "espidf", target_os = "horizon", target_os = "vita")))]
243
#[inline]
244
0
pub fn access<P: path::Arg>(path: P, access: Access) -> io::Result<()> {
245
0
    path.into_with_c_str(|path| backend::fs::syscalls::access(path, access))
246
0
}
247
248
/// `statfs`—Queries filesystem metadata.
249
///
250
/// Compared to [`statvfs`], this function often provides more information,
251
/// though it's less portable.
252
///
253
/// # References
254
///  - [Linux]
255
///
256
/// [Linux]: https://man7.org/linux/man-pages/man2/statfs.2.html
257
#[cfg(not(any(
258
    solarish,
259
    target_os = "espidf",
260
    target_os = "haiku",
261
    target_os = "horizon",
262
    target_os = "netbsd",
263
    target_os = "nto",
264
    target_os = "redox",
265
    target_os = "vita",
266
    target_os = "wasi",
267
)))]
268
#[inline]
269
0
pub fn statfs<P: path::Arg>(path: P) -> io::Result<StatFs> {
270
0
    path.into_with_c_str(backend::fs::syscalls::statfs)
271
0
}
272
273
/// `statvfs`—Queries filesystem metadata, POSIX version.
274
///
275
/// Compared to [`statfs`], this function often provides less information, but
276
/// it is more portable. But even so, filesystems are very diverse and not all
277
/// the fields are meaningful for every filesystem. And `f_fsid` doesn't seem
278
/// to have a clear meaning anywhere.
279
///
280
/// # References
281
///  - [POSIX]
282
///  - [Linux]
283
///
284
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/statvfs.html
285
/// [Linux]: https://man7.org/linux/man-pages/man2/statvfs.2.html
286
#[cfg(not(any(target_os = "haiku", target_os = "wasi")))]
287
#[inline]
288
0
pub fn statvfs<P: path::Arg>(path: P) -> io::Result<StatVfs> {
289
0
    path.into_with_c_str(backend::fs::syscalls::statvfs)
290
0
}
291
292
/// `chown(path, owner, group)`—Sets open file or directory ownership.
293
///
294
/// # References
295
///  - [POSIX]
296
///  - [Linux]
297
///
298
/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/chown.html
299
/// [Linux]: https://man7.org/linux/man-pages/man2/chown.2.html
300
#[cfg(not(target_os = "wasi"))]
301
#[inline]
302
0
pub fn chown<P: path::Arg>(path: P, owner: Option<Uid>, group: Option<Gid>) -> io::Result<()> {
303
0
    path.into_with_c_str(|path| backend::fs::syscalls::chown(path, owner, group))
304
0
}