mod helper;
mod keychain;
mod launchd;
mod preferences;
mod ps;
pub(crate) use super::unix::{fs, proc, user};
use super::administered::{self, Administered};
use super::unix::service;
use super::{Elevation, Host, LoginPath, Os, Process, Scheduler};
use crate::context::{Context, Environment};
use crate::store::{PlainFile, RawStore};
use std::path::PathBuf;
use std::sync::Arc;
pub(super) const OS: Os = Os::MacOs;
pub(super) const SPAWN_FLAGS: libc::c_short =
0x0400 | libc::POSIX_SPAWN_CLOEXEC_DEFAULT as libc::c_short;
pub(super) fn login_path(env: &Environment) -> LoginPath {
super::unix::shell::login_path(env, SPAWN_FLAGS)
}
fn vault_account(ctx: &Context) -> String {
crate::provider::claude::slot::account_name(ctx)
}
#[derive(Debug)]
struct MacOs {
scheduler: launchd::Launchd,
}
impl Host for MacOs {
fn foreign_secrets(&self, ctx: &Context, account: &str) -> Option<Box<dyn RawStore>> {
Some(Box::new(keychain::Keychain::foreign(
ctx,
account.to_string(),
)))
}
fn file(&self, path: PathBuf) -> Box<dyn RawStore> {
Box::new(PlainFile::at(path))
}
fn vault(&self, ctx: &Context) -> Box<dyn RawStore> {
Box::new(keychain::Keychain::vault(ctx))
}
fn vault_is_shared(&self) -> bool {
true
}
fn processes(&self, program: &str) -> Option<Vec<Process>> {
ps::processes(program)
}
fn scheduler(&self) -> Option<&dyn Scheduler> {
Some(&self.scheduler)
}
fn elevation(&self, ctx: &Context) -> Elevation {
user::elevation(ctx.sudo())
}
fn managed_preference(&self, domain: &str, key: &str) -> Administered {
if administered::READ_BY_REAL_HOSTS {
preferences::forced(domain, key)
} else {
Administered::Unset
}
}
}
pub(super) fn host() -> Arc<dyn Host> {
Arc::new(MacOs {
scheduler: launchd::Launchd::new(service::system()),
})
}
pub(super) fn current_program() -> std::io::Result<PathBuf> {
std::env::current_exe()
}
#[cfg(any(test, feature = "test-support"))]
pub(super) fn pretend_scheduler(
refuse_start: Arc<std::sync::atomic::AtomicBool>,
) -> Option<Box<dyn Scheduler>> {
Some(Box::new(launchd::Launchd::new(Arc::new(
service::Pretend { refuse_start },
))))
}