wasm_bpf_rs/
pipe.rs

1//!  SPDX-License-Identifier: MIT
2//!
3//! Copyright (c) 2023, eunomia-bpf
4//! All rights reserved.
5//!
6use std::{
7    any::Any,
8    io::{self, Cursor, Write},
9    sync::{Arc, RwLock},
10};
11
12use wasi_common::{
13    file::{FdFlags, FileType},
14    Error, ErrorExt, WasiFile,
15};
16
17/// This is a pipe that can be read from and written to.
18/// The original wasmtime pipe is only writable when the wasm program is running.
19pub struct ReadableWritePipe<W: Write> {
20    buf: Arc<RwLock<W>>,
21}
22
23#[wiggle::async_trait]
24impl<W: Write + Any + Send + Sync> WasiFile for ReadableWritePipe<W> {
25    fn as_any(&self) -> &dyn std::any::Any {
26        self
27    }
28    async fn get_filetype(&mut self) -> Result<FileType, Error> {
29        Ok(FileType::Pipe)
30    }
31    async fn get_fdflags(&mut self) -> Result<FdFlags, Error> {
32        Ok(FdFlags::APPEND)
33    }
34    async fn write_vectored<'a>(&mut self, bufs: &[std::io::IoSlice<'a>]) -> Result<u64, Error> {
35        let n = self.borrow().write_vectored(bufs)?;
36        Ok(n.try_into()?)
37    }
38    async fn writable(&self) -> Result<(), Error> {
39        Ok(())
40    }
41    async fn write_vectored_at<'a>(
42        &mut self,
43        _bufs: &[io::IoSlice<'a>],
44        _offset: u64,
45    ) -> Result<u64, Error> {
46        Err(Error::seek_pipe())
47    }
48    async fn seek(&mut self, _pos: std::io::SeekFrom) -> Result<u64, Error> {
49        Err(Error::seek_pipe())
50    }
51    fn isatty(&mut self) -> bool {
52        false
53    }
54}
55
56impl<W: Write> ReadableWritePipe<W> {
57    pub fn borrow(&self) -> std::sync::RwLockWriteGuard<W> {
58        RwLock::write(&self.buf).unwrap()
59    }
60    pub fn get_read_lock(&self) -> std::sync::RwLockReadGuard<W> {
61        self.buf.read().unwrap()
62    }
63    pub fn new(inner: W) -> Self {
64        Self {
65            buf: Arc::new(RwLock::new(inner)),
66        }
67    }
68}
69
70impl ReadableWritePipe<Cursor<Vec<u8>>> {
71    pub fn new_vec_buf() -> Self {
72        Self::new(Cursor::new(vec![]))
73    }
74}
75
76impl<W: Write> Clone for ReadableWritePipe<W> {
77    fn clone(&self) -> Self {
78        Self {
79            buf: self.buf.clone(),
80        }
81    }
82}