Coverage Report

Created: 2024-08-22 06:13

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