linux: Use filesystem based unix socket instead of abstract namespace (#12756)

Release Notes:

- N/A

fixes: unable to launch multiple zed instances even if the support dirs
are different(example: bwrap based sandboxing)
This commit is contained in:
maan2003 2024-06-12 06:47:07 +05:30 committed by GitHub
parent e16bbe048f
commit b82350979f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 14 additions and 16 deletions

1
Cargo.lock generated
View File

@ -2150,7 +2150,6 @@ dependencies = [
"exec", "exec",
"fork", "fork",
"ipc-channel", "ipc-channel",
"libc",
"once_cell", "once_cell",
"plist", "plist",
"release_channel", "release_channel",

View File

@ -19,7 +19,6 @@ path = "src/main.rs"
[dependencies] [dependencies]
anyhow.workspace = true anyhow.workspace = true
clap.workspace = true clap.workspace = true
libc.workspace = true
ipc-channel = "0.18" ipc-channel = "0.18"
once_cell.workspace = true once_cell.workspace = true
release_channel.workspace = true release_channel.workspace = true

View File

@ -161,10 +161,7 @@ mod linux {
env, env,
ffi::OsString, ffi::OsString,
io, io,
os::{ os::unix::net::{SocketAddr, UnixDatagram},
linux::net::SocketAddrExt,
unix::net::{SocketAddr, UnixDatagram},
},
path::{Path, PathBuf}, path::{Path, PathBuf},
process::{self, ExitStatus}, process::{self, ExitStatus},
thread, thread,
@ -175,6 +172,7 @@ mod linux {
use cli::FORCE_CLI_MODE_ENV_VAR_NAME; use cli::FORCE_CLI_MODE_ENV_VAR_NAME;
use fork::Fork; use fork::Fork;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use util::paths;
use crate::{Detect, InstalledApp}; use crate::{Detect, InstalledApp};
@ -223,12 +221,9 @@ mod linux {
} }
fn launch(&self, ipc_url: String) -> anyhow::Result<()> { fn launch(&self, ipc_url: String) -> anyhow::Result<()> {
let uid: u32 = unsafe { libc::getuid() }; let sock_path = paths::SUPPORT_DIR.join(format!("zed-{}.sock", *RELEASE_CHANNEL));
let sock_addr =
SocketAddr::from_abstract_name(format!("zed-{}-{}", *RELEASE_CHANNEL, uid))?;
let sock = UnixDatagram::unbound()?; let sock = UnixDatagram::unbound()?;
if sock.connect_addr(&sock_addr).is_err() { if sock.connect(&sock_path).is_err() {
self.boot_background(ipc_url)?; self.boot_background(ipc_url)?;
} else { } else {
sock.send(ipc_url.as_bytes())?; sock.send(ipc_url.as_bytes())?;

View File

@ -112,12 +112,17 @@ impl OpenListener {
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
pub fn listen_for_cli_connections(opener: OpenListener) -> Result<()> { pub fn listen_for_cli_connections(opener: OpenListener) -> Result<()> {
use release_channel::RELEASE_CHANNEL_NAME; use release_channel::RELEASE_CHANNEL_NAME;
use std::os::{linux::net::SocketAddrExt, unix::net::SocketAddr, unix::net::UnixDatagram}; use std::os::unix::net::UnixDatagram;
use util::paths;
let uid: u32 = unsafe { libc::getuid() }; let sock_path = paths::SUPPORT_DIR.join(format!("zed-{}.sock", *RELEASE_CHANNEL_NAME));
let sock_addr = // remove the socket if the process listening on it has died
SocketAddr::from_abstract_name(format!("zed-{}-{}", *RELEASE_CHANNEL_NAME, uid))?; if let Err(e) = UnixDatagram::unbound()?.connect(&sock_path) {
let listener = UnixDatagram::bind_addr(&sock_addr)?; if e.kind() == std::io::ErrorKind::ConnectionRefused {
std::fs::remove_file(&sock_path)?;
}
}
let listener = UnixDatagram::bind(&sock_path)?;
thread::spawn(move || { thread::spawn(move || {
let mut buf = [0u8; 1024]; let mut buf = [0u8; 1024];
while let Ok(len) = listener.recv(&mut buf) { while let Ok(len) = listener.recv(&mut buf) {