Coverage Report

Created: 2026-04-12 06:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/rustix-1.1.4/src/path/arg.rs
Line
Count
Source
1
//! Convenient and efficient string argument passing.
2
//!
3
//! This module defines the `Arg` trait and implements it for several common
4
//! string types. This allows users to pass any of these string types directly
5
//! to rustix APIs with string arguments, and it allows rustix to implement
6
//! NUL-termination without the need for copying or dynamic allocation where
7
//! possible.
8
9
use crate::ffi::CStr;
10
use crate::io;
11
use crate::path::{DecInt, SMALL_PATH_BUFFER_SIZE};
12
#[cfg(feature = "alloc")]
13
use alloc::borrow::ToOwned as _;
14
use core::mem::MaybeUninit;
15
use core::{ptr, slice, str};
16
#[cfg(feature = "std")]
17
use std::ffi::{OsStr, OsString};
18
#[cfg(all(feature = "std", target_os = "hermit"))]
19
use std::os::hermit::ext::ffi::{OsStrExt, OsStringExt};
20
#[cfg(all(feature = "std", unix))]
21
use std::os::unix::ffi::{OsStrExt as _, OsStringExt as _};
22
#[cfg(all(feature = "std", target_os = "vxworks"))]
23
use std::os::vxworks::ext::ffi::{OsStrExt, OsStringExt};
24
#[cfg(all(
25
    feature = "std",
26
    target_os = "wasi",
27
    any(not(target_env = "p2"), wasip2)
28
))]
29
use std::os::wasi::ffi::{OsStrExt, OsStringExt};
30
#[cfg(feature = "std")]
31
use std::path::{Component, Components, Iter, Path, PathBuf};
32
#[cfg(feature = "alloc")]
33
use {crate::ffi::CString, alloc::borrow::Cow};
34
#[cfg(feature = "alloc")]
35
use {alloc::string::String, alloc::vec::Vec};
36
37
/// A trait for passing path arguments.
38
///
39
/// This is similar to [`AsRef`]`<`[`Path`]`>`, but is implemented for more
40
/// kinds of strings and can convert into more kinds of strings.
41
///
42
/// # Examples
43
///
44
/// ```
45
/// # #[cfg(any(feature = "fs", feature = "net"))]
46
/// use rustix::ffi::CStr;
47
/// use rustix::io;
48
/// # #[cfg(any(feature = "fs", feature = "net"))]
49
/// use rustix::path::Arg;
50
///
51
/// # #[cfg(any(feature = "fs", feature = "net"))]
52
/// pub fn touch<P: Arg>(path: P) -> io::Result<()> {
53
///     let path = path.into_c_str()?;
54
///     _touch(&path)
55
/// }
56
///
57
/// # #[cfg(any(feature = "fs", feature = "net"))]
58
/// fn _touch(path: &CStr) -> io::Result<()> {
59
///     // implementation goes here
60
///     Ok(())
61
/// }
62
/// ```
63
///
64
/// Users can then call `touch("foo")`, `touch(cstr!("foo"))`,
65
/// `touch(Path::new("foo"))`, or many other things.
66
///
67
/// [`AsRef`]: std::convert::AsRef
68
pub trait Arg {
69
    /// Returns a view of this string as a string slice.
70
    fn as_str(&self) -> io::Result<&str>;
71
72
    /// Returns a potentially-lossy rendering of this string as a
73
    /// `Cow<'_, str>`.
74
    #[cfg(feature = "alloc")]
75
    fn to_string_lossy(&self) -> Cow<'_, str>;
76
77
    /// Returns a view of this string as a maybe-owned [`CStr`].
78
    #[cfg(feature = "alloc")]
79
    fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>>;
80
81
    /// Consumes `self` and returns a view of this string as a maybe-owned
82
    /// [`CStr`].
83
    #[cfg(feature = "alloc")]
84
    fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
85
    where
86
        Self: 'b;
87
88
    /// Runs a closure with `self` passed in as a `&CStr`.
89
    fn into_with_c_str<T, F>(self, f: F) -> io::Result<T>
90
    where
91
        Self: Sized,
92
        F: FnOnce(&CStr) -> io::Result<T>;
93
}
94
95
/// Runs a closure on `arg` where `A` is mapped to a `&CStr`
96
0
pub fn option_into_with_c_str<T, F, A>(arg: Option<A>, f: F) -> io::Result<T>
97
0
where
98
0
    A: Arg + Sized,
99
0
    F: FnOnce(Option<&CStr>) -> io::Result<T>,
100
{
101
0
    if let Some(arg) = arg {
102
0
        arg.into_with_c_str(|p| f(Some(p)))
103
    } else {
104
0
        f(None)
105
    }
106
0
}
107
108
impl Arg for &str {
109
    #[inline]
110
0
    fn as_str(&self) -> io::Result<&str> {
111
0
        Ok(self)
112
0
    }
113
114
    #[cfg(feature = "alloc")]
115
    #[inline]
116
0
    fn to_string_lossy(&self) -> Cow<'_, str> {
117
0
        Cow::Borrowed(self)
118
0
    }
119
120
    #[cfg(feature = "alloc")]
121
    #[inline]
122
0
    fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> {
123
        Ok(Cow::Owned(
124
0
            CString::new(*self).map_err(|_cstr_err| io::Errno::INVAL)?,
125
        ))
126
0
    }
127
128
    #[cfg(feature = "alloc")]
129
    #[inline]
130
0
    fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
131
0
    where
132
0
        Self: 'b,
133
    {
134
        Ok(Cow::Owned(
135
0
            CString::new(self).map_err(|_cstr_err| io::Errno::INVAL)?,
136
        ))
137
0
    }
138
139
    #[inline]
140
0
    fn into_with_c_str<T, F>(self, f: F) -> io::Result<T>
141
0
    where
142
0
        Self: Sized,
143
0
        F: FnOnce(&CStr) -> io::Result<T>,
144
    {
145
0
        with_c_str(self.as_bytes(), f)
146
0
    }
Unexecuted instantiation: <&str as rustix::path::arg::Arg>::into_with_c_str::<rustix::fs::statx::Statx, rustix::fs::statx::statx<&str, std::os::fd::owned::BorrowedFd>::{closure#0}>
Unexecuted instantiation: <&str as rustix::path::arg::Arg>::into_with_c_str::<rustix::backend::fs::types::Stat, rustix::fs::at::statat<&str, &std::fs::File>::{closure#0}>
Unexecuted instantiation: <&str as rustix::path::arg::Arg>::into_with_c_str::<std::os::fd::owned::OwnedFd, rustix::fs::abs::open<&str>::{closure#0}>
147
}
148
149
#[cfg(feature = "alloc")]
150
impl Arg for &String {
151
    #[inline]
152
0
    fn as_str(&self) -> io::Result<&str> {
153
0
        Ok(self)
154
0
    }
155
156
    #[cfg(feature = "alloc")]
157
    #[inline]
158
0
    fn to_string_lossy(&self) -> Cow<'_, str> {
159
0
        Cow::Borrowed(self)
160
0
    }
161
162
    #[cfg(feature = "alloc")]
163
    #[inline]
164
0
    fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> {
165
        Ok(Cow::Owned(
166
0
            CString::new(String::as_str(self)).map_err(|_cstr_err| io::Errno::INVAL)?,
167
        ))
168
0
    }
169
170
    #[cfg(feature = "alloc")]
171
    #[inline]
172
0
    fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
173
0
    where
174
0
        Self: 'b,
175
    {
176
0
        self.as_str().into_c_str()
177
0
    }
178
179
    #[inline]
180
0
    fn into_with_c_str<T, F>(self, f: F) -> io::Result<T>
181
0
    where
182
0
        Self: Sized,
183
0
        F: FnOnce(&CStr) -> io::Result<T>,
184
    {
185
0
        with_c_str(self.as_bytes(), f)
186
0
    }
187
}
188
189
#[cfg(feature = "alloc")]
190
impl Arg for String {
191
    #[inline]
192
0
    fn as_str(&self) -> io::Result<&str> {
193
0
        Ok(self)
194
0
    }
195
196
    #[cfg(feature = "alloc")]
197
    #[inline]
198
0
    fn to_string_lossy(&self) -> Cow<'_, str> {
199
0
        Cow::Borrowed(self)
200
0
    }
201
202
    #[cfg(feature = "alloc")]
203
    #[inline]
204
0
    fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> {
205
        Ok(Cow::Owned(
206
0
            CString::new(self.as_str()).map_err(|_cstr_err| io::Errno::INVAL)?,
207
        ))
208
0
    }
209
210
    #[cfg(feature = "alloc")]
211
    #[inline]
212
0
    fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
213
0
    where
214
0
        Self: 'b,
215
    {
216
        Ok(Cow::Owned(
217
0
            CString::new(self).map_err(|_cstr_err| io::Errno::INVAL)?,
218
        ))
219
0
    }
220
221
    #[inline]
222
0
    fn into_with_c_str<T, F>(self, f: F) -> io::Result<T>
223
0
    where
224
0
        Self: Sized,
225
0
        F: FnOnce(&CStr) -> io::Result<T>,
226
    {
227
0
        f(&CString::new(self).map_err(|_cstr_err| io::Errno::INVAL)?)
228
0
    }
229
}
230
231
#[cfg(feature = "std")]
232
impl Arg for &OsStr {
233
    #[inline]
234
0
    fn as_str(&self) -> io::Result<&str> {
235
0
        self.to_str().ok_or(io::Errno::INVAL)
236
0
    }
237
238
    #[inline]
239
0
    fn to_string_lossy(&self) -> Cow<'_, str> {
240
0
        OsStr::to_string_lossy(self)
241
0
    }
242
243
    #[inline]
244
0
    fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> {
245
0
        self.into_c_str()
246
0
    }
247
248
    #[inline]
249
0
    fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
250
0
    where
251
0
        Self: 'b,
252
    {
253
        #[cfg(all(target_os = "wasi", target_env = "p2", not(wasip2)))]
254
        return self.to_str().ok_or(io::Errno::INVAL)?.into_c_str();
255
        #[cfg(any(wasip2, not(all(target_os = "wasi", target_env = "p2"))))]
256
0
        return self.as_bytes().into_c_str();
257
0
    }
258
259
    #[inline]
260
1.25M
    fn into_with_c_str<T, F>(self, f: F) -> io::Result<T>
261
1.25M
    where
262
1.25M
        Self: Sized,
263
1.25M
        F: FnOnce(&CStr) -> io::Result<T>,
264
    {
265
        #[cfg(all(target_os = "wasi", target_env = "p2", not(wasip2)))]
266
        return self.as_str()?.into_with_c_str(f);
267
268
        #[cfg(any(wasip2, not(all(target_os = "wasi", target_env = "p2"))))]
269
1.25M
        return self.as_bytes().into_with_c_str(f);
270
1.25M
    }
Unexecuted instantiation: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<(), 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: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::abs::rename<&std::path::Path, &std::path::Path>::{closure#0}>
Unexecuted instantiation: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<(), 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: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::abs::rename<&std::path::Path, &std::path::Path>::{closure#0}::{closure#0}>
Unexecuted instantiation: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::backend::fs::syscalls::unlink>
Unexecuted instantiation: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<(&mut [u8], &mut [core::mem::maybe_uninit::MaybeUninit<u8>]), rustix::fs::xattr::llistxattr<&std::path::Path, &mut [core::mem::maybe_uninit::MaybeUninit<u8>]>::{closure#0}>
Unexecuted instantiation: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<(&mut [u8], &mut [core::mem::maybe_uninit::MaybeUninit<u8>]), rustix::fs::xattr::getxattr<&std::path::Path, &std::ffi::os_str::OsStr, &mut [core::mem::maybe_uninit::MaybeUninit<u8>]>::{closure#0}>
Unexecuted instantiation: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<(&mut [u8], &mut [core::mem::maybe_uninit::MaybeUninit<u8>]), rustix::fs::xattr::fgetxattr<std::os::fd::owned::BorrowedFd, &std::ffi::os_str::OsStr, &mut [core::mem::maybe_uninit::MaybeUninit<u8>]>::{closure#0}>
Unexecuted instantiation: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<(&mut [u8], &mut [core::mem::maybe_uninit::MaybeUninit<u8>]), rustix::fs::xattr::lgetxattr<&std::path::Path, &std::ffi::os_str::OsStr, &mut [core::mem::maybe_uninit::MaybeUninit<u8>]>::{closure#0}>
Unexecuted instantiation: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<(&mut [u8], &mut [core::mem::maybe_uninit::MaybeUninit<u8>]), rustix::fs::xattr::listxattr<&std::path::Path, &mut [core::mem::maybe_uninit::MaybeUninit<u8>]>::{closure#0}>
Unexecuted instantiation: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<(&mut [u8], &mut [core::mem::maybe_uninit::MaybeUninit<u8>]), rustix::fs::xattr::getxattr<&std::path::Path, &std::ffi::os_str::OsStr, &mut [core::mem::maybe_uninit::MaybeUninit<u8>]>::{closure#0}::{closure#0}>
Unexecuted instantiation: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<(&mut [u8], &mut [core::mem::maybe_uninit::MaybeUninit<u8>]), rustix::fs::xattr::lgetxattr<&std::path::Path, &std::ffi::os_str::OsStr, &mut [core::mem::maybe_uninit::MaybeUninit<u8>]>::{closure#0}::{closure#0}>
Unexecuted instantiation: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<usize, rustix::fs::xattr::llistxattr<&std::path::Path, &mut [u8]>::{closure#0}>
Unexecuted instantiation: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<usize, rustix::fs::xattr::getxattr<&std::path::Path, &std::ffi::os_str::OsStr, &mut [u8]>::{closure#0}>
Unexecuted instantiation: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<usize, rustix::fs::xattr::fgetxattr<std::os::fd::owned::BorrowedFd, &std::ffi::os_str::OsStr, &mut [u8]>::{closure#0}>
Unexecuted instantiation: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<usize, rustix::fs::xattr::lgetxattr<&std::path::Path, &std::ffi::os_str::OsStr, &mut [u8]>::{closure#0}>
Unexecuted instantiation: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<usize, rustix::fs::xattr::listxattr<&std::path::Path, &mut [u8]>::{closure#0}>
Unexecuted instantiation: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<usize, rustix::fs::xattr::getxattr<&std::path::Path, &std::ffi::os_str::OsStr, &mut [u8]>::{closure#0}::{closure#0}>
Unexecuted instantiation: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<usize, rustix::fs::xattr::lgetxattr<&std::path::Path, &std::ffi::os_str::OsStr, &mut [u8]>::{closure#0}::{closure#0}>
Unexecuted instantiation: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::xattr::removexattr<&std::path::Path, &std::ffi::os_str::OsStr>::{closure#0}>
Unexecuted instantiation: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::xattr::fremovexattr<std::os::fd::owned::BorrowedFd, &std::ffi::os_str::OsStr>::{closure#0}>
Unexecuted instantiation: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::xattr::lremovexattr<&std::path::Path, &std::ffi::os_str::OsStr>::{closure#0}>
Unexecuted instantiation: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::xattr::setxattr<&std::path::Path, &std::ffi::os_str::OsStr>::{closure#0}>
Unexecuted instantiation: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::xattr::fsetxattr<std::os::fd::owned::BorrowedFd, &std::ffi::os_str::OsStr>::{closure#0}>
Unexecuted instantiation: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::xattr::lsetxattr<&std::path::Path, &std::ffi::os_str::OsStr>::{closure#0}>
Unexecuted instantiation: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::xattr::removexattr<&std::path::Path, &std::ffi::os_str::OsStr>::{closure#0}::{closure#0}>
Unexecuted instantiation: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::xattr::lremovexattr<&std::path::Path, &std::ffi::os_str::OsStr>::{closure#0}::{closure#0}>
Unexecuted instantiation: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::xattr::setxattr<&std::path::Path, &std::ffi::os_str::OsStr>::{closure#0}::{closure#0}>
Unexecuted instantiation: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::xattr::lsetxattr<&std::path::Path, &std::ffi::os_str::OsStr>::{closure#0}::{closure#0}>
<&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<std::fs::File, cap_primitives::rustix::linux::fs::open_impl::open_beneath::{closure#0}>
Line
Count
Source
260
877k
    fn into_with_c_str<T, F>(self, f: F) -> io::Result<T>
261
877k
    where
262
877k
        Self: Sized,
263
877k
        F: FnOnce(&CStr) -> io::Result<T>,
264
    {
265
        #[cfg(all(target_os = "wasi", target_env = "p2", not(wasip2)))]
266
        return self.as_str()?.into_with_c_str(f);
267
268
        #[cfg(any(wasip2, not(all(target_os = "wasi", target_env = "p2"))))]
269
877k
        return self.as_bytes().into_with_c_str(f);
270
877k
    }
Unexecuted instantiation: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<rustix::fs::statx::Statx, rustix::fs::statx::statx<&std::path::Path, &std::fs::File>::{closure#0}>
Unexecuted instantiation: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<alloc::ffi::c_str::CString, rustix::fs::at::readlinkat<&std::path::Path, &std::fs::File, alloc::vec::Vec<u8>>::{closure#0}>
Unexecuted instantiation: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<std::os::fd::owned::OwnedFd, rustix::fs::at::openat<&std::path::Path, &std::fs::File>::{closure#0}>
Unexecuted instantiation: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<rustix::backend::fs::types::Stat, rustix::fs::at::statat<&std::path::Path, &std::fs::File>::{closure#0}>
Unexecuted instantiation: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::at::linkat<&std::path::Path, &std::path::Path, &std::fs::File, &std::fs::File>::{closure#0}>
Unexecuted instantiation: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::at::chmodat<&std::path::Path, &std::fs::File>::{closure#0}>
<&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::at::mkdirat<&std::path::Path, &std::fs::File>::{closure#0}>
Line
Count
Source
260
379k
    fn into_with_c_str<T, F>(self, f: F) -> io::Result<T>
261
379k
    where
262
379k
        Self: Sized,
263
379k
        F: FnOnce(&CStr) -> io::Result<T>,
264
    {
265
        #[cfg(all(target_os = "wasi", target_env = "p2", not(wasip2)))]
266
        return self.as_str()?.into_with_c_str(f);
267
268
        #[cfg(any(wasip2, not(all(target_os = "wasi", target_env = "p2"))))]
269
379k
        return self.as_bytes().into_with_c_str(f);
270
379k
    }
Unexecuted instantiation: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::at::accessat<&std::ffi::os_str::OsStr, &std::fs::File>::{closure#0}>
Unexecuted instantiation: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::at::accessat<&std::path::Path, &std::fs::File>::{closure#0}>
Unexecuted instantiation: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::at::renameat<&std::path::Path, &std::path::Path, &std::fs::File, &std::fs::File>::{closure#0}>
Unexecuted instantiation: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::at::unlinkat<&std::path::Path, &std::fs::File>::{closure#0}>
Unexecuted instantiation: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::at::symlinkat<&std::path::Path, &std::path::Path, &std::fs::File>::{closure#0}>
Unexecuted instantiation: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::at::utimensat<&std::path::Path, &std::fs::File>::{closure#0}>
Unexecuted instantiation: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::at::linkat<&std::path::Path, &std::path::Path, &std::fs::File, &std::fs::File>::{closure#0}::{closure#0}>
Unexecuted instantiation: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::at::renameat<&std::path::Path, &std::path::Path, &std::fs::File, &std::fs::File>::{closure#0}::{closure#0}>
Unexecuted instantiation: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::at::symlinkat<&std::path::Path, &std::path::Path, &std::fs::File>::{closure#0}::{closure#0}>
Unexecuted instantiation: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::at::utimensat<&std::path::Path, std::os::fd::owned::BorrowedFd>::{closure#0}>
Unexecuted instantiation: <&std::ffi::os_str::OsStr as rustix::path::arg::Arg>::into_with_c_str::<_, _>
271
}
272
273
#[cfg(feature = "std")]
274
impl Arg for &OsString {
275
    #[inline]
276
0
    fn as_str(&self) -> io::Result<&str> {
277
0
        OsString::as_os_str(self).to_str().ok_or(io::Errno::INVAL)
278
0
    }
279
280
    #[inline]
281
0
    fn to_string_lossy(&self) -> Cow<'_, str> {
282
0
        self.as_os_str().to_string_lossy()
283
0
    }
284
285
    #[inline]
286
0
    fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> {
287
0
        self.as_os_str().into_c_str()
288
0
    }
289
290
    #[inline]
291
0
    fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
292
0
    where
293
0
        Self: 'b,
294
    {
295
0
        self.as_os_str().into_c_str()
296
0
    }
297
298
    #[inline]
299
0
    fn into_with_c_str<T, F>(self, f: F) -> io::Result<T>
300
0
    where
301
0
        Self: Sized,
302
0
        F: FnOnce(&CStr) -> io::Result<T>,
303
    {
304
0
        self.as_os_str().into_with_c_str(f)
305
0
    }
306
}
307
308
#[cfg(feature = "std")]
309
impl Arg for OsString {
310
    #[inline]
311
0
    fn as_str(&self) -> io::Result<&str> {
312
0
        self.as_os_str().to_str().ok_or(io::Errno::INVAL)
313
0
    }
314
315
    #[inline]
316
0
    fn to_string_lossy(&self) -> Cow<'_, str> {
317
0
        self.as_os_str().to_string_lossy()
318
0
    }
319
320
    #[inline]
321
0
    fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> {
322
0
        self.as_os_str().into_c_str()
323
0
    }
324
325
    #[inline]
326
0
    fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
327
0
    where
328
0
        Self: 'b,
329
    {
330
        #[cfg(all(target_os = "wasi", target_env = "p2", not(wasip2)))]
331
        return self
332
            .into_string()
333
            .map_err(|_strng_err| io::Errno::INVAL)?
334
            .into_c_str();
335
        #[cfg(any(wasip2, not(all(target_os = "wasi", target_env = "p2"))))]
336
0
        self.into_vec().into_c_str()
337
0
    }
338
339
    #[inline]
340
0
    fn into_with_c_str<T, F>(self, f: F) -> io::Result<T>
341
0
    where
342
0
        Self: Sized,
343
0
        F: FnOnce(&CStr) -> io::Result<T>,
344
    {
345
0
        f(&self.into_c_str()?)
346
0
    }
347
}
348
349
#[cfg(feature = "std")]
350
impl Arg for &Path {
351
    #[inline]
352
0
    fn as_str(&self) -> io::Result<&str> {
353
0
        self.as_os_str().to_str().ok_or(io::Errno::INVAL)
354
0
    }
355
356
    #[inline]
357
0
    fn to_string_lossy(&self) -> Cow<'_, str> {
358
0
        Path::to_string_lossy(self)
359
0
    }
360
361
    #[inline]
362
0
    fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> {
363
0
        self.as_os_str().into_c_str()
364
0
    }
365
366
    #[inline]
367
0
    fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
368
0
    where
369
0
        Self: 'b,
370
    {
371
0
        self.as_os_str().into_c_str()
372
0
    }
373
374
    #[inline]
375
1.25M
    fn into_with_c_str<T, F>(self, f: F) -> io::Result<T>
376
1.25M
    where
377
1.25M
        Self: Sized,
378
1.25M
        F: FnOnce(&CStr) -> io::Result<T>,
379
    {
380
1.25M
        self.as_os_str().into_with_c_str(f)
381
1.25M
    }
Unexecuted instantiation: <&std::path::Path as rustix::path::arg::Arg>::into_with_c_str::<(), 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: <&std::path::Path as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::abs::rename<&std::path::Path, &std::path::Path>::{closure#0}>
Unexecuted instantiation: <&std::path::Path as rustix::path::arg::Arg>::into_with_c_str::<(), 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: <&std::path::Path as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::abs::rename<&std::path::Path, &std::path::Path>::{closure#0}::{closure#0}>
Unexecuted instantiation: <&std::path::Path as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::backend::fs::syscalls::unlink>
Unexecuted instantiation: <&std::path::Path as rustix::path::arg::Arg>::into_with_c_str::<(&mut [u8], &mut [core::mem::maybe_uninit::MaybeUninit<u8>]), rustix::fs::xattr::llistxattr<&std::path::Path, &mut [core::mem::maybe_uninit::MaybeUninit<u8>]>::{closure#0}>
Unexecuted instantiation: <&std::path::Path as rustix::path::arg::Arg>::into_with_c_str::<(&mut [u8], &mut [core::mem::maybe_uninit::MaybeUninit<u8>]), rustix::fs::xattr::getxattr<&std::path::Path, &std::ffi::os_str::OsStr, &mut [core::mem::maybe_uninit::MaybeUninit<u8>]>::{closure#0}>
Unexecuted instantiation: <&std::path::Path as rustix::path::arg::Arg>::into_with_c_str::<(&mut [u8], &mut [core::mem::maybe_uninit::MaybeUninit<u8>]), rustix::fs::xattr::lgetxattr<&std::path::Path, &std::ffi::os_str::OsStr, &mut [core::mem::maybe_uninit::MaybeUninit<u8>]>::{closure#0}>
Unexecuted instantiation: <&std::path::Path as rustix::path::arg::Arg>::into_with_c_str::<(&mut [u8], &mut [core::mem::maybe_uninit::MaybeUninit<u8>]), rustix::fs::xattr::listxattr<&std::path::Path, &mut [core::mem::maybe_uninit::MaybeUninit<u8>]>::{closure#0}>
Unexecuted instantiation: <&std::path::Path as rustix::path::arg::Arg>::into_with_c_str::<usize, rustix::fs::xattr::llistxattr<&std::path::Path, &mut [u8]>::{closure#0}>
Unexecuted instantiation: <&std::path::Path as rustix::path::arg::Arg>::into_with_c_str::<usize, rustix::fs::xattr::getxattr<&std::path::Path, &std::ffi::os_str::OsStr, &mut [u8]>::{closure#0}>
Unexecuted instantiation: <&std::path::Path as rustix::path::arg::Arg>::into_with_c_str::<usize, rustix::fs::xattr::lgetxattr<&std::path::Path, &std::ffi::os_str::OsStr, &mut [u8]>::{closure#0}>
Unexecuted instantiation: <&std::path::Path as rustix::path::arg::Arg>::into_with_c_str::<usize, rustix::fs::xattr::listxattr<&std::path::Path, &mut [u8]>::{closure#0}>
Unexecuted instantiation: <&std::path::Path as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::xattr::removexattr<&std::path::Path, &std::ffi::os_str::OsStr>::{closure#0}>
Unexecuted instantiation: <&std::path::Path as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::xattr::lremovexattr<&std::path::Path, &std::ffi::os_str::OsStr>::{closure#0}>
Unexecuted instantiation: <&std::path::Path as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::xattr::setxattr<&std::path::Path, &std::ffi::os_str::OsStr>::{closure#0}>
Unexecuted instantiation: <&std::path::Path as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::xattr::lsetxattr<&std::path::Path, &std::ffi::os_str::OsStr>::{closure#0}>
<&std::path::Path as rustix::path::arg::Arg>::into_with_c_str::<std::fs::File, cap_primitives::rustix::linux::fs::open_impl::open_beneath::{closure#0}>
Line
Count
Source
375
877k
    fn into_with_c_str<T, F>(self, f: F) -> io::Result<T>
376
877k
    where
377
877k
        Self: Sized,
378
877k
        F: FnOnce(&CStr) -> io::Result<T>,
379
    {
380
877k
        self.as_os_str().into_with_c_str(f)
381
877k
    }
Unexecuted instantiation: <&std::path::Path as rustix::path::arg::Arg>::into_with_c_str::<rustix::fs::statx::Statx, rustix::fs::statx::statx<&std::path::Path, &std::fs::File>::{closure#0}>
Unexecuted instantiation: <&std::path::Path as rustix::path::arg::Arg>::into_with_c_str::<alloc::ffi::c_str::CString, rustix::fs::at::readlinkat<&std::path::Path, &std::fs::File, alloc::vec::Vec<u8>>::{closure#0}>
Unexecuted instantiation: <&std::path::Path as rustix::path::arg::Arg>::into_with_c_str::<std::os::fd::owned::OwnedFd, rustix::fs::at::openat<&std::path::Path, &std::fs::File>::{closure#0}>
Unexecuted instantiation: <&std::path::Path as rustix::path::arg::Arg>::into_with_c_str::<rustix::backend::fs::types::Stat, rustix::fs::at::statat<&std::path::Path, &std::fs::File>::{closure#0}>
Unexecuted instantiation: <&std::path::Path as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::at::linkat<&std::path::Path, &std::path::Path, &std::fs::File, &std::fs::File>::{closure#0}>
Unexecuted instantiation: <&std::path::Path as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::at::chmodat<&std::path::Path, &std::fs::File>::{closure#0}>
<&std::path::Path as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::at::mkdirat<&std::path::Path, &std::fs::File>::{closure#0}>
Line
Count
Source
375
379k
    fn into_with_c_str<T, F>(self, f: F) -> io::Result<T>
376
379k
    where
377
379k
        Self: Sized,
378
379k
        F: FnOnce(&CStr) -> io::Result<T>,
379
    {
380
379k
        self.as_os_str().into_with_c_str(f)
381
379k
    }
Unexecuted instantiation: <&std::path::Path as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::at::accessat<&std::path::Path, &std::fs::File>::{closure#0}>
Unexecuted instantiation: <&std::path::Path as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::at::renameat<&std::path::Path, &std::path::Path, &std::fs::File, &std::fs::File>::{closure#0}>
Unexecuted instantiation: <&std::path::Path as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::at::unlinkat<&std::path::Path, &std::fs::File>::{closure#0}>
Unexecuted instantiation: <&std::path::Path as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::at::symlinkat<&std::path::Path, &std::path::Path, &std::fs::File>::{closure#0}>
Unexecuted instantiation: <&std::path::Path as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::at::utimensat<&std::path::Path, &std::fs::File>::{closure#0}>
Unexecuted instantiation: <&std::path::Path as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::at::linkat<&std::path::Path, &std::path::Path, &std::fs::File, &std::fs::File>::{closure#0}::{closure#0}>
Unexecuted instantiation: <&std::path::Path as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::at::renameat<&std::path::Path, &std::path::Path, &std::fs::File, &std::fs::File>::{closure#0}::{closure#0}>
Unexecuted instantiation: <&std::path::Path as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::at::symlinkat<&std::path::Path, &std::path::Path, &std::fs::File>::{closure#0}::{closure#0}>
Unexecuted instantiation: <&std::path::Path as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::at::utimensat<&std::path::Path, std::os::fd::owned::BorrowedFd>::{closure#0}>
Unexecuted instantiation: <&std::path::Path as rustix::path::arg::Arg>::into_with_c_str::<_, _>
382
}
383
384
#[cfg(feature = "std")]
385
impl Arg for &PathBuf {
386
    #[inline]
387
0
    fn as_str(&self) -> io::Result<&str> {
388
0
        self.as_os_str().to_str().ok_or(io::Errno::INVAL)
389
0
    }
390
391
    #[inline]
392
0
    fn to_string_lossy(&self) -> Cow<'_, str> {
393
0
        self.as_path().to_string_lossy()
394
0
    }
395
396
    #[inline]
397
0
    fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> {
398
0
        self.as_os_str().into_c_str()
399
0
    }
400
401
    #[inline]
402
0
    fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
403
0
    where
404
0
        Self: 'b,
405
    {
406
0
        self.as_path().into_c_str()
407
0
    }
408
409
    #[inline]
410
0
    fn into_with_c_str<T, F>(self, f: F) -> io::Result<T>
411
0
    where
412
0
        Self: Sized,
413
0
        F: FnOnce(&CStr) -> io::Result<T>,
414
    {
415
0
        self.as_os_str().into_with_c_str(f)
416
0
    }
417
}
418
419
#[cfg(feature = "std")]
420
impl Arg for PathBuf {
421
    #[inline]
422
0
    fn as_str(&self) -> io::Result<&str> {
423
0
        self.as_os_str().to_str().ok_or(io::Errno::INVAL)
424
0
    }
425
426
    #[inline]
427
0
    fn to_string_lossy(&self) -> Cow<'_, str> {
428
0
        self.as_os_str().to_string_lossy()
429
0
    }
430
431
    #[inline]
432
0
    fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> {
433
0
        self.as_os_str().into_c_str()
434
0
    }
435
436
    #[inline]
437
0
    fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
438
0
    where
439
0
        Self: 'b,
440
    {
441
0
        self.into_os_string().into_c_str()
442
0
    }
443
444
    #[inline]
445
0
    fn into_with_c_str<T, F>(self, f: F) -> io::Result<T>
446
0
    where
447
0
        Self: Sized,
448
0
        F: FnOnce(&CStr) -> io::Result<T>,
449
    {
450
0
        self.into_os_string().into_with_c_str(f)
451
0
    }
452
}
453
454
impl Arg for &CStr {
455
    #[inline]
456
0
    fn as_str(&self) -> io::Result<&str> {
457
0
        self.to_str().map_err(|_utf8_err| io::Errno::INVAL)
458
0
    }
459
460
    #[cfg(feature = "alloc")]
461
    #[inline]
462
0
    fn to_string_lossy(&self) -> Cow<'_, str> {
463
0
        CStr::to_string_lossy(self)
464
0
    }
465
466
    #[cfg(feature = "alloc")]
467
    #[inline]
468
0
    fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> {
469
0
        Ok(Cow::Borrowed(self))
470
0
    }
471
472
    #[cfg(feature = "alloc")]
473
    #[inline]
474
0
    fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
475
0
    where
476
0
        Self: 'b,
477
    {
478
0
        Ok(Cow::Borrowed(self))
479
0
    }
480
481
    #[inline]
482
875k
    fn into_with_c_str<T, F>(self, f: F) -> io::Result<T>
483
875k
    where
484
875k
        Self: Sized,
485
875k
        F: FnOnce(&CStr) -> io::Result<T>,
486
    {
487
875k
        f(self)
488
875k
    }
<&core::ffi::c_str::CStr as rustix::path::arg::Arg>::into_with_c_str::<std::os::fd::owned::OwnedFd, rustix::fs::openat2::openat2<&std::fs::File, &core::ffi::c_str::CStr>::{closure#0}>
Line
Count
Source
482
875k
    fn into_with_c_str<T, F>(self, f: F) -> io::Result<T>
483
875k
    where
484
875k
        Self: Sized,
485
875k
        F: FnOnce(&CStr) -> io::Result<T>,
486
    {
487
875k
        f(self)
488
875k
    }
Unexecuted instantiation: <&core::ffi::c_str::CStr as rustix::path::arg::Arg>::into_with_c_str::<std::os::fd::owned::OwnedFd, rustix::fs::at::openat<&core::ffi::c_str::CStr, std::os::fd::owned::BorrowedFd>::{closure#0}>
Unexecuted instantiation: <&core::ffi::c_str::CStr as rustix::path::arg::Arg>::into_with_c_str::<usize, 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: <&core::ffi::c_str::CStr as rustix::path::arg::Arg>::into_with_c_str::<(), 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: <&core::ffi::c_str::CStr as rustix::path::arg::Arg>::into_with_c_str::<(), 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: <&core::ffi::c_str::CStr as rustix::path::arg::Arg>::into_with_c_str::<usize, rustix::fs::at::readlinkat_raw<&core::ffi::c_str::CStr, std::os::fd::owned::BorrowedFd, &mut [core::mem::maybe_uninit::MaybeUninit<u8>]>::{closure#0}>
489
}
490
491
#[cfg(feature = "alloc")]
492
impl Arg for &CString {
493
    #[inline]
494
0
    fn as_str(&self) -> io::Result<&str> {
495
0
        self.to_str().map_err(|_utf8_err| io::Errno::INVAL)
496
0
    }
497
498
    #[inline]
499
0
    fn to_string_lossy(&self) -> Cow<'_, str> {
500
0
        CStr::to_string_lossy(self)
501
0
    }
502
503
    #[inline]
504
0
    fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> {
505
0
        Ok(Cow::Borrowed(self))
506
0
    }
507
508
    #[inline]
509
0
    fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
510
0
    where
511
0
        Self: 'b,
512
    {
513
0
        Ok(Cow::Borrowed(self))
514
0
    }
515
516
    #[inline]
517
0
    fn into_with_c_str<T, F>(self, f: F) -> io::Result<T>
518
0
    where
519
0
        Self: Sized,
520
0
        F: FnOnce(&CStr) -> io::Result<T>,
521
    {
522
0
        f(self)
523
0
    }
524
}
525
526
#[cfg(feature = "alloc")]
527
impl Arg for CString {
528
    #[inline]
529
0
    fn as_str(&self) -> io::Result<&str> {
530
0
        self.to_str().map_err(|_utf8_err| io::Errno::INVAL)
531
0
    }
532
533
    #[inline]
534
0
    fn to_string_lossy(&self) -> Cow<'_, str> {
535
0
        CStr::to_string_lossy(self)
536
0
    }
537
538
    #[inline]
539
0
    fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> {
540
0
        Ok(Cow::Borrowed(self))
541
0
    }
542
543
    #[inline]
544
0
    fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
545
0
    where
546
0
        Self: 'b,
547
    {
548
0
        Ok(Cow::Owned(self))
549
0
    }
550
551
    #[inline]
552
0
    fn into_with_c_str<T, F>(self, f: F) -> io::Result<T>
553
0
    where
554
0
        Self: Sized,
555
0
        F: FnOnce(&CStr) -> io::Result<T>,
556
    {
557
0
        f(&self)
558
0
    }
559
}
560
561
#[cfg(feature = "alloc")]
562
impl<'a> Arg for Cow<'a, str> {
563
    #[inline]
564
0
    fn as_str(&self) -> io::Result<&str> {
565
0
        Ok(self)
566
0
    }
567
568
    #[inline]
569
0
    fn to_string_lossy(&self) -> Cow<'_, str> {
570
0
        Cow::Borrowed(self)
571
0
    }
572
573
    #[inline]
574
0
    fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> {
575
        Ok(Cow::Owned(
576
0
            CString::new(self.as_ref()).map_err(|_cstr_err| io::Errno::INVAL)?,
577
        ))
578
0
    }
579
580
    #[inline]
581
0
    fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
582
0
    where
583
0
        Self: 'b,
584
    {
585
        Ok(Cow::Owned(
586
0
            match self {
587
0
                Cow::Owned(s) => CString::new(s),
588
0
                Cow::Borrowed(s) => CString::new(s),
589
            }
590
0
            .map_err(|_cstr_err| io::Errno::INVAL)?,
591
        ))
592
0
    }
593
594
    #[inline]
595
0
    fn into_with_c_str<T, F>(self, f: F) -> io::Result<T>
596
0
    where
597
0
        Self: Sized,
598
0
        F: FnOnce(&CStr) -> io::Result<T>,
599
    {
600
0
        with_c_str(self.as_bytes(), f)
601
0
    }
602
}
603
604
#[cfg(feature = "std")]
605
impl<'a> Arg for Cow<'a, OsStr> {
606
    #[inline]
607
0
    fn as_str(&self) -> io::Result<&str> {
608
0
        (**self).to_str().ok_or(io::Errno::INVAL)
609
0
    }
610
611
    #[inline]
612
0
    fn to_string_lossy(&self) -> Cow<'_, str> {
613
0
        (**self).to_string_lossy()
614
0
    }
615
616
    #[inline]
617
0
    fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> {
618
0
        (&**self).into_c_str()
619
0
    }
620
621
    #[inline]
622
0
    fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
623
0
    where
624
0
        Self: 'b,
625
    {
626
0
        match self {
627
0
            Cow::Owned(os) => os.into_c_str(),
628
0
            Cow::Borrowed(os) => os.into_c_str(),
629
        }
630
0
    }
631
632
    #[inline]
633
0
    fn into_with_c_str<T, F>(self, f: F) -> io::Result<T>
634
0
    where
635
0
        Self: Sized,
636
0
        F: FnOnce(&CStr) -> io::Result<T>,
637
    {
638
0
        (&*self).into_with_c_str(f)
639
0
    }
640
}
641
642
#[cfg(feature = "alloc")]
643
impl<'a> Arg for Cow<'a, CStr> {
644
    #[inline]
645
0
    fn as_str(&self) -> io::Result<&str> {
646
0
        self.to_str().map_err(|_utf8_err| io::Errno::INVAL)
647
0
    }
648
649
    #[inline]
650
0
    fn to_string_lossy(&self) -> Cow<'_, str> {
651
0
        let borrow: &CStr = core::borrow::Borrow::borrow(self);
652
0
        borrow.to_string_lossy()
653
0
    }
654
655
    #[inline]
656
0
    fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> {
657
0
        Ok(Cow::Borrowed(self))
658
0
    }
659
660
    #[inline]
661
0
    fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
662
0
    where
663
0
        Self: 'b,
664
    {
665
0
        Ok(self)
666
0
    }
667
668
    #[inline]
669
0
    fn into_with_c_str<T, F>(self, f: F) -> io::Result<T>
670
0
    where
671
0
        Self: Sized,
672
0
        F: FnOnce(&CStr) -> io::Result<T>,
673
    {
674
0
        f(&self)
675
0
    }
676
}
677
678
#[cfg(feature = "std")]
679
impl<'a> Arg for Component<'a> {
680
    #[inline]
681
0
    fn as_str(&self) -> io::Result<&str> {
682
0
        self.as_os_str().to_str().ok_or(io::Errno::INVAL)
683
0
    }
684
685
    #[inline]
686
0
    fn to_string_lossy(&self) -> Cow<'_, str> {
687
0
        self.as_os_str().to_string_lossy()
688
0
    }
689
690
    #[inline]
691
0
    fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> {
692
0
        self.as_os_str().into_c_str()
693
0
    }
694
695
    #[inline]
696
0
    fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
697
0
    where
698
0
        Self: 'b,
699
    {
700
0
        self.as_os_str().into_c_str()
701
0
    }
702
703
    #[inline]
704
0
    fn into_with_c_str<T, F>(self, f: F) -> io::Result<T>
705
0
    where
706
0
        Self: Sized,
707
0
        F: FnOnce(&CStr) -> io::Result<T>,
708
    {
709
0
        self.as_os_str().into_with_c_str(f)
710
0
    }
711
}
712
713
#[cfg(feature = "std")]
714
impl<'a> Arg for Components<'a> {
715
    #[inline]
716
0
    fn as_str(&self) -> io::Result<&str> {
717
0
        self.as_path().to_str().ok_or(io::Errno::INVAL)
718
0
    }
719
720
    #[inline]
721
0
    fn to_string_lossy(&self) -> Cow<'_, str> {
722
0
        self.as_path().to_string_lossy()
723
0
    }
724
725
    #[inline]
726
0
    fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> {
727
0
        self.as_path().into_c_str()
728
0
    }
729
730
    #[inline]
731
0
    fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
732
0
    where
733
0
        Self: 'b,
734
    {
735
0
        self.as_path().into_c_str()
736
0
    }
737
738
    #[inline]
739
0
    fn into_with_c_str<T, F>(self, f: F) -> io::Result<T>
740
0
    where
741
0
        Self: Sized,
742
0
        F: FnOnce(&CStr) -> io::Result<T>,
743
    {
744
0
        self.as_path().into_with_c_str(f)
745
0
    }
746
}
747
748
#[cfg(feature = "std")]
749
impl<'a> Arg for Iter<'a> {
750
    #[inline]
751
0
    fn as_str(&self) -> io::Result<&str> {
752
0
        self.as_path().to_str().ok_or(io::Errno::INVAL)
753
0
    }
754
755
    #[inline]
756
0
    fn to_string_lossy(&self) -> Cow<'_, str> {
757
0
        self.as_path().to_string_lossy()
758
0
    }
759
760
    #[inline]
761
0
    fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> {
762
0
        self.as_path().into_c_str()
763
0
    }
764
765
    #[inline]
766
0
    fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
767
0
    where
768
0
        Self: 'b,
769
    {
770
0
        self.as_path().into_c_str()
771
0
    }
772
773
    #[inline]
774
0
    fn into_with_c_str<T, F>(self, f: F) -> io::Result<T>
775
0
    where
776
0
        Self: Sized,
777
0
        F: FnOnce(&CStr) -> io::Result<T>,
778
    {
779
0
        self.as_path().into_with_c_str(f)
780
0
    }
781
}
782
783
impl Arg for &[u8] {
784
    #[inline]
785
0
    fn as_str(&self) -> io::Result<&str> {
786
0
        str::from_utf8(self).map_err(|_utf8_err| io::Errno::INVAL)
787
0
    }
788
789
    #[cfg(feature = "alloc")]
790
    #[inline]
791
0
    fn to_string_lossy(&self) -> Cow<'_, str> {
792
0
        String::from_utf8_lossy(self)
793
0
    }
794
795
    #[cfg(feature = "alloc")]
796
    #[inline]
797
0
    fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> {
798
        Ok(Cow::Owned(
799
0
            CString::new(*self).map_err(|_cstr_err| io::Errno::INVAL)?,
800
        ))
801
0
    }
802
803
    #[cfg(feature = "alloc")]
804
    #[inline]
805
0
    fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
806
0
    where
807
0
        Self: 'b,
808
    {
809
        Ok(Cow::Owned(
810
0
            CString::new(self).map_err(|_cstr_err| io::Errno::INVAL)?,
811
        ))
812
0
    }
813
814
    #[inline]
815
1.25M
    fn into_with_c_str<T, F>(self, f: F) -> io::Result<T>
816
1.25M
    where
817
1.25M
        Self: Sized,
818
1.25M
        F: FnOnce(&CStr) -> io::Result<T>,
819
    {
820
1.25M
        with_c_str(self, f)
821
1.25M
    }
Unexecuted instantiation: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<(), 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: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::abs::rename<&std::path::Path, &std::path::Path>::{closure#0}>
Unexecuted instantiation: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<(), 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: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::abs::rename<&std::path::Path, &std::path::Path>::{closure#0}::{closure#0}>
Unexecuted instantiation: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::backend::fs::syscalls::unlink>
Unexecuted instantiation: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<(&mut [u8], &mut [core::mem::maybe_uninit::MaybeUninit<u8>]), rustix::fs::xattr::llistxattr<&std::path::Path, &mut [core::mem::maybe_uninit::MaybeUninit<u8>]>::{closure#0}>
Unexecuted instantiation: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<(&mut [u8], &mut [core::mem::maybe_uninit::MaybeUninit<u8>]), rustix::fs::xattr::getxattr<&std::path::Path, &std::ffi::os_str::OsStr, &mut [core::mem::maybe_uninit::MaybeUninit<u8>]>::{closure#0}>
Unexecuted instantiation: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<(&mut [u8], &mut [core::mem::maybe_uninit::MaybeUninit<u8>]), rustix::fs::xattr::fgetxattr<std::os::fd::owned::BorrowedFd, &std::ffi::os_str::OsStr, &mut [core::mem::maybe_uninit::MaybeUninit<u8>]>::{closure#0}>
Unexecuted instantiation: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<(&mut [u8], &mut [core::mem::maybe_uninit::MaybeUninit<u8>]), rustix::fs::xattr::lgetxattr<&std::path::Path, &std::ffi::os_str::OsStr, &mut [core::mem::maybe_uninit::MaybeUninit<u8>]>::{closure#0}>
Unexecuted instantiation: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<(&mut [u8], &mut [core::mem::maybe_uninit::MaybeUninit<u8>]), rustix::fs::xattr::listxattr<&std::path::Path, &mut [core::mem::maybe_uninit::MaybeUninit<u8>]>::{closure#0}>
Unexecuted instantiation: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<(&mut [u8], &mut [core::mem::maybe_uninit::MaybeUninit<u8>]), rustix::fs::xattr::getxattr<&std::path::Path, &std::ffi::os_str::OsStr, &mut [core::mem::maybe_uninit::MaybeUninit<u8>]>::{closure#0}::{closure#0}>
Unexecuted instantiation: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<(&mut [u8], &mut [core::mem::maybe_uninit::MaybeUninit<u8>]), rustix::fs::xattr::lgetxattr<&std::path::Path, &std::ffi::os_str::OsStr, &mut [core::mem::maybe_uninit::MaybeUninit<u8>]>::{closure#0}::{closure#0}>
Unexecuted instantiation: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<usize, rustix::fs::xattr::llistxattr<&std::path::Path, &mut [u8]>::{closure#0}>
Unexecuted instantiation: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<usize, rustix::fs::xattr::getxattr<&std::path::Path, &std::ffi::os_str::OsStr, &mut [u8]>::{closure#0}>
Unexecuted instantiation: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<usize, rustix::fs::xattr::fgetxattr<std::os::fd::owned::BorrowedFd, &std::ffi::os_str::OsStr, &mut [u8]>::{closure#0}>
Unexecuted instantiation: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<usize, rustix::fs::xattr::lgetxattr<&std::path::Path, &std::ffi::os_str::OsStr, &mut [u8]>::{closure#0}>
Unexecuted instantiation: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<usize, rustix::fs::xattr::listxattr<&std::path::Path, &mut [u8]>::{closure#0}>
Unexecuted instantiation: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<usize, rustix::fs::xattr::getxattr<&std::path::Path, &std::ffi::os_str::OsStr, &mut [u8]>::{closure#0}::{closure#0}>
Unexecuted instantiation: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<usize, rustix::fs::xattr::lgetxattr<&std::path::Path, &std::ffi::os_str::OsStr, &mut [u8]>::{closure#0}::{closure#0}>
Unexecuted instantiation: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::xattr::removexattr<&std::path::Path, &std::ffi::os_str::OsStr>::{closure#0}>
Unexecuted instantiation: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::xattr::fremovexattr<std::os::fd::owned::BorrowedFd, &std::ffi::os_str::OsStr>::{closure#0}>
Unexecuted instantiation: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::xattr::lremovexattr<&std::path::Path, &std::ffi::os_str::OsStr>::{closure#0}>
Unexecuted instantiation: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::xattr::setxattr<&std::path::Path, &std::ffi::os_str::OsStr>::{closure#0}>
Unexecuted instantiation: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::xattr::fsetxattr<std::os::fd::owned::BorrowedFd, &std::ffi::os_str::OsStr>::{closure#0}>
Unexecuted instantiation: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::xattr::lsetxattr<&std::path::Path, &std::ffi::os_str::OsStr>::{closure#0}>
Unexecuted instantiation: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::xattr::removexattr<&std::path::Path, &std::ffi::os_str::OsStr>::{closure#0}::{closure#0}>
Unexecuted instantiation: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::xattr::lremovexattr<&std::path::Path, &std::ffi::os_str::OsStr>::{closure#0}::{closure#0}>
Unexecuted instantiation: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::xattr::setxattr<&std::path::Path, &std::ffi::os_str::OsStr>::{closure#0}::{closure#0}>
Unexecuted instantiation: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::xattr::lsetxattr<&std::path::Path, &std::ffi::os_str::OsStr>::{closure#0}::{closure#0}>
<&[u8] as rustix::path::arg::Arg>::into_with_c_str::<std::fs::File, cap_primitives::rustix::linux::fs::open_impl::open_beneath::{closure#0}>
Line
Count
Source
815
877k
    fn into_with_c_str<T, F>(self, f: F) -> io::Result<T>
816
877k
    where
817
877k
        Self: Sized,
818
877k
        F: FnOnce(&CStr) -> io::Result<T>,
819
    {
820
877k
        with_c_str(self, f)
821
877k
    }
Unexecuted instantiation: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<rustix::fs::statx::Statx, rustix::fs::statx::statx<&std::path::Path, &std::fs::File>::{closure#0}>
Unexecuted instantiation: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<alloc::ffi::c_str::CString, rustix::fs::at::readlinkat<&std::path::Path, &std::fs::File, alloc::vec::Vec<u8>>::{closure#0}>
Unexecuted instantiation: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<rustix::backend::fs::types::Stat, rustix::fs::at::statat<&std::path::Path, &std::fs::File>::{closure#0}>
Unexecuted instantiation: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<std::os::fd::owned::OwnedFd, rustix::fs::at::openat<&std::path::Path, &std::fs::File>::{closure#0}>
Unexecuted instantiation: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::at::linkat<&std::path::Path, &std::path::Path, &std::fs::File, &std::fs::File>::{closure#0}>
Unexecuted instantiation: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::at::chmodat<&std::path::Path, &std::fs::File>::{closure#0}>
<&[u8] as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::at::mkdirat<&std::path::Path, &std::fs::File>::{closure#0}>
Line
Count
Source
815
379k
    fn into_with_c_str<T, F>(self, f: F) -> io::Result<T>
816
379k
    where
817
379k
        Self: Sized,
818
379k
        F: FnOnce(&CStr) -> io::Result<T>,
819
    {
820
379k
        with_c_str(self, f)
821
379k
    }
Unexecuted instantiation: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::at::accessat<&std::path::Path, &std::fs::File>::{closure#0}>
Unexecuted instantiation: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::at::accessat<&std::ffi::os_str::OsStr, &std::fs::File>::{closure#0}>
Unexecuted instantiation: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::at::renameat<&std::path::Path, &std::path::Path, &std::fs::File, &std::fs::File>::{closure#0}>
Unexecuted instantiation: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::at::unlinkat<&std::path::Path, &std::fs::File>::{closure#0}>
Unexecuted instantiation: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::at::symlinkat<&std::path::Path, &std::path::Path, &std::fs::File>::{closure#0}>
Unexecuted instantiation: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::at::utimensat<&std::path::Path, &std::fs::File>::{closure#0}>
Unexecuted instantiation: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::at::linkat<&std::path::Path, &std::path::Path, &std::fs::File, &std::fs::File>::{closure#0}::{closure#0}>
Unexecuted instantiation: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::at::renameat<&std::path::Path, &std::path::Path, &std::fs::File, &std::fs::File>::{closure#0}::{closure#0}>
Unexecuted instantiation: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::at::symlinkat<&std::path::Path, &std::path::Path, &std::fs::File>::{closure#0}::{closure#0}>
Unexecuted instantiation: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::at::utimensat<&std::path::Path, std::os::fd::owned::BorrowedFd>::{closure#0}>
Unexecuted instantiation: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<std::os::fd::owned::OwnedFd, rustix::fs::at::openat<&[u8], std::os::fd::owned::BorrowedFd>::{closure#0}>
Unexecuted instantiation: <&[u8] as rustix::path::arg::Arg>::into_with_c_str::<_, _>
822
}
823
824
#[cfg(feature = "alloc")]
825
impl Arg for &Vec<u8> {
826
    #[inline]
827
0
    fn as_str(&self) -> io::Result<&str> {
828
0
        str::from_utf8(self).map_err(|_utf8_err| io::Errno::INVAL)
829
0
    }
830
831
    #[cfg(feature = "alloc")]
832
    #[inline]
833
0
    fn to_string_lossy(&self) -> Cow<'_, str> {
834
0
        String::from_utf8_lossy(self)
835
0
    }
836
837
    #[cfg(feature = "alloc")]
838
    #[inline]
839
0
    fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> {
840
        Ok(Cow::Owned(
841
0
            CString::new(self.as_slice()).map_err(|_cstr_err| io::Errno::INVAL)?,
842
        ))
843
0
    }
844
845
    #[cfg(feature = "alloc")]
846
    #[inline]
847
0
    fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
848
0
    where
849
0
        Self: 'b,
850
    {
851
        Ok(Cow::Owned(
852
0
            CString::new(self.as_slice()).map_err(|_cstr_err| io::Errno::INVAL)?,
853
        ))
854
0
    }
855
856
    #[inline]
857
0
    fn into_with_c_str<T, F>(self, f: F) -> io::Result<T>
858
0
    where
859
0
        Self: Sized,
860
0
        F: FnOnce(&CStr) -> io::Result<T>,
861
    {
862
0
        with_c_str(self, f)
863
0
    }
864
}
865
866
#[cfg(feature = "alloc")]
867
impl Arg for Vec<u8> {
868
    #[inline]
869
0
    fn as_str(&self) -> io::Result<&str> {
870
0
        str::from_utf8(self).map_err(|_utf8_err| io::Errno::INVAL)
871
0
    }
872
873
    #[cfg(feature = "alloc")]
874
    #[inline]
875
0
    fn to_string_lossy(&self) -> Cow<'_, str> {
876
0
        String::from_utf8_lossy(self)
877
0
    }
878
879
    #[cfg(feature = "alloc")]
880
    #[inline]
881
0
    fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> {
882
        Ok(Cow::Owned(
883
0
            CString::new(self.as_slice()).map_err(|_cstr_err| io::Errno::INVAL)?,
884
        ))
885
0
    }
886
887
    #[cfg(feature = "alloc")]
888
    #[inline]
889
0
    fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
890
0
    where
891
0
        Self: 'b,
892
    {
893
        Ok(Cow::Owned(
894
0
            CString::new(self).map_err(|_cstr_err| io::Errno::INVAL)?,
895
        ))
896
0
    }
897
898
    #[inline]
899
0
    fn into_with_c_str<T, F>(self, f: F) -> io::Result<T>
900
0
    where
901
0
        Self: Sized,
902
0
        F: FnOnce(&CStr) -> io::Result<T>,
903
    {
904
0
        f(&CString::new(self).map_err(|_cstr_err| io::Errno::INVAL)?)
905
0
    }
906
}
907
908
impl Arg for DecInt {
909
    #[inline]
910
0
    fn as_str(&self) -> io::Result<&str> {
911
0
        Ok(self.as_str())
912
0
    }
913
914
    #[cfg(feature = "alloc")]
915
    #[inline]
916
0
    fn to_string_lossy(&self) -> Cow<'_, str> {
917
0
        Cow::Borrowed(self.as_str())
918
0
    }
919
920
    #[cfg(feature = "alloc")]
921
    #[inline]
922
0
    fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> {
923
0
        Ok(Cow::Borrowed(self.as_c_str()))
924
0
    }
925
926
    #[cfg(feature = "alloc")]
927
    #[inline]
928
0
    fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>>
929
0
    where
930
0
        Self: 'b,
931
    {
932
0
        Ok(Cow::Owned(self.as_c_str().to_owned()))
933
0
    }
934
935
    #[inline]
936
0
    fn into_with_c_str<T, F>(self, f: F) -> io::Result<T>
937
0
    where
938
0
        Self: Sized,
939
0
        F: FnOnce(&CStr) -> io::Result<T>,
940
    {
941
0
        f(self.as_c_str())
942
0
    }
Unexecuted instantiation: <rustix::path::dec_int::DecInt as rustix::path::arg::Arg>::into_with_c_str::<(), rustix::fs::at::chmodat<rustix::path::dec_int::DecInt, std::os::fd::owned::BorrowedFd>::{closure#0}>
Unexecuted instantiation: <rustix::path::dec_int::DecInt as rustix::path::arg::Arg>::into_with_c_str::<_, _>
943
}
944
945
/// Runs a closure with `bytes` passed in as a `&CStr`.
946
#[allow(unsafe_code, clippy::int_plus_one)]
947
#[inline]
948
1.25M
fn with_c_str<T, F>(bytes: &[u8], f: F) -> io::Result<T>
949
1.25M
where
950
1.25M
    F: FnOnce(&CStr) -> io::Result<T>,
951
{
952
    // Most paths are less than `SMALL_PATH_BUFFER_SIZE` long. The rest can go
953
    // through the dynamic allocation path. If you're opening many files in a
954
    // directory with a long path, consider opening the directory and using
955
    // `openat` to open the files under it, which will avoid this, and is often
956
    // faster in the OS as well.
957
958
    // Test with `>=` so that we have room for the trailing NUL.
959
1.25M
    if bytes.len() >= SMALL_PATH_BUFFER_SIZE {
960
672k
        return with_c_str_slow_path(bytes, f);
961
584k
    }
962
963
    // Taken from
964
    // <https://github.com/rust-lang/rust/blob/a00f8ba7fcac1b27341679c51bf5a3271fa82df3/library/std/src/sys/common/small_c_string.rs>
965
584k
    let mut buf = MaybeUninit::<[u8; SMALL_PATH_BUFFER_SIZE]>::uninit();
966
584k
    let buf_ptr = buf.as_mut_ptr().cast::<u8>();
967
968
    // This helps test our safety condition below.
969
584k
    debug_assert!(bytes.len() + 1 <= SMALL_PATH_BUFFER_SIZE);
970
971
    // SAFETY: `bytes.len() < SMALL_PATH_BUFFER_SIZE` which means we have space
972
    // for `bytes.len() + 1` `u8`s:
973
584k
    unsafe {
974
584k
        ptr::copy_nonoverlapping(bytes.as_ptr(), buf_ptr, bytes.len());
975
584k
        buf_ptr.add(bytes.len()).write(b'\0');
976
584k
    }
977
978
    // SAFETY: We just wrote the bytes above and they will remain valid for the
979
    // duration of `f` because `buf` doesn't get dropped until the end of the
980
    // function.
981
584k
    match CStr::from_bytes_with_nul(unsafe { slice::from_raw_parts(buf_ptr, bytes.len() + 1) }) {
982
582k
        Ok(s) => f(s),
983
2.06k
        Err(_) => Err(io::Errno::INVAL),
984
    }
985
1.25M
}
Unexecuted instantiation: rustix::path::arg::with_c_str::<(), 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::path::arg::with_c_str::<(), rustix::fs::abs::rename<&std::path::Path, &std::path::Path>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str::<(), 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::path::arg::with_c_str::<(), rustix::fs::abs::rename<&std::path::Path, &std::path::Path>::{closure#0}::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str::<(), rustix::backend::fs::syscalls::unlink>
Unexecuted instantiation: rustix::path::arg::with_c_str::<(&mut [u8], &mut [core::mem::maybe_uninit::MaybeUninit<u8>]), rustix::fs::xattr::llistxattr<&std::path::Path, &mut [core::mem::maybe_uninit::MaybeUninit<u8>]>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str::<(&mut [u8], &mut [core::mem::maybe_uninit::MaybeUninit<u8>]), rustix::fs::xattr::getxattr<&std::path::Path, &std::ffi::os_str::OsStr, &mut [core::mem::maybe_uninit::MaybeUninit<u8>]>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str::<(&mut [u8], &mut [core::mem::maybe_uninit::MaybeUninit<u8>]), rustix::fs::xattr::fgetxattr<std::os::fd::owned::BorrowedFd, &std::ffi::os_str::OsStr, &mut [core::mem::maybe_uninit::MaybeUninit<u8>]>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str::<(&mut [u8], &mut [core::mem::maybe_uninit::MaybeUninit<u8>]), rustix::fs::xattr::lgetxattr<&std::path::Path, &std::ffi::os_str::OsStr, &mut [core::mem::maybe_uninit::MaybeUninit<u8>]>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str::<(&mut [u8], &mut [core::mem::maybe_uninit::MaybeUninit<u8>]), rustix::fs::xattr::listxattr<&std::path::Path, &mut [core::mem::maybe_uninit::MaybeUninit<u8>]>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str::<(&mut [u8], &mut [core::mem::maybe_uninit::MaybeUninit<u8>]), rustix::fs::xattr::getxattr<&std::path::Path, &std::ffi::os_str::OsStr, &mut [core::mem::maybe_uninit::MaybeUninit<u8>]>::{closure#0}::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str::<(&mut [u8], &mut [core::mem::maybe_uninit::MaybeUninit<u8>]), rustix::fs::xattr::lgetxattr<&std::path::Path, &std::ffi::os_str::OsStr, &mut [core::mem::maybe_uninit::MaybeUninit<u8>]>::{closure#0}::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str::<usize, rustix::fs::xattr::llistxattr<&std::path::Path, &mut [u8]>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str::<usize, rustix::fs::xattr::getxattr<&std::path::Path, &std::ffi::os_str::OsStr, &mut [u8]>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str::<usize, rustix::fs::xattr::fgetxattr<std::os::fd::owned::BorrowedFd, &std::ffi::os_str::OsStr, &mut [u8]>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str::<usize, rustix::fs::xattr::lgetxattr<&std::path::Path, &std::ffi::os_str::OsStr, &mut [u8]>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str::<usize, rustix::fs::xattr::listxattr<&std::path::Path, &mut [u8]>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str::<usize, rustix::fs::xattr::getxattr<&std::path::Path, &std::ffi::os_str::OsStr, &mut [u8]>::{closure#0}::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str::<usize, rustix::fs::xattr::lgetxattr<&std::path::Path, &std::ffi::os_str::OsStr, &mut [u8]>::{closure#0}::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str::<(), rustix::fs::xattr::removexattr<&std::path::Path, &std::ffi::os_str::OsStr>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str::<(), rustix::fs::xattr::fremovexattr<std::os::fd::owned::BorrowedFd, &std::ffi::os_str::OsStr>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str::<(), rustix::fs::xattr::lremovexattr<&std::path::Path, &std::ffi::os_str::OsStr>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str::<(), rustix::fs::xattr::setxattr<&std::path::Path, &std::ffi::os_str::OsStr>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str::<(), rustix::fs::xattr::fsetxattr<std::os::fd::owned::BorrowedFd, &std::ffi::os_str::OsStr>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str::<(), rustix::fs::xattr::lsetxattr<&std::path::Path, &std::ffi::os_str::OsStr>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str::<(), rustix::fs::xattr::removexattr<&std::path::Path, &std::ffi::os_str::OsStr>::{closure#0}::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str::<(), rustix::fs::xattr::lremovexattr<&std::path::Path, &std::ffi::os_str::OsStr>::{closure#0}::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str::<(), rustix::fs::xattr::setxattr<&std::path::Path, &std::ffi::os_str::OsStr>::{closure#0}::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str::<(), rustix::fs::xattr::lsetxattr<&std::path::Path, &std::ffi::os_str::OsStr>::{closure#0}::{closure#0}>
rustix::path::arg::with_c_str::<std::fs::File, cap_primitives::rustix::linux::fs::open_impl::open_beneath::{closure#0}>
Line
Count
Source
948
877k
fn with_c_str<T, F>(bytes: &[u8], f: F) -> io::Result<T>
949
877k
where
950
877k
    F: FnOnce(&CStr) -> io::Result<T>,
951
{
952
    // Most paths are less than `SMALL_PATH_BUFFER_SIZE` long. The rest can go
953
    // through the dynamic allocation path. If you're opening many files in a
954
    // directory with a long path, consider opening the directory and using
955
    // `openat` to open the files under it, which will avoid this, and is often
956
    // faster in the OS as well.
957
958
    // Test with `>=` so that we have room for the trailing NUL.
959
877k
    if bytes.len() >= SMALL_PATH_BUFFER_SIZE {
960
672k
        return with_c_str_slow_path(bytes, f);
961
205k
    }
962
963
    // Taken from
964
    // <https://github.com/rust-lang/rust/blob/a00f8ba7fcac1b27341679c51bf5a3271fa82df3/library/std/src/sys/common/small_c_string.rs>
965
205k
    let mut buf = MaybeUninit::<[u8; SMALL_PATH_BUFFER_SIZE]>::uninit();
966
205k
    let buf_ptr = buf.as_mut_ptr().cast::<u8>();
967
968
    // This helps test our safety condition below.
969
205k
    debug_assert!(bytes.len() + 1 <= SMALL_PATH_BUFFER_SIZE);
970
971
    // SAFETY: `bytes.len() < SMALL_PATH_BUFFER_SIZE` which means we have space
972
    // for `bytes.len() + 1` `u8`s:
973
205k
    unsafe {
974
205k
        ptr::copy_nonoverlapping(bytes.as_ptr(), buf_ptr, bytes.len());
975
205k
        buf_ptr.add(bytes.len()).write(b'\0');
976
205k
    }
977
978
    // SAFETY: We just wrote the bytes above and they will remain valid for the
979
    // duration of `f` because `buf` doesn't get dropped until the end of the
980
    // function.
981
205k
    match CStr::from_bytes_with_nul(unsafe { slice::from_raw_parts(buf_ptr, bytes.len() + 1) }) {
982
204k
        Ok(s) => f(s),
983
1.50k
        Err(_) => Err(io::Errno::INVAL),
984
    }
985
877k
}
Unexecuted instantiation: rustix::path::arg::with_c_str::<rustix::fs::statx::Statx, rustix::fs::statx::statx<&std::path::Path, &std::fs::File>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str::<rustix::fs::statx::Statx, rustix::fs::statx::statx<&str, std::os::fd::owned::BorrowedFd>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str::<alloc::ffi::c_str::CString, rustix::fs::at::readlinkat<&std::path::Path, &std::fs::File, alloc::vec::Vec<u8>>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str::<rustix::backend::fs::types::Stat, rustix::fs::at::statat<&std::path::Path, &std::fs::File>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str::<rustix::backend::fs::types::Stat, rustix::fs::at::statat<&str, &std::fs::File>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str::<std::os::fd::owned::OwnedFd, rustix::fs::at::openat<&std::path::Path, &std::fs::File>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str::<(), rustix::fs::at::linkat<&std::path::Path, &std::path::Path, &std::fs::File, &std::fs::File>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str::<(), rustix::fs::at::chmodat<&std::path::Path, &std::fs::File>::{closure#0}>
rustix::path::arg::with_c_str::<(), rustix::fs::at::mkdirat<&std::path::Path, &std::fs::File>::{closure#0}>
Line
Count
Source
948
379k
fn with_c_str<T, F>(bytes: &[u8], f: F) -> io::Result<T>
949
379k
where
950
379k
    F: FnOnce(&CStr) -> io::Result<T>,
951
{
952
    // Most paths are less than `SMALL_PATH_BUFFER_SIZE` long. The rest can go
953
    // through the dynamic allocation path. If you're opening many files in a
954
    // directory with a long path, consider opening the directory and using
955
    // `openat` to open the files under it, which will avoid this, and is often
956
    // faster in the OS as well.
957
958
    // Test with `>=` so that we have room for the trailing NUL.
959
379k
    if bytes.len() >= SMALL_PATH_BUFFER_SIZE {
960
874
        return with_c_str_slow_path(bytes, f);
961
378k
    }
962
963
    // Taken from
964
    // <https://github.com/rust-lang/rust/blob/a00f8ba7fcac1b27341679c51bf5a3271fa82df3/library/std/src/sys/common/small_c_string.rs>
965
378k
    let mut buf = MaybeUninit::<[u8; SMALL_PATH_BUFFER_SIZE]>::uninit();
966
378k
    let buf_ptr = buf.as_mut_ptr().cast::<u8>();
967
968
    // This helps test our safety condition below.
969
378k
    debug_assert!(bytes.len() + 1 <= SMALL_PATH_BUFFER_SIZE);
970
971
    // SAFETY: `bytes.len() < SMALL_PATH_BUFFER_SIZE` which means we have space
972
    // for `bytes.len() + 1` `u8`s:
973
378k
    unsafe {
974
378k
        ptr::copy_nonoverlapping(bytes.as_ptr(), buf_ptr, bytes.len());
975
378k
        buf_ptr.add(bytes.len()).write(b'\0');
976
378k
    }
977
978
    // SAFETY: We just wrote the bytes above and they will remain valid for the
979
    // duration of `f` because `buf` doesn't get dropped until the end of the
980
    // function.
981
378k
    match CStr::from_bytes_with_nul(unsafe { slice::from_raw_parts(buf_ptr, bytes.len() + 1) }) {
982
377k
        Ok(s) => f(s),
983
561
        Err(_) => Err(io::Errno::INVAL),
984
    }
985
379k
}
Unexecuted instantiation: rustix::path::arg::with_c_str::<(), rustix::fs::at::accessat<&std::path::Path, &std::fs::File>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str::<(), rustix::fs::at::accessat<&std::ffi::os_str::OsStr, &std::fs::File>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str::<(), rustix::fs::at::renameat<&std::path::Path, &std::path::Path, &std::fs::File, &std::fs::File>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str::<(), rustix::fs::at::unlinkat<&std::path::Path, &std::fs::File>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str::<(), rustix::fs::at::symlinkat<&std::path::Path, &std::path::Path, &std::fs::File>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str::<(), rustix::fs::at::utimensat<&std::path::Path, &std::fs::File>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str::<(), rustix::fs::at::linkat<&std::path::Path, &std::path::Path, &std::fs::File, &std::fs::File>::{closure#0}::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str::<(), rustix::fs::at::renameat<&std::path::Path, &std::path::Path, &std::fs::File, &std::fs::File>::{closure#0}::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str::<(), rustix::fs::at::symlinkat<&std::path::Path, &std::path::Path, &std::fs::File>::{closure#0}::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str::<(), rustix::fs::at::utimensat<&std::path::Path, std::os::fd::owned::BorrowedFd>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str::<std::os::fd::owned::OwnedFd, rustix::fs::at::openat<&[u8], std::os::fd::owned::BorrowedFd>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str::<std::os::fd::owned::OwnedFd, rustix::fs::abs::open<&str>::{closure#0}>
986
987
/// The slow path which handles any length. In theory OS's only support up to
988
/// `PATH_MAX`, but we let the OS enforce that.
989
#[allow(unsafe_code, clippy::int_plus_one)]
990
#[cold]
991
672k
fn with_c_str_slow_path<T, F>(bytes: &[u8], f: F) -> io::Result<T>
992
672k
where
993
672k
    F: FnOnce(&CStr) -> io::Result<T>,
994
{
995
    #[cfg(feature = "alloc")]
996
    {
997
672k
        f(&CString::new(bytes).map_err(|_cstr_err| io::Errno::INVAL)?)
998
    }
999
1000
    #[cfg(not(feature = "alloc"))]
1001
    {
1002
        #[cfg(all(
1003
            libc,
1004
            not(any(
1005
                target_os = "espidf",
1006
                target_os = "horizon",
1007
                target_os = "hurd",
1008
                target_os = "vita",
1009
                target_os = "wasi"
1010
            ))
1011
        ))]
1012
        const LARGE_PATH_BUFFER_SIZE: usize = libc::PATH_MAX as usize;
1013
        #[cfg(linux_raw)]
1014
        const LARGE_PATH_BUFFER_SIZE: usize = linux_raw_sys::general::PATH_MAX as usize;
1015
        #[cfg(any(
1016
            target_os = "espidf",
1017
            target_os = "horizon",
1018
            target_os = "hurd",
1019
            target_os = "vita",
1020
            target_os = "wasi"
1021
        ))]
1022
        const LARGE_PATH_BUFFER_SIZE: usize = 4096 as usize; // TODO: upstream this
1023
1024
        // Taken from
1025
        // <https://github.com/rust-lang/rust/blob/a00f8ba7fcac1b27341679c51bf5a3271fa82df3/library/std/src/sys/common/small_c_string.rs>
1026
        let mut buf = MaybeUninit::<[u8; LARGE_PATH_BUFFER_SIZE]>::uninit();
1027
        let buf_ptr = buf.as_mut_ptr().cast::<u8>();
1028
1029
        // This helps test our safety condition below.
1030
        if bytes.len() + 1 > LARGE_PATH_BUFFER_SIZE {
1031
            return Err(io::Errno::NAMETOOLONG);
1032
        }
1033
1034
        // SAFETY: `bytes.len() < LARGE_PATH_BUFFER_SIZE` which means we have
1035
        // space for `bytes.len() + 1` `u8`s:
1036
        unsafe {
1037
            ptr::copy_nonoverlapping(bytes.as_ptr(), buf_ptr, bytes.len());
1038
            buf_ptr.add(bytes.len()).write(b'\0');
1039
        }
1040
1041
        // SAFETY: We just wrote the bytes above and they will remain valid for
1042
        // the duration of `f` because `buf` doesn't get dropped until the end
1043
        // of the function.
1044
        match CStr::from_bytes_with_nul(unsafe { slice::from_raw_parts(buf_ptr, bytes.len() + 1) })
1045
        {
1046
            Ok(s) => f(s),
1047
            Err(_) => Err(io::Errno::INVAL),
1048
        }
1049
    }
1050
672k
}
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<(), 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::path::arg::with_c_str_slow_path::<(), rustix::fs::abs::rename<&std::path::Path, &std::path::Path>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<(), 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::path::arg::with_c_str_slow_path::<(), rustix::fs::abs::rename<&std::path::Path, &std::path::Path>::{closure#0}::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<(), rustix::backend::fs::syscalls::unlink>
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<(&mut [u8], &mut [core::mem::maybe_uninit::MaybeUninit<u8>]), rustix::fs::xattr::llistxattr<&std::path::Path, &mut [core::mem::maybe_uninit::MaybeUninit<u8>]>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<(&mut [u8], &mut [core::mem::maybe_uninit::MaybeUninit<u8>]), rustix::fs::xattr::getxattr<&std::path::Path, &std::ffi::os_str::OsStr, &mut [core::mem::maybe_uninit::MaybeUninit<u8>]>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<(&mut [u8], &mut [core::mem::maybe_uninit::MaybeUninit<u8>]), rustix::fs::xattr::fgetxattr<std::os::fd::owned::BorrowedFd, &std::ffi::os_str::OsStr, &mut [core::mem::maybe_uninit::MaybeUninit<u8>]>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<(&mut [u8], &mut [core::mem::maybe_uninit::MaybeUninit<u8>]), rustix::fs::xattr::lgetxattr<&std::path::Path, &std::ffi::os_str::OsStr, &mut [core::mem::maybe_uninit::MaybeUninit<u8>]>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<(&mut [u8], &mut [core::mem::maybe_uninit::MaybeUninit<u8>]), rustix::fs::xattr::listxattr<&std::path::Path, &mut [core::mem::maybe_uninit::MaybeUninit<u8>]>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<(&mut [u8], &mut [core::mem::maybe_uninit::MaybeUninit<u8>]), rustix::fs::xattr::getxattr<&std::path::Path, &std::ffi::os_str::OsStr, &mut [core::mem::maybe_uninit::MaybeUninit<u8>]>::{closure#0}::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<(&mut [u8], &mut [core::mem::maybe_uninit::MaybeUninit<u8>]), rustix::fs::xattr::lgetxattr<&std::path::Path, &std::ffi::os_str::OsStr, &mut [core::mem::maybe_uninit::MaybeUninit<u8>]>::{closure#0}::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<usize, rustix::fs::xattr::llistxattr<&std::path::Path, &mut [u8]>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<usize, rustix::fs::xattr::getxattr<&std::path::Path, &std::ffi::os_str::OsStr, &mut [u8]>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<usize, rustix::fs::xattr::fgetxattr<std::os::fd::owned::BorrowedFd, &std::ffi::os_str::OsStr, &mut [u8]>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<usize, rustix::fs::xattr::lgetxattr<&std::path::Path, &std::ffi::os_str::OsStr, &mut [u8]>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<usize, rustix::fs::xattr::listxattr<&std::path::Path, &mut [u8]>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<usize, rustix::fs::xattr::getxattr<&std::path::Path, &std::ffi::os_str::OsStr, &mut [u8]>::{closure#0}::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<usize, rustix::fs::xattr::lgetxattr<&std::path::Path, &std::ffi::os_str::OsStr, &mut [u8]>::{closure#0}::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<(), rustix::fs::xattr::removexattr<&std::path::Path, &std::ffi::os_str::OsStr>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<(), rustix::fs::xattr::fremovexattr<std::os::fd::owned::BorrowedFd, &std::ffi::os_str::OsStr>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<(), rustix::fs::xattr::lremovexattr<&std::path::Path, &std::ffi::os_str::OsStr>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<(), rustix::fs::xattr::setxattr<&std::path::Path, &std::ffi::os_str::OsStr>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<(), rustix::fs::xattr::fsetxattr<std::os::fd::owned::BorrowedFd, &std::ffi::os_str::OsStr>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<(), rustix::fs::xattr::lsetxattr<&std::path::Path, &std::ffi::os_str::OsStr>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<(), rustix::fs::xattr::removexattr<&std::path::Path, &std::ffi::os_str::OsStr>::{closure#0}::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<(), rustix::fs::xattr::lremovexattr<&std::path::Path, &std::ffi::os_str::OsStr>::{closure#0}::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<(), rustix::fs::xattr::setxattr<&std::path::Path, &std::ffi::os_str::OsStr>::{closure#0}::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<(), rustix::fs::xattr::lsetxattr<&std::path::Path, &std::ffi::os_str::OsStr>::{closure#0}::{closure#0}>
rustix::path::arg::with_c_str_slow_path::<std::fs::File, cap_primitives::rustix::linux::fs::open_impl::open_beneath::{closure#0}>
Line
Count
Source
991
672k
fn with_c_str_slow_path<T, F>(bytes: &[u8], f: F) -> io::Result<T>
992
672k
where
993
672k
    F: FnOnce(&CStr) -> io::Result<T>,
994
{
995
    #[cfg(feature = "alloc")]
996
    {
997
672k
        f(&CString::new(bytes).map_err(|_cstr_err| io::Errno::INVAL)?)
998
    }
999
1000
    #[cfg(not(feature = "alloc"))]
1001
    {
1002
        #[cfg(all(
1003
            libc,
1004
            not(any(
1005
                target_os = "espidf",
1006
                target_os = "horizon",
1007
                target_os = "hurd",
1008
                target_os = "vita",
1009
                target_os = "wasi"
1010
            ))
1011
        ))]
1012
        const LARGE_PATH_BUFFER_SIZE: usize = libc::PATH_MAX as usize;
1013
        #[cfg(linux_raw)]
1014
        const LARGE_PATH_BUFFER_SIZE: usize = linux_raw_sys::general::PATH_MAX as usize;
1015
        #[cfg(any(
1016
            target_os = "espidf",
1017
            target_os = "horizon",
1018
            target_os = "hurd",
1019
            target_os = "vita",
1020
            target_os = "wasi"
1021
        ))]
1022
        const LARGE_PATH_BUFFER_SIZE: usize = 4096 as usize; // TODO: upstream this
1023
1024
        // Taken from
1025
        // <https://github.com/rust-lang/rust/blob/a00f8ba7fcac1b27341679c51bf5a3271fa82df3/library/std/src/sys/common/small_c_string.rs>
1026
        let mut buf = MaybeUninit::<[u8; LARGE_PATH_BUFFER_SIZE]>::uninit();
1027
        let buf_ptr = buf.as_mut_ptr().cast::<u8>();
1028
1029
        // This helps test our safety condition below.
1030
        if bytes.len() + 1 > LARGE_PATH_BUFFER_SIZE {
1031
            return Err(io::Errno::NAMETOOLONG);
1032
        }
1033
1034
        // SAFETY: `bytes.len() < LARGE_PATH_BUFFER_SIZE` which means we have
1035
        // space for `bytes.len() + 1` `u8`s:
1036
        unsafe {
1037
            ptr::copy_nonoverlapping(bytes.as_ptr(), buf_ptr, bytes.len());
1038
            buf_ptr.add(bytes.len()).write(b'\0');
1039
        }
1040
1041
        // SAFETY: We just wrote the bytes above and they will remain valid for
1042
        // the duration of `f` because `buf` doesn't get dropped until the end
1043
        // of the function.
1044
        match CStr::from_bytes_with_nul(unsafe { slice::from_raw_parts(buf_ptr, bytes.len() + 1) })
1045
        {
1046
            Ok(s) => f(s),
1047
            Err(_) => Err(io::Errno::INVAL),
1048
        }
1049
    }
1050
672k
}
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<rustix::fs::statx::Statx, rustix::fs::statx::statx<&std::path::Path, &std::fs::File>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<rustix::fs::statx::Statx, rustix::fs::statx::statx<&str, std::os::fd::owned::BorrowedFd>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<alloc::ffi::c_str::CString, rustix::fs::at::readlinkat<&std::path::Path, &std::fs::File, alloc::vec::Vec<u8>>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<rustix::backend::fs::types::Stat, rustix::fs::at::statat<&std::path::Path, &std::fs::File>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<rustix::backend::fs::types::Stat, rustix::fs::at::statat<&str, &std::fs::File>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<std::os::fd::owned::OwnedFd, rustix::fs::at::openat<&std::path::Path, &std::fs::File>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<(), rustix::fs::at::linkat<&std::path::Path, &std::path::Path, &std::fs::File, &std::fs::File>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<(), rustix::fs::at::chmodat<&std::path::Path, &std::fs::File>::{closure#0}>
rustix::path::arg::with_c_str_slow_path::<(), rustix::fs::at::mkdirat<&std::path::Path, &std::fs::File>::{closure#0}>
Line
Count
Source
991
874
fn with_c_str_slow_path<T, F>(bytes: &[u8], f: F) -> io::Result<T>
992
874
where
993
874
    F: FnOnce(&CStr) -> io::Result<T>,
994
{
995
    #[cfg(feature = "alloc")]
996
    {
997
874
        f(&CString::new(bytes).map_err(|_cstr_err| io::Errno::INVAL)?)
998
    }
999
1000
    #[cfg(not(feature = "alloc"))]
1001
    {
1002
        #[cfg(all(
1003
            libc,
1004
            not(any(
1005
                target_os = "espidf",
1006
                target_os = "horizon",
1007
                target_os = "hurd",
1008
                target_os = "vita",
1009
                target_os = "wasi"
1010
            ))
1011
        ))]
1012
        const LARGE_PATH_BUFFER_SIZE: usize = libc::PATH_MAX as usize;
1013
        #[cfg(linux_raw)]
1014
        const LARGE_PATH_BUFFER_SIZE: usize = linux_raw_sys::general::PATH_MAX as usize;
1015
        #[cfg(any(
1016
            target_os = "espidf",
1017
            target_os = "horizon",
1018
            target_os = "hurd",
1019
            target_os = "vita",
1020
            target_os = "wasi"
1021
        ))]
1022
        const LARGE_PATH_BUFFER_SIZE: usize = 4096 as usize; // TODO: upstream this
1023
1024
        // Taken from
1025
        // <https://github.com/rust-lang/rust/blob/a00f8ba7fcac1b27341679c51bf5a3271fa82df3/library/std/src/sys/common/small_c_string.rs>
1026
        let mut buf = MaybeUninit::<[u8; LARGE_PATH_BUFFER_SIZE]>::uninit();
1027
        let buf_ptr = buf.as_mut_ptr().cast::<u8>();
1028
1029
        // This helps test our safety condition below.
1030
        if bytes.len() + 1 > LARGE_PATH_BUFFER_SIZE {
1031
            return Err(io::Errno::NAMETOOLONG);
1032
        }
1033
1034
        // SAFETY: `bytes.len() < LARGE_PATH_BUFFER_SIZE` which means we have
1035
        // space for `bytes.len() + 1` `u8`s:
1036
        unsafe {
1037
            ptr::copy_nonoverlapping(bytes.as_ptr(), buf_ptr, bytes.len());
1038
            buf_ptr.add(bytes.len()).write(b'\0');
1039
        }
1040
1041
        // SAFETY: We just wrote the bytes above and they will remain valid for
1042
        // the duration of `f` because `buf` doesn't get dropped until the end
1043
        // of the function.
1044
        match CStr::from_bytes_with_nul(unsafe { slice::from_raw_parts(buf_ptr, bytes.len() + 1) })
1045
        {
1046
            Ok(s) => f(s),
1047
            Err(_) => Err(io::Errno::INVAL),
1048
        }
1049
    }
1050
874
}
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<(), rustix::fs::at::accessat<&std::path::Path, &std::fs::File>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<(), rustix::fs::at::accessat<&std::ffi::os_str::OsStr, &std::fs::File>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<(), rustix::fs::at::renameat<&std::path::Path, &std::path::Path, &std::fs::File, &std::fs::File>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<(), rustix::fs::at::unlinkat<&std::path::Path, &std::fs::File>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<(), rustix::fs::at::symlinkat<&std::path::Path, &std::path::Path, &std::fs::File>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<(), rustix::fs::at::utimensat<&std::path::Path, &std::fs::File>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<(), rustix::fs::at::linkat<&std::path::Path, &std::path::Path, &std::fs::File, &std::fs::File>::{closure#0}::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<(), rustix::fs::at::renameat<&std::path::Path, &std::path::Path, &std::fs::File, &std::fs::File>::{closure#0}::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<(), rustix::fs::at::symlinkat<&std::path::Path, &std::path::Path, &std::fs::File>::{closure#0}::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<(), rustix::fs::at::utimensat<&std::path::Path, std::os::fd::owned::BorrowedFd>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<std::os::fd::owned::OwnedFd, rustix::fs::at::openat<&[u8], std::os::fd::owned::BorrowedFd>::{closure#0}>
Unexecuted instantiation: rustix::path::arg::with_c_str_slow_path::<std::os::fd::owned::OwnedFd, rustix::fs::abs::open<&str>::{closure#0}>