aboutsummaryrefslogtreecommitdiff
path: root/niri-ipc/src/socket.rs
diff options
context:
space:
mode:
authorsodiboo <37938646+sodiboo@users.noreply.github.com>2024-04-19 15:02:32 +0200
committerGitHub <noreply@github.com>2024-04-19 13:02:32 +0000
commitb5f7e4bd83dbfc77e0c8b973bc217c9a4cb3f364 (patch)
treedbe59c9a19f2e7d94086e9fbb1c28a43e062e16b /niri-ipc/src/socket.rs
parentb98b95883def5cd726c1e96a006f9cd7498d1730 (diff)
downloadniri-b5f7e4bd83dbfc77e0c8b973bc217c9a4cb3f364.tar.gz
niri-b5f7e4bd83dbfc77e0c8b973bc217c9a4cb3f364.tar.bz2
niri-b5f7e4bd83dbfc77e0c8b973bc217c9a4cb3f364.zip
`niri_ipc::Socket`; `niri msg version`; version checking on IPC (#278)
* Implement version checking in IPC implement version checking; streamed IPC streamed IPC will allow multiple requests per connection add nonsense request change inline struct to json macro only check version if request actually fails fix usage of inspect_err (MSRV 1.72.0; stabilized 1.76.0) "nonsense request" -> "return error" oneshot connections * Change some things around * Unqualify niri_ipc::Transform --------- Co-authored-by: Ivan Molodetskikh <yalterz@gmail.com>
Diffstat (limited to 'niri-ipc/src/socket.rs')
-rw-r--r--niri-ipc/src/socket.rs63
1 files changed, 63 insertions, 0 deletions
diff --git a/niri-ipc/src/socket.rs b/niri-ipc/src/socket.rs
new file mode 100644
index 00000000..67b9625c
--- /dev/null
+++ b/niri-ipc/src/socket.rs
@@ -0,0 +1,63 @@
+//! Helper for blocking communication over the niri socket.
+
+use std::env;
+use std::io::{self, Read, Write};
+use std::net::Shutdown;
+use std::os::unix::net::UnixStream;
+use std::path::Path;
+
+use crate::{Reply, Request};
+
+/// Name of the environment variable containing the niri IPC socket path.
+pub const SOCKET_PATH_ENV: &str = "NIRI_SOCKET";
+
+/// Helper for blocking communication over the niri socket.
+///
+/// This struct is used to communicate with the niri IPC server. It handles the socket connection
+/// and serialization/deserialization of messages.
+pub struct Socket {
+ stream: UnixStream,
+}
+
+impl Socket {
+ /// Connects to the default niri IPC socket.
+ ///
+ /// This is equivalent to calling [`Self::connect_to`] with the path taken from the
+ /// [`SOCKET_PATH_ENV`] environment variable.
+ pub fn connect() -> io::Result<Self> {
+ let socket_path = env::var_os(SOCKET_PATH_ENV).ok_or_else(|| {
+ io::Error::new(
+ io::ErrorKind::NotFound,
+ format!("{SOCKET_PATH_ENV} is not set, are you running this within niri?"),
+ )
+ })?;
+ Self::connect_to(socket_path)
+ }
+
+ /// Connects to the niri IPC socket at the given path.
+ pub fn connect_to(path: impl AsRef<Path>) -> io::Result<Self> {
+ let stream = UnixStream::connect(path.as_ref())?;
+ Ok(Self { stream })
+ }
+
+ /// Sends a request to niri and returns the response.
+ ///
+ /// Return values:
+ ///
+ /// * `Ok(Ok(response))`: successful [`Response`](crate::Response) from niri
+ /// * `Ok(Err(message))`: error message from niri
+ /// * `Err(error)`: error communicating with niri
+ pub fn send(self, request: Request) -> io::Result<Reply> {
+ let Self { mut stream } = self;
+
+ let mut buf = serde_json::to_vec(&request).unwrap();
+ stream.write_all(&buf)?;
+ stream.shutdown(Shutdown::Write)?;
+
+ buf.clear();
+ stream.read_to_end(&mut buf)?;
+
+ let reply = serde_json::from_slice(&buf)?;
+ Ok(reply)
+ }
+}