view src/memory.rs @ 62:d83623951070

Further improve docs and put `conv` behind a feature gate.
author Paul Fisher <paul@pfish.zone>
date Wed, 21 May 2025 23:10:09 -0400
parents 05cc2c27334f
children bbe84835d6db
line wrap: on
line source

//! Utility functions for dealing with memory copying and stuff.

use crate::ErrorCode;
use libc::c_char;
use std::ffi::{CStr, CString};

/// Safely converts a `&str` option to a `CString` option.
pub fn option_cstr(prompt: Option<&str>) -> crate::Result<Option<CString>> {
    prompt
        .map(CString::new)
        .transpose()
        .map_err(|_| ErrorCode::ConversationError)
}

/// Gets the pointer to the given CString, or a null pointer if absent.
pub fn prompt_ptr(prompt: Option<&CString>) -> *const c_char {
    match prompt {
        Some(c_str) => c_str.as_ptr(),
        None => std::ptr::null(),
    }
}

/// Creates an owned copy of a string that is returned from a
/// <code>pam_get_<var>whatever</var></code> function.
pub fn copy_pam_string(result_ptr: *const c_char) -> crate::Result<String> {
    // We really shouldn't get a null pointer back here, but if we do, return nothing.
    if result_ptr.is_null() {
        return Ok(String::new());
    }
    let bytes = unsafe { CStr::from_ptr(result_ptr) };
    bytes
        .to_str()
        .map(String::from)
        .map_err(|_| ErrorCode::ConversationError)
}