diff options
| author | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-05-25 15:36:50 +0300 |
|---|---|---|
| committer | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-05-25 15:36:50 +0300 |
| commit | d4a5e02e8433db156b9dabe2b81ddd1d2aca9ea6 (patch) | |
| tree | f94ebdfc2bf1e54b3d110052269c67b6ba5f6fb8 /src/ipc.rs | |
| parent | a1543f3e248f8f5266322014ccd853e478b1dcd6 (diff) | |
feat: hand off ptys during updates
Diffstat (limited to 'src/ipc.rs')
| -rw-r--r-- | src/ipc.rs | 36 |
1 files changed, 36 insertions, 0 deletions
@@ -1,9 +1,16 @@ use std::fs; use std::io; +use std::os::unix::fs::MetadataExt; use std::os::unix::fs::PermissionsExt; use std::os::unix::net::UnixStream; use std::path::Path; +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub(crate) struct SocketFileIdentity { + dev: u64, + ino: u64, +} + pub(crate) fn prepare_socket_path( path: &Path, busy_message: impl FnOnce(&Path) -> String, @@ -39,6 +46,35 @@ pub(crate) fn prepare_socket_path( Ok(()) } +pub(crate) fn socket_file_identity(path: &Path) -> io::Result<SocketFileIdentity> { + let metadata = fs::metadata(path)?; + Ok(SocketFileIdentity { + dev: metadata.dev(), + ino: metadata.ino(), + }) +} + +pub(crate) fn remove_socket_file_if_owned( + path: &Path, + identity: SocketFileIdentity, +) -> io::Result<()> { + let current = match socket_file_identity(path) { + Ok(current) => current, + Err(err) if err.kind() == io::ErrorKind::NotFound => return Ok(()), + Err(err) => return Err(err), + }; + + if current != identity { + return Ok(()); + } + + match fs::remove_file(path) { + Ok(()) => Ok(()), + Err(err) if err.kind() == io::ErrorKind::NotFound => Ok(()), + Err(err) => Err(err), + } +} + pub(crate) fn restrict_socket_permissions(path: &Path, mode: u32) -> io::Result<()> { let mut permissions = fs::metadata(path)?.permissions(); permissions.set_mode(mode); |
