mirror of
https://github.com/herdrdev/herdr.git
synced 2026-10-02 16:00:26 +00:00
83 lines
2.1 KiB
Rust
83 lines
2.1 KiB
Rust
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,
|
|
) -> io::Result<()> {
|
|
if let Some(parent) = path.parent() {
|
|
fs::create_dir_all(parent)?;
|
|
}
|
|
|
|
if !path.exists() {
|
|
return Ok(());
|
|
}
|
|
|
|
match UnixStream::connect(path) {
|
|
Ok(_) => {
|
|
return Err(io::Error::new(io::ErrorKind::AddrInUse, busy_message(path)));
|
|
}
|
|
Err(err)
|
|
if matches!(
|
|
err.kind(),
|
|
io::ErrorKind::ConnectionRefused
|
|
| io::ErrorKind::NotFound
|
|
| io::ErrorKind::TimedOut
|
|
) => {}
|
|
Err(err) => return Err(err),
|
|
}
|
|
|
|
if let Err(err) = fs::remove_file(path) {
|
|
if err.kind() != io::ErrorKind::NotFound {
|
|
return Err(err);
|
|
}
|
|
}
|
|
|
|
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);
|
|
fs::set_permissions(path, permissions)
|
|
}
|