From 36cc66666f7fef4578aff61f2161a97a32306f1d Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Fri, 20 Mar 2026 20:41:14 +0000 Subject: [PATCH] fix: resolve nested IPC socket collisions for instantwmctl Update `src/ipc/mod.rs` to dynamically find an available socket path (e.g. `/tmp/instantwm-{uid}-{i}.sock`) rather than blindly removing and overwriting the default socket. This allows nested instances of the window manager to maintain their own IPC socket. Update `src/bin/ctl/ipc.rs` to prioritize the `INSTANTWM_SOCKET` environment variable when connecting, ensuring `instantwmctl` connects to the appropriate nested instance when spawned from it. Co-authored-by: paperbenni <15818888+paperbenni@users.noreply.github.com> --- src/bin/ctl/ipc.rs | 3 +++ src/ipc/mod.rs | 29 ++++++++++++++++++++--------- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/bin/ctl/ipc.rs b/src/bin/ctl/ipc.rs index d3db4e80..568e0934 100644 --- a/src/bin/ctl/ipc.rs +++ b/src/bin/ctl/ipc.rs @@ -64,5 +64,8 @@ impl std::fmt::Display for IpcError { impl std::error::Error for IpcError {} pub fn get_default_socket() -> String { + if let Ok(val) = std::env::var("INSTANTWM_SOCKET") { + return val; + } format!("/tmp/instantwm-{}.sock", unsafe { libc::geteuid() }) } diff --git a/src/ipc/mod.rs b/src/ipc/mod.rs index 0ef03bd7..c17212d9 100644 --- a/src/ipc/mod.rs +++ b/src/ipc/mod.rs @@ -23,10 +23,7 @@ pub struct IpcServer { impl IpcServer { pub fn bind() -> std::io::Result { - let path = socket_path(); - if path.exists() { - let _ = fs::remove_file(&path); - } + let path = get_available_socket_path(); let listener = UnixListener::bind(&path)?; listener.set_nonblocking(true)?; unsafe { std::env::set_var("INSTANTWM_SOCKET", &path) }; @@ -112,12 +109,26 @@ impl std::os::unix::io::AsRawFd for IpcServer { } } -fn socket_path() -> PathBuf { - if let Ok(p) = std::env::var("INSTANTWM_SOCKET") { - return PathBuf::from(p); - } +fn get_available_socket_path() -> PathBuf { let uid = unsafe { libc::geteuid() }; - PathBuf::from(format!("/tmp/instantwm-{}.sock", uid)) + let mut i = 0; + loop { + let path = if i == 0 { + PathBuf::from(format!("/tmp/instantwm-{}.sock", uid)) + } else { + PathBuf::from(format!("/tmp/instantwm-{}-{}.sock", uid, i)) + }; + + if path.exists() { + if UnixStream::connect(&path).is_ok() { + i += 1; + continue; + } else { + let _ = fs::remove_file(&path); + } + } + return path; + } } fn send_response(stream: &mut UnixStream, response: &Response) -> std::io::Result<()> {