feat(ipc): server bind + Connection wrapper

This commit is contained in:
2026-05-25 11:47:24 +02:00
parent fbfb1db427
commit b137f85a0c
2 changed files with 69 additions and 0 deletions
+2
View File
@@ -3,6 +3,7 @@
pub mod client;
pub mod envelope;
pub mod framing;
pub mod server;
pub use client::{Client, ClientError};
pub use envelope::{
@@ -10,3 +11,4 @@ pub use envelope::{
RpcError,
};
pub use framing::JsonFramed;
pub use server::{bind, Connection};
+67
View File
@@ -0,0 +1,67 @@
use crate::envelope::{Incoming, Notification, Response};
use crate::framing::JsonFramed;
use std::path::Path;
use std::sync::Arc;
use tokio::net::{UnixListener, UnixStream};
use tokio::sync::Mutex;
pub struct Connection {
inner: Arc<Mutex<JsonFramed>>,
}
impl Connection {
pub fn new(stream: UnixStream) -> Self {
Self {
inner: Arc::new(Mutex::new(JsonFramed::new(stream))),
}
}
pub async fn read_incoming(&self) -> std::io::Result<Option<Incoming>> {
let mut g = self.inner.lock().await;
g.read::<Incoming>().await
}
pub async fn write_response(&self, r: &Response) -> std::io::Result<()> {
let mut g = self.inner.lock().await;
g.write(r).await
}
pub async fn write_notification(&self, n: &Notification) -> std::io::Result<()> {
let mut g = self.inner.lock().await;
g.write(n).await
}
}
pub fn bind(socket_path: &Path) -> std::io::Result<UnixListener> {
if socket_path.exists() {
std::fs::remove_file(socket_path)?;
}
if let Some(parent) = socket_path.parent() {
std::fs::create_dir_all(parent)?;
}
let listener = UnixListener::bind(socket_path)?;
use std::os::unix::fs::PermissionsExt;
std::fs::set_permissions(socket_path, std::fs::Permissions::from_mode(0o600))?;
Ok(listener)
}
#[cfg(test)]
mod tests {
use super::*;
use tempfile::tempdir;
#[tokio::test]
async fn bind_creates_socket_with_0600() {
let dir = tempdir().unwrap();
let path = dir.path().join("x.sock");
let _listener = bind(&path).unwrap();
use std::os::unix::fs::PermissionsExt;
let mode = std::fs::metadata(&path).unwrap().permissions().mode() & 0o777;
assert_eq!(mode, 0o600);
}
}