Mercurial > crates > nonstick
view libpam-sys/libpam-sys-helpers/build.rs @ 141:a508a69c068a
Remove a lot of Results from functions.
Many functions are documented to only return failing Results when given
improper inputs or when there is a memory allocation failure (which
can be verified by looking at the source). In cases where we know our
input is correct, we don't need to check for memory allocation errors
for the same reason that Rust doesn't do so when you, e.g., create a
new Vec.
author | Paul Fisher <paul@pfish.zone> |
---|---|
date | Sat, 05 Jul 2025 17:16:56 -0400 |
parents | efbc235f01d3 |
children | 4b3a5095f68c |
line wrap: on
line source
#![allow(unexpected_cfgs)] use std::ffi::{c_void, CString}; use std::ptr::NonNull; use std::{env, fs}; include!("src/pam_impl.rs"); fn main() { let pam_impl = match option_env!("LIBPAMSYS_IMPL") { // The default option: Guess what PAM impl we're using based on OS. None | Some("") => LibPam::detect(), Some(other) => match PamImpl::try_from(other) { Ok(i) => i, Err(_) => { panic!( "unknown PAM implementation {other:?}. valid LIBPAMSYS_IMPLs are {:?}, or unset to detect", PamImpl::items() ) } }, }; let impl_str = format!("{pam_impl:?}"); println!("{}", generate_cfg(&impl_str)); // We set this environment variable to substitute into docstrings. println!("cargo:rustc-env=LIBPAMSYS_IMPL={impl_str}"); fs::write( format!("{}/pam_impl_const.rs", env::var("OUT_DIR").unwrap()), generate_consts(&impl_str), ) .unwrap(); } fn generate_consts(impl_str: &str) -> String { format!( "\ impl PamImpl {{ /// The implementation of libpam this was built for (`{impl_str}`). pub const CURRENT: Self = Self::{impl_str}; }} /// String name of [`PamImpl::CURRENT`], for substituting into docs. #[macro_export] macro_rules! pam_impl_name {{ () => ({impl_str:?}) }} " ) } struct LibPam(NonNull<c_void>); impl LibPam { fn detect() -> PamImpl { if let Some(lib) = Self::open() { if lib.has("pam_syslog") { return PamImpl::LinuxPam; } else if lib.has("_openpam_log") { return PamImpl::OpenPam; } else if lib.has("__pam_get_authtok") { return PamImpl::Sun; } } if cfg!(target_os = "linux") { PamImpl::LinuxPam } else if cfg!(any( target_os = "macos", target_os = "freebsd", target_os = "netbsd", target_os = "dragonfly", target_os = "openbsd", )) { PamImpl::OpenPam } else if cfg!(any(target_os = "illumos", target_os = "solaris")) { PamImpl::Sun } else { PamImpl::XSso } } fn open() -> Option<Self> { NonNull::new(unsafe { libc::dlopen(b"libpam.so\0".as_ptr().cast(), libc::RTLD_LAZY) }) .map(Self) } fn has(&self, name: &str) -> bool { let name = CString::new(name).unwrap(); let symbol = unsafe { libc::dlsym(self.0.as_ptr(), name.as_ptr()) }; !symbol.is_null() } } impl Drop for LibPam { fn drop(&mut self) { unsafe { libc::dlclose(self.0.as_ptr()); } } }