mirror of
https://github.com/nushell/nushell.git
synced 2025-08-09 08:55:40 +02:00
Port unsafe_op_in_unsafe_fn
fix to FreeBSD (#16275)
Same general idea as https://github.com/nushell/nushell/pull/16266 Fixes the 2024 edition [`unsafe_op_in_unsafe_fn`](https://doc.rust-lang.org/nightly/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html) lint for FreeBSD as well Add safety comments to both implementations and an assertion before `MaybeUninit::assume_init`
This commit is contained in:
committed by
GitHub
parent
28a796d5cb
commit
00ac34d716
@ -213,19 +213,39 @@ fn get_proc_args(pid: i32) -> io::Result<Vec<u8>> {
|
||||
}
|
||||
}
|
||||
|
||||
// For getting simple values from the sysctl interface
|
||||
/// For getting simple values from the sysctl interface
|
||||
///
|
||||
/// # Safety
|
||||
/// `T` needs to be of the structure that is expected to be returned by `sysctl` for the given
|
||||
/// `ctl_name` sequence and will then be assumed to be of correct layout.
|
||||
/// Thus only use it for primitive types or well defined fixed size types. For variable length
|
||||
/// arrays that can be returned from `sysctl` use it directly (or write a proper wrapper handling
|
||||
/// capacity management)
|
||||
///
|
||||
/// # Panics
|
||||
/// If the size of the returned data diverges from the size of the expected `T`
|
||||
unsafe fn get_ctl<T>(ctl_name: &[i32]) -> io::Result<T> {
|
||||
let mut value: MaybeUninit<T> = MaybeUninit::uninit();
|
||||
let mut value_len = mem::size_of_val(&value);
|
||||
check(sysctl(
|
||||
ctl_name.as_ptr(),
|
||||
ctl_name.len() as u32,
|
||||
value.as_mut_ptr() as *mut libc::c_void,
|
||||
&mut value_len,
|
||||
ptr::null(),
|
||||
0,
|
||||
))?;
|
||||
Ok(value.assume_init())
|
||||
// SAFETY: lengths to the pointers is provided, uninitialized data with checked length provided
|
||||
// Only assume initialized when the written data doesn't diverge in length, layout is the
|
||||
// safety responsibility of the caller.
|
||||
check(unsafe {
|
||||
sysctl(
|
||||
ctl_name.as_ptr(),
|
||||
ctl_name.len() as u32,
|
||||
value.as_mut_ptr() as *mut libc::c_void,
|
||||
&mut value_len,
|
||||
ptr::null(),
|
||||
0,
|
||||
)
|
||||
})?;
|
||||
assert_eq!(
|
||||
value_len,
|
||||
mem::size_of_val(&value),
|
||||
"Data requested from from `sysctl` diverged in size from the expected return type. For variable length data you need to manually truncate the data to the valid returned size!"
|
||||
);
|
||||
Ok(unsafe { value.assume_init() })
|
||||
}
|
||||
|
||||
fn get_pagesize() -> io::Result<libc::c_int> {
|
||||
|
@ -93,7 +93,15 @@ fn check(err: libc::c_int) -> std::io::Result<()> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Call `sysctl()` in read mode (i.e. the last two arguments are NULL and zero)
|
||||
/// Call `sysctl()` in read mode (i.e. the last two arguments to set new values are NULL and zero)
|
||||
///
|
||||
/// `name` is a flag array.
|
||||
///
|
||||
/// # Safety
|
||||
/// `data` needs to be writable for `data_len` or be a `ptr::null()` paired with `data_len = 0` to
|
||||
/// poll for the expected length in the `data_len` out parameter.
|
||||
///
|
||||
/// For more details see: https://man.netbsd.org/sysctl.3
|
||||
unsafe fn sysctl_get(
|
||||
name: *const i32,
|
||||
name_len: u32,
|
||||
@ -250,20 +258,37 @@ fn get_proc_args(pid: i32, what: i32) -> io::Result<Vec<u8>> {
|
||||
}
|
||||
}
|
||||
|
||||
// For getting simple values from the sysctl interface
|
||||
/// For getting simple values from the sysctl interface
|
||||
///
|
||||
/// # Safety
|
||||
/// `T` needs to be of the structure that is expected to be returned by `sysctl` for the given
|
||||
/// `ctl_name` sequence and will then be assumed to be of correct layout.
|
||||
/// Thus only use it for primitive types or well defined fixed size types. For variable length
|
||||
/// arrays that can be returned from `sysctl` use it directly (or write a proper wrapper handling
|
||||
/// capacity management)
|
||||
///
|
||||
/// # Panics
|
||||
/// If the size of the returned data diverges from the size of the expected `T`
|
||||
unsafe fn get_ctl<T>(ctl_name: &[i32]) -> io::Result<T> {
|
||||
// Safety: Call to unsafe function `netbsd::sysctl_get`
|
||||
unsafe {
|
||||
let mut value: MaybeUninit<T> = MaybeUninit::uninit();
|
||||
let mut value_len = mem::size_of_val(&value);
|
||||
check(sysctl_get(
|
||||
let mut value: MaybeUninit<T> = MaybeUninit::uninit();
|
||||
let mut value_len = mem::size_of_val(&value);
|
||||
// SAFETY: lengths to the pointers is provided, uninitialized data with checked length provided
|
||||
// Only assume initialized when the written data doesn't diverge in length, layout is the
|
||||
// safety responsibility of the caller.
|
||||
check(unsafe {
|
||||
sysctl_get(
|
||||
ctl_name.as_ptr(),
|
||||
ctl_name.len() as u32,
|
||||
value.as_mut_ptr() as *mut libc::c_void,
|
||||
&mut value_len,
|
||||
))?;
|
||||
Ok(value.assume_init())
|
||||
}
|
||||
)
|
||||
})?;
|
||||
assert_eq!(
|
||||
value_len,
|
||||
mem::size_of_val(&value),
|
||||
"Data requested from from `sysctl` diverged in size from the expected return type. For variable length data you need to manually truncate the data to the valid returned size!"
|
||||
);
|
||||
Ok(unsafe { value.assume_init() })
|
||||
}
|
||||
|
||||
fn get_pagesize() -> io::Result<libc::c_int> {
|
||||
|
Reference in New Issue
Block a user