MCPcopy Create free account
hub / github.com/bytecodealliance/rustix / with_c_str_slow_path

Function with_c_str_slow_path

src/path/arg.rs:991–1050  ·  view source on GitHub ↗
(bytes: &[u8], f: F)

Source from the content-addressed store, hash-verified

989#[allow(unsafe_code, clippy::int_plus_one)]
990#[cold]
991fn with_c_str_slow_path<T, F>(bytes: &[u8], f: F) -> io::Result<T>
992where
993 F: FnOnce(&CStr) -> io::Result<T>,
994{
995 #[cfg(feature = "alloc")]
996 {
997 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 }

Callers 1

with_c_strFunction · 0.85

Calls 5

fFunction · 0.85
addMethod · 0.80
as_mut_ptrMethod · 0.45
lenMethod · 0.45
as_ptrMethod · 0.45

Tested by

no test coverage detected