use std::collections::HashMap;
use std::env;
use std::path::PathBuf;
use std::os::unix::process::CommandExt;
use std::process::{Command, Stdio};
use crate::path_ext::IsExecutable;
use crate::provider::{Provider, run_provider};
pub struct BinProvider;
impl Provider for BinProvider {
type Item = PathBuf;
fn title(&self) -> &str {
"run"
}
fn collect(&self) -> HashMap<String, PathBuf> {
let paths = env::var_os("PATH")
.map(|p| env::split_paths(&p).collect::<Vec<_>>())
.unwrap_or_default();
let mut binaries = HashMap::new();
for dir in &paths {
let Ok(entries) = dir.read_dir() else {
continue;
};
for entry in entries.flatten() {
let path = entry.path();
if path.is_executable()
&& let Some(name) = path.file_name().and_then(|f| f.to_str())
{
binaries.entry(name.to_string()).or_insert(path);
}
}
}
binaries
}
fn launch(&self, item: &PathBuf) {
unsafe {
Command::new(item)
.stdin(Stdio::null())
.stdout(Stdio::null())
.stderr(Stdio::null())
.pre_exec(|| {
libc::setsid();
Ok(())
})
.spawn().ok();
}
}
}
pub fn run() -> i32 {
run_provider(BinProvider)
}