ok nvm *mut was im stupid

This commit is contained in:
do butterflies cry? 2026-03-25 09:47:51 +10:00
parent 648aadf5ab
commit ff28c6f13f
Signed by: cry
GPG key ID: F68745A836CA0412
5 changed files with 103 additions and 80 deletions

View file

@ -22,6 +22,7 @@
// }; // };
use std::ffi::c_uint; use std::ffi::c_uint;
use std::ffi::c_void;
use std::ptr::NonNull; use std::ptr::NonNull;
use super::{NixError, NixideResult}; use super::{NixError, NixideResult};
@ -269,10 +270,16 @@ impl ErrorContext {
/// } /// }
/// ``` /// ```
pub(super) fn get_nix_err_name(&self) -> Option<String> { pub(super) fn get_nix_err_name(&self) -> Option<String> {
#[allow(unused_unsafe)] // XXX: TODO: remove this `unused_unsafe`
unsafe { unsafe {
// NOTE: an Err here only occurs when "Last error was not a nix error" // NOTE: an Err here only occurs when "Last error was not a nix error"
wrap::nix_string_callback!(|callback, userdata: &mut __UserData, ctx: &ErrorContext| { wrap::nix_string_callback!(|callback, userdata: *mut __UserData, ctx: &ErrorContext| {
sys::nix_err_name(ctx.as_ptr(), self.as_ptr(), Some(callback), userdata) sys::nix_err_name(
ctx.as_ptr(),
self.as_ptr(),
Some(callback),
userdata as *mut c_void,
)
}) })
.ok() .ok()
} }
@ -314,10 +321,16 @@ impl ErrorContext {
/// } /// }
/// ``` /// ```
pub(super) fn get_nix_err_info_msg(&self) -> Option<String> { pub(super) fn get_nix_err_info_msg(&self) -> Option<String> {
#[allow(unused_unsafe)] // XXX: TODO: remove this `unused_unsafe`
unsafe { unsafe {
// NOTE: an Err here only occurs when "Last error was not a nix error" // NOTE: an Err here only occurs when "Last error was not a nix error"
wrap::nix_string_callback!(|callback, user_data, ctx: &ErrorContext| { wrap::nix_string_callback!(|callback, userdata, ctx: &ErrorContext| {
sys::nix_err_info_msg(ctx.as_ptr(), self.as_ptr(), Some(callback), user_data) sys::nix_err_info_msg(
ctx.as_ptr(),
self.as_ptr(),
Some(callback),
userdata as *mut c_void,
)
}) })
.ok() .ok()
} }

View file

@ -34,31 +34,3 @@ impl CCharPtrExt for *const c_char {
} }
} }
} }
// XXX: TODO: remove if unused
// pub trait CCharPtrExt {
// fn to_utf8_string(self) -> Result<String, Option<Utf8Error>>;
//
// fn to_utf8_string_n(self, n: usize) -> Result<String, Option<Utf8Error>>;
// }
//
// impl CCharPtrExt for *const c_char {
// fn to_utf8_string(self) -> Result<String, Option<Utf8Error>> {
// if self.is_null() {
// return Err(None);
// }
// let cstr = unsafe { CStr::from_ptr(self) };
// match cstr.to_str() {
// Ok(s) => Ok(s.to_owned()),
// Err(err) => Err(Some(err)),
// }
// }
//
// fn to_utf8_string_n(self, n: usize) -> Result<String, Option<Utf8Error>> {
// if self.is_null() || n == 0 {
// return Err(None);
// }
// let bytes = unsafe { from_raw_parts(self.cast::<u8>(), n as usize) };
// from_utf8(bytes).map(str::to_string).map_err(Some)
// }
// }

View file

@ -162,7 +162,7 @@ impl Store {
})?; })?;
let store_path = StorePath { inner }; let store_path = StorePath { inner };
let callback = userdata.inner; let callback = unsafe { (*userdata).inner };
callback(output_name.as_ref(), &store_path); callback(output_name.as_ref(), &store_path);
Ok((output_name, store_path)) Ok((output_name, store_path))
@ -213,27 +213,43 @@ impl Store {
/// ///
/// If the store doesn't have a version (like the dummy store), returns None /// If the store doesn't have a version (like the dummy store), returns None
pub fn version(&self) -> Result<String, NixideError> { pub fn version(&self) -> Result<String, NixideError> {
wrap::nix_string_callback(|callback, user_data, ctx| unsafe { wrap::nix_string_callback!(
sys::nix_store_get_version(ctx.as_ptr(), self.inner.as_ptr(), Some(callback), user_data) |callback, userdata: *mut __UserData, ctx: &ErrorContext| unsafe {
}) sys::nix_store_get_version(
ctx.as_ptr(),
self.inner.as_ptr(),
Some(callback),
userdata as *mut c_void,
)
}
)
} }
/// Get the URI of a Nix store /// Get the URI of a Nix store
pub fn uri(&self) -> Result<String, NixideError> { pub fn uri(&self) -> Result<String, NixideError> {
wrap::nix_string_callback(|callback, user_data, ctx| unsafe { wrap::nix_string_callback!(
sys::nix_store_get_uri(ctx.as_ptr(), self.inner.as_ptr(), Some(callback), user_data) |callback, userdata: *mut __UserData, ctx: &ErrorContext| unsafe {
}) sys::nix_store_get_uri(
ctx.as_ptr(),
self.inner.as_ptr(),
Some(callback),
userdata as *mut c_void,
)
}
)
} }
pub fn store_dir(&self) -> Result<PathBuf, NixideError> { pub fn store_dir(&self) -> Result<PathBuf, NixideError> {
wrap::nix_pathbuf_callback(|callback, user_data, ctx| unsafe { wrap::nix_pathbuf_callback!(
sys::nix_store_get_storedir( |callback, userdata: *mut __UserData, ctx: &ErrorContext| unsafe {
ctx.as_ptr(), sys::nix_store_get_storedir(
self.inner.as_ptr(), ctx.as_ptr(),
Some(callback), self.inner.as_ptr(),
user_data, Some(callback),
) userdata as *mut c_void,
}) )
}
)
} }
pub fn copy_closure_to( pub fn copy_closure_to(

View file

@ -1,4 +1,4 @@
use std::ffi::CString; use std::ffi::{c_void, CString};
use std::path::PathBuf; use std::path::PathBuf;
use std::ptr::NonNull; use std::ptr::NonNull;
@ -56,8 +56,8 @@ impl StorePath {
/// Returns an error if the name cannot be retrieved. /// Returns an error if the name cannot be retrieved.
/// ///
pub fn name(&self) -> Result<String, NixideError> { pub fn name(&self) -> Result<String, NixideError> {
wrap::nix_string_callback(|callback, user_data, _| unsafe { wrap::nix_string_callback!(|callback, userdata: *mut __UserData, _| unsafe {
sys::nix_store_path_name(self.inner.as_ptr(), Some(callback), user_data); sys::nix_store_path_name(self.inner.as_ptr(), Some(callback), userdata as *mut c_void);
// NOTE: nix_store_path_name doesn't return nix_err, so we force it to return successfully // NOTE: nix_store_path_name doesn't return nix_err, so we force it to return successfully
nix_err_NIX_OK nix_err_NIX_OK
}) })
@ -85,15 +85,17 @@ impl StorePath {
/// * `store` - The store containing the path /// * `store` - The store containing the path
/// ///
pub fn real_path(&self, store: &Store) -> Result<PathBuf, NixideError> { pub fn real_path(&self, store: &Store) -> Result<PathBuf, NixideError> {
wrap::nix_pathbuf_callback(|callback, user_data, ctx| unsafe { wrap::nix_pathbuf_callback!(
sys::nix_store_real_path( |callback, userdata: *mut __UserData, ctx: &ErrorContext| unsafe {
ctx.as_ptr(), sys::nix_store_real_path(
store.inner.as_ptr(), ctx.as_ptr(),
self.as_ptr(), store.inner.as_ptr(),
Some(callback), self.as_ptr(),
user_data, Some(callback),
) userdata as *mut c_void,
}) )
}
)
} }
/// Check if a [StorePath] is valid (i.e. that its corresponding store object /// Check if a [StorePath] is valid (i.e. that its corresponding store object

View file

@ -11,6 +11,22 @@ impl<S, T> AsMut<UserData<S, T>> for UserData<S, T> {
} }
} }
// pub(crate) trait VoidPtrIsomorphism {
// fn as_void_ptr(self) -> *mut c_void;
// fn from_void_ptr(ptr: *mut c_void) -> Self;
// }
// impl<S, T> VoidPtrIsomorphism for *mut UserData<S, T> {
// fn as_void_ptr(self) -> *mut c_void {
// self as *mut c_void
// }
// fn from_void_ptr(ptr: *mut c_void) -> Self {
// ptr as Self
// }
// }
impl<S, T> UserData<S, T> { impl<S, T> UserData<S, T> {
/// # Warning /// # Warning
/// ///
@ -46,6 +62,8 @@ macro_rules! nonnull {
} }
}}; }};
} }
use std::ffi::c_void;
pub(crate) use nonnull; pub(crate) use nonnull;
macro_rules! nix_fn { macro_rules! nix_fn {
@ -80,6 +98,7 @@ macro_rules! __nix_callback {
__return __return
}}; }};
} }
#[allow(unused_imports)] // XXX: TODO: replace the tail of `nix_callback!` with this macro
pub(crate) use __nix_callback; pub(crate) use __nix_callback;
/// `libnix` functions consistently either expect the `userdata`/`user_data` (inconsistently named in the API...) /// `libnix` functions consistently either expect the `userdata`/`user_data` (inconsistently named in the API...)
@ -95,36 +114,37 @@ macro_rules! nix_callback {
( | $( $($pre:ident : $pre_ty:ty),+ $(,)? )? ; $userdata:ident : $userdata_type:ty ; $( $($post:ident : $post_ty:ty),+ $(,)? )? | -> $ret:ty $body:block, $function:expr $(,)? ) => {{ ( | $( $($pre:ident : $pre_ty:ty),+ $(,)? )? ; $userdata:ident : $userdata_type:ty ; $( $($post:ident : $post_ty:ty),+ $(,)? )? | -> $ret:ty $body:block, $function:expr $(,)? ) => {{
type __UserData = $crate::util::wrap::UserData<$userdata_type, $ret>; type __UserData = $crate::util::wrap::UserData<$userdata_type, $ret>;
// create a function item that wraps the closure body (so it has a concrete type) // create a function item that wraps the closure body (so it has a concrete type)
#[allow(unused_variables)]
unsafe extern "C" fn __captured_fn( unsafe extern "C" fn __captured_fn(
$($( $pre: $pre_ty, )*)? $($( $pre: $pre_ty, )*)?
$userdata: &mut __UserData, $userdata: *mut __UserData,
$($( $post: $post_ty, )*)? $($( $post: $post_ty, )*)?
) -> $ret $body ) -> $ret { $body }
unsafe extern "C" fn __wrapper_callback( unsafe extern "C" fn __wrapper_callback(
$($( $pre: $pre_ty, )*)? $($( $pre: $pre_ty, )*)?
$userdata: &mut __UserData, $userdata: *mut ::std::ffi::c_void,
$($( $post: $post_ty, )*)? $($( $post: $post_ty, )*)?
) { ) {
let stored_retval = &raw mut $userdata.retval;
let retval = unsafe {
__captured_fn(
$($( $pre, )*)?
$userdata,
$($( $post, )*)?
)
};
unsafe { unsafe {
let userdata_ = $userdata as *mut __UserData;
let stored_retval = &raw mut (*userdata_).retval;
let retval =
__captured_fn(
$($( $pre, )*)?
userdata_,
$($( $post, )*)?
);
stored_retval.write(retval) stored_retval.write(retval)
}; }
} }
let mut __ctx: $crate::errors::ErrorContext = $crate::errors::ErrorContext::new(); let mut __ctx: $crate::errors::ErrorContext = $crate::errors::ErrorContext::new();
let mut __state: ::std::mem::MaybeUninit<__UserData> = ::std::mem::MaybeUninit::uninit(); let mut __state: ::std::mem::MaybeUninit<__UserData> = ::std::mem::MaybeUninit::zeroed();
$function(__wrapper_callback, &mut __state, &__ctx); $function(__wrapper_callback, __state.as_mut_ptr(), &__ctx);
__ctx.pop().and_then(|_| unsafe { __state.assume_init().retval }) __ctx.pop().and_then(|_| unsafe { __state.assume_init().retval })
}}; }};
@ -133,20 +153,20 @@ pub(crate) use nix_callback;
// XXX: TODO: convert these to declarative macros // XXX: TODO: convert these to declarative macros
macro_rules! nix_string_callback { macro_rules! nix_string_callback {
($callback:expr $(,)?) => {{ ($function:expr $(,)?) => {{
$crate::util::wrap::nix_callback!( $crate::util::wrap::nix_callback!(
|start: *const ::std::ffi::c_char, n: ::std::ffi::c_uint; userdata: ();| -> $crate::NixideResult<String> { |start: *const ::std::ffi::c_char, n: ::std::ffi::c_uint; userdata: ();| -> $crate::NixideResult<String> {
start.to_utf8_string_n(n as usize) $crate::stdext::CCharPtrExt::to_utf8_string_n(start, n as usize)
}, },
$callback $function
) )
}}; }};
} }
pub(crate) use nix_string_callback; pub(crate) use nix_string_callback;
macro_rules! nix_pathbuf_callback { macro_rules! nix_pathbuf_callback {
($callback:expr $(,)?) => {{ ($function:expr $(,)?) => {{
$crate::util::wrap::nix_string_callback!($callback).map(::std::path::PathBuf::from) $crate::util::wrap::nix_string_callback!($function).map(::std::path::PathBuf::from)
}}; }};
} }
pub(crate) use nix_pathbuf_callback; pub(crate) use nix_pathbuf_callback;