aboutsummaryrefslogtreecommitdiff
path: root/alsa
diff options
context:
space:
mode:
authorAndreas Grois <andi@grois.info>2024-01-27 19:58:39 +0100
committerAndreas Grois <andi@grois.info>2024-01-27 19:58:39 +0100
commitef34d465945a565c8bf02931677131b43f930493 (patch)
tree68ab47a917cf0503808b9241f6d7a8871c9f8b07 /alsa
parent592e80a279e6fde4d79bc44807941fb7054e1407 (diff)
Start working on pipe_chan
Diffstat (limited to 'alsa')
-rw-r--r--alsa/Cargo.toml2
-rw-r--r--alsa/src/communication.rs3
-rw-r--r--alsa/src/communication/pipe_chan.rs81
3 files changed, 86 insertions, 0 deletions
diff --git a/alsa/Cargo.toml b/alsa/Cargo.toml
index c89855e..12d83d7 100644
--- a/alsa/Cargo.toml
+++ b/alsa/Cargo.toml
@@ -10,6 +10,8 @@ edition = "2021"
swaystatus-plugin = { path = '../swaystatus-plugin', version = '*'}
serde = { version = "1.0", features = ["derive"] }
erased-serde = "0.3"
+libc = "0.2.152"
+errno = "0.3.8"
[lib]
crate-type = ["cdylib"]
diff --git a/alsa/src/communication.rs b/alsa/src/communication.rs
index be11dd8..b55a786 100644
--- a/alsa/src/communication.rs
+++ b/alsa/src/communication.rs
@@ -1,6 +1,9 @@
use std::sync::mpsc::*;
use swaystatus_plugin::*;
+pub(crate) mod pipe_chan;
+
+#[repr(C)]
pub enum MessagesFromMain {
Quit,
Refresh
diff --git a/alsa/src/communication/pipe_chan.rs b/alsa/src/communication/pipe_chan.rs
new file mode 100644
index 0000000..1a671ea
--- /dev/null
+++ b/alsa/src/communication/pipe_chan.rs
@@ -0,0 +1,81 @@
+use std::{ffi::{c_int, c_void}, fmt::Display, error::Error};
+use libc::{read, close, pipe2, O_NONBLOCK, EINTR };
+use errno::{errno, set_errno, Errno}; //Why isn't this in libc?!?
+
+/// Sends byte data to the corresponding receiver.
+pub(crate) struct Sender {
+ handle : FileHandle,
+}
+/// Receives byte data from the corresponding sender.
+pub(crate) struct Receiver {
+ handle : FileHandle,
+}
+
+impl Receiver {
+ pub(crate) fn read_byte(&self) -> Result<Option<u8>, ReceiveError> {
+ set_errno(Errno(0));
+ let mut buf : u8 = 0;
+ let status = unsafe {read(self.handle.get_raw(),&mut buf as *mut u8 as *mut c_void, 1)};
+ if status == 0 {
+ //need to check errno. if a signal interrupted, then there is no error and we just
+ //retry.
+ //If no error happened, then the sender has hung up and we return err.
+ let e = errno();
+ if e == Errno(0) {
+ Err(ReceiveError::SenderHasHungUp)
+ } else if e.0 == EINTR {
+ self.read_byte()
+ } else {
+ //Not sure what to do
+ todo!()
+ }
+ }
+ else {
+ todo!()
+ }
+ }
+}
+
+#[derive(Debug, Clone, Copy)]
+pub(crate) enum ReceiveError {
+ SenderHasHungUp
+}
+
+impl Display for ReceiveError{
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ write!(f, "Read failed, Sender has closed their end of the pipe.")
+ }
+}
+
+impl Error for ReceiveError {}
+
+pub(crate) fn create_pipe_chan() -> Result<(Sender, Receiver),()> {
+ let mut handles : [c_int;2] = [0;2];
+ let result = unsafe { pipe2(handles.as_mut_ptr(), O_NONBLOCK) };
+ if result == -1 {
+ Err(())
+ } else {
+ Ok((
+ Sender{handle : FileHandle{raw : handles[1]}},
+ Receiver{handle : FileHandle{ raw : handles[0]}}
+ ))
+ }
+}
+
+struct FileHandle {
+ raw : c_int,
+}
+
+impl FileHandle {
+ pub(crate) fn get_raw(&self) -> c_int {
+ self.raw
+ }
+}
+
+impl Drop for FileHandle {
+ fn drop(&mut self) {
+ unsafe {
+ close(self.raw);
+ }
+ }
+}