diff options
| author | Andreas Grois <andi@grois.info> | 2024-01-27 19:58:39 +0100 |
|---|---|---|
| committer | Andreas Grois <andi@grois.info> | 2024-01-27 19:58:39 +0100 |
| commit | ef34d465945a565c8bf02931677131b43f930493 (patch) | |
| tree | 68ab47a917cf0503808b9241f6d7a8871c9f8b07 /alsa/src/communication | |
| parent | 592e80a279e6fde4d79bc44807941fb7054e1407 (diff) | |
Start working on pipe_chan
Diffstat (limited to 'alsa/src/communication')
| -rw-r--r-- | alsa/src/communication/pipe_chan.rs | 81 |
1 files changed, 81 insertions, 0 deletions
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); + } + } +} |
