use super::*;
pub trait PwdGrpString: SealedString + Deref {}
impl PwdGrpString for Box<str> {}
impl PwdGrpString for Box<[u8]> {}
impl PwdGrpString for String {}
impl PwdGrpString for Vec<u8> {}
impl PwdGrpProvider for PwdGrp {}
define_derive_deftly! {
Blank for struct, expect items:
impl<S: Default> $tname<S> {
pub fn blank() -> Self {
Self { $( ${select1 fmeta(dummy) {
$fname: NonExhaustive {},
} else {
$fname: Default::default(),
}})}
}
}
}
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Default)]
#[allow(clippy::exhaustive_structs)] pub struct PwdGrp;
macro_rules! define_generic_entrypoint {
{
fn $getfoobar:ident($key:ident: $keytype:ty) -> $out:ty;
} => { define_generic_entrypoint! {
fn $getfoobar($key: $keytype, $keytype; ) -> $out { }
} };
{
fn $getfoobar:ident($key:ident) -> $out:ty;
} => { define_generic_entrypoint! {
fn $getfoobar(
$key:
impl AsRef<str>,
impl AsRef<<S as Deref>::Target>;
.as_ref()
) -> $out {
let $key: &[u8] = <S as SealedString>::as_u8($key.as_ref());
}
} };
{
fn $getfoobar:ident(
$key:ident:
$ktsim:ty,
$ktgen:ty;
$( $k_as_ref:tt )*
) -> $out:ty {
$( $bind_key:tt )*
}
} => { paste!{
#[doc = stringify!([< $out:lower >])]
#[doc = concat!(stringify!([< $key >]), ",")]
fn $getfoobar<S: PwdGrpString>(
&self,
$key: $ktgen,
) -> io::Result<Option<$out<S>>> {
$( $bind_key )*
let value = {
if let Some(mock) = self.with_mocks(|data| {
data.0.[< $out:lower >].iter().find(|ent| {
$key == ent.$key $( $k_as_ref )*
}).cloned().into()
}) {
mock
} else {
[< $getfoobar _inner >](RealLibc, $key)?
}
};
value
.map(|v| $out::<S>::try_convert_from(v, ""))
.transpose()
.map_err(<S as SealedString>::handle_error_as_io)
}
} };
}
macro_rules! define_getid_wrapper { {
$fn:ident: $id:ident. $f:ident, $doc:literal $( $real:literal )?
} => { define_getid_wrapper! {
@ $fn: $id, $doc $($real)?,
Id,
|mock: mock::RealEffectiveSavedIds| mock.$f,
} }; {
$fn:ident: $id:ident. ($( $f:ident )*), $doc:literal $( $real:literal )?
} => { define_getid_wrapper! {
@ $fn: $id, $doc $($real)?,
(Id, Id, Id),
|mock: mock::RealEffectiveSavedIds| ( $( mock.$f, )* ),
} }; {
@ $fn:ident: $id:ident, $doc:literal $( $want_real_warn:literal )?,
$ret:ty,
$if_mock:expr,
} => { paste!{
#[doc = $doc]
#[doc = $doc]
$(
#[doc = $want_real_warn]
)?
fn $fn(&self) -> $ret {
match self.with_mocks(|data| data.0.[< $id s >]) {
Some(mock) => ($if_mock)(mock),
None => [<$fn _inner>](RealLibc),
}
}
} } }
macro_rules! for_getid_wrappers { { $call:ident } => {
$call! { getuid: uid. r, "(real) uid" ""}
$call! { geteuid: uid. e, "effective uid"}
if_cfg_getresuid! {
$call! { getresuid: uid. (r e s), "real, effective and saved set-uid" ""}
}
$call! { getgid: gid. r, "(real) gid" ""}
$call! { getegid: gid. e, "effective gid"}
if_cfg_getresuid! {
$call! { getresgid: gid. (r e s), "real, effective and saved set-gid" ""}
}
} }
pub trait PwdGrpProvider: SealedProvider {
define_generic_entrypoint! { fn getpwnam(name) -> Passwd; }
define_generic_entrypoint! { fn getpwuid(uid: Id) -> Passwd; }
define_generic_entrypoint! { fn getgrnam(name) -> Group; }
define_generic_entrypoint! { fn getgrgid(gid: Id) -> Group; }
for_getid_wrappers! { define_getid_wrapper }
fn getgroups(&self) -> io::Result<Vec<Id>> {
if let Some(mock) =
self.with_mocks(|data| data.0.supplementary_groups.clone())
{
return Ok(mock);
}
getgroups_inner(RealLibc)
}
}