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

Function with_c_str

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

Source from the content-addressed store, hash-verified

946#[allow(unsafe_code, clippy::int_plus_one)]
947#[inline]
948fn with_c_str<T, F>(bytes: &[u8], f: F) -> io::Result<T>
949where
950 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 if bytes.len() >= SMALL_PATH_BUFFER_SIZE {
960 return with_c_str_slow_path(bytes, f);
961 }
962
963 // Taken from
964 // <https://github.com/rust-lang/rust/blob/a00f8ba7fcac1b27341679c51bf5a3271fa82df3/library/std/src/sys/common/small_c_string.rs>
965 let mut buf = MaybeUninit::<[u8; SMALL_PATH_BUFFER_SIZE]>::uninit();
966 let buf_ptr = buf.as_mut_ptr().cast::<u8>();
967
968 // This helps test our safety condition below.
969 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 unsafe {
974 ptr::copy_nonoverlapping(bytes.as_ptr(), buf_ptr, bytes.len());
975 buf_ptr.add(bytes.len()).write(b'\0');
976 }
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 match CStr::from_bytes_with_nul(unsafe { slice::from_raw_parts(buf_ptr, bytes.len() + 1) }) {
982 Ok(s) => f(s),
983 Err(_) => Err(io::Errno::INVAL),
984 }
985}
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.

Callers 1

into_with_c_strMethod · 0.85

Calls 6

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

Tested by

no test coverage detected