Skip to main content

running_process/cleanup/
instances.rs

1use std::path::PathBuf;
2
3/// One broker instance discovered from the local pipe namespace.
4#[derive(Debug, Clone, PartialEq, Eq)]
5pub struct BrokerInstance {
6    /// Filesystem path or named pipe string.
7    pub path: String,
8}
9
10/// Enumerate broker v1 instances visible to the current user.
11pub fn list() -> Vec<BrokerInstance> {
12    // Enumeration here means reading a directory, so it only means anything
13    // where an endpoint has a name in the filesystem. Asking the transport
14    // rather than the host also keeps this honest about *why* the Windows
15    // answer is empty: not because it is Windows, but because there is no
16    // directory to read. Enumerating the named-pipe namespace directly lands
17    // with the broker binary in Phase 4.
18    if !crate::platform::ipc::endpoint_is_filesystem_backed() {
19        return Vec::new();
20    }
21    {
22        instance_dirs()
23            .into_iter()
24            .flat_map(|dir| {
25                std::fs::read_dir(dir)
26                    .into_iter()
27                    .flat_map(|rd| rd.flatten())
28                    .filter_map(|entry| {
29                        let path = entry.path();
30                        let name = path.file_name()?.to_string_lossy();
31                        if name.starts_with("rpb-v1-") && name.ends_with(".sock") {
32                            Some(BrokerInstance {
33                                path: path.to_string_lossy().into_owned(),
34                            })
35                        } else {
36                            None
37                        }
38                    })
39                    .collect::<Vec<_>>()
40            })
41            .collect()
42    }
43}
44
45/// Render `running-process-cleanup instances --json`.
46pub fn render_json(instances: &[BrokerInstance]) -> String {
47    let body = instances
48        .iter()
49        .map(|instance| {
50            format!(
51                "{{\"path\":\"{}\"}}",
52                crate::cleanup::json_escape(&instance.path)
53            )
54        })
55        .collect::<Vec<_>>()
56        .join(",");
57    format!("{{\"schema_version\":1,\"instances\":[{body}]}}")
58}
59
60/// Directories a filesystem-backed broker endpoint may live in.
61fn instance_dirs() -> Vec<PathBuf> {
62    let mut dirs = Vec::new();
63    if let Some(runtime) = crate::env_vars::XDG_RUNTIME_DIR.path() {
64        dirs.push(runtime.join("running-process").join("broker"));
65    }
66    dirs.push(std::env::temp_dir());
67    dirs
68}