wasi_process/
stdio.rs

1use serde::{Deserialize, Serialize};
2use std::io::{prelude::*, SeekFrom};
3use tokio::io::{self, AsyncReadExt, AsyncWriteExt};
4use tokio::runtime::Handle;
5use wasmer_wasi::{types as wasi_types, WasiFile, WasiFsError};
6
7use super::{STDERR, STDIN, STDOUT};
8
9/// The stdin pseudo-file for wasi processes.
10#[derive(Debug, Serialize, Deserialize)]
11pub struct Stdin;
12impl Read for Stdin {
13    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
14        STDIN.with(|stdin| Handle::current().block_on((&*stdin).read(buf)))
15    }
16}
17impl Seek for Stdin {
18    fn seek(&mut self, _pos: SeekFrom) -> io::Result<u64> {
19        Err(io::Error::new(io::ErrorKind::Other, "can not seek stdin"))
20    }
21}
22impl Write for Stdin {
23    fn write(&mut self, _buf: &[u8]) -> io::Result<usize> {
24        Err(io::Error::new(
25            io::ErrorKind::Other,
26            "can not write to stdin",
27        ))
28    }
29    fn flush(&mut self) -> io::Result<()> {
30        Err(io::Error::new(
31            io::ErrorKind::Other,
32            "can not write to stdin",
33        ))
34    }
35    fn write_all(&mut self, _buf: &[u8]) -> io::Result<()> {
36        Err(io::Error::new(
37            io::ErrorKind::Other,
38            "can not write to stdin",
39        ))
40    }
41    fn write_fmt(&mut self, _fmt: ::std::fmt::Arguments) -> io::Result<()> {
42        Err(io::Error::new(
43            io::ErrorKind::Other,
44            "can not write to stdin",
45        ))
46    }
47}
48
49#[typetag::serde(name = "tokio_process_stdin")]
50impl WasiFile for Stdin {
51    fn last_accessed(&self) -> u64 {
52        0
53    }
54    fn last_modified(&self) -> u64 {
55        0
56    }
57    fn created_time(&self) -> u64 {
58        0
59    }
60    fn size(&self) -> u64 {
61        0
62    }
63    fn set_len(&mut self, _new_size: wasi_types::__wasi_filesize_t) -> Result<(), WasiFsError> {
64        Err(WasiFsError::PermissionDenied)
65    }
66
67    fn unlink(&mut self) -> Result<(), WasiFsError> {
68        Ok(())
69    }
70
71    fn bytes_available(&self) -> Result<usize, WasiFsError> {
72        Ok(0)
73    }
74
75    fn get_raw_fd(&self) -> Option<i32> {
76        None
77    }
78}
79
80/// The stdout pseudo-file for wasi processes.
81#[derive(Debug, Serialize, Deserialize)]
82pub struct Stdout;
83impl Read for Stdout {
84    fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
85        Err(io::Error::new(
86            io::ErrorKind::Other,
87            "can not read from stdout",
88        ))
89    }
90    fn read_to_end(&mut self, _buf: &mut Vec<u8>) -> io::Result<usize> {
91        Err(io::Error::new(
92            io::ErrorKind::Other,
93            "can not read from stdout",
94        ))
95    }
96    fn read_to_string(&mut self, _buf: &mut String) -> io::Result<usize> {
97        Err(io::Error::new(
98            io::ErrorKind::Other,
99            "can not read from stdout",
100        ))
101    }
102    fn read_exact(&mut self, _buf: &mut [u8]) -> io::Result<()> {
103        Err(io::Error::new(
104            io::ErrorKind::Other,
105            "can not read from stdout",
106        ))
107    }
108}
109impl Seek for Stdout {
110    fn seek(&mut self, _pos: SeekFrom) -> io::Result<u64> {
111        Err(io::Error::new(io::ErrorKind::Other, "can not seek stdout"))
112    }
113}
114impl Write for Stdout {
115    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
116        STDOUT.with(|stdout| Handle::current().block_on((&*stdout).write(buf)))
117    }
118    fn flush(&mut self) -> io::Result<()> {
119        Ok(())
120    }
121}
122
123#[typetag::serde(name = "tokio_process_stdout")]
124impl WasiFile for Stdout {
125    fn last_accessed(&self) -> u64 {
126        0
127    }
128    fn last_modified(&self) -> u64 {
129        0
130    }
131    fn created_time(&self) -> u64 {
132        0
133    }
134    fn size(&self) -> u64 {
135        0
136    }
137    fn set_len(&mut self, _new_size: wasi_types::__wasi_filesize_t) -> Result<(), WasiFsError> {
138        Err(WasiFsError::PermissionDenied)
139    }
140    fn unlink(&mut self) -> Result<(), WasiFsError> {
141        Ok(())
142    }
143
144    fn bytes_available(&self) -> Result<usize, WasiFsError> {
145        Err(WasiFsError::InvalidInput)
146    }
147
148    fn get_raw_fd(&self) -> Option<i32> {
149        None
150    }
151}
152
153/// The stderr pseudo-file for wasi processes.
154#[derive(Debug, Serialize, Deserialize)]
155pub struct Stderr;
156impl Read for Stderr {
157    fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
158        Err(io::Error::new(
159            io::ErrorKind::Other,
160            "can not read from stderr",
161        ))
162    }
163    fn read_to_end(&mut self, _buf: &mut Vec<u8>) -> io::Result<usize> {
164        Err(io::Error::new(
165            io::ErrorKind::Other,
166            "can not read from stderr",
167        ))
168    }
169    fn read_to_string(&mut self, _buf: &mut String) -> io::Result<usize> {
170        Err(io::Error::new(
171            io::ErrorKind::Other,
172            "can not read from stderr",
173        ))
174    }
175    fn read_exact(&mut self, _buf: &mut [u8]) -> io::Result<()> {
176        Err(io::Error::new(
177            io::ErrorKind::Other,
178            "can not read from stderr",
179        ))
180    }
181}
182impl Seek for Stderr {
183    fn seek(&mut self, _pos: SeekFrom) -> io::Result<u64> {
184        Err(io::Error::new(io::ErrorKind::Other, "can not seek stderr"))
185    }
186}
187impl Write for Stderr {
188    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
189        STDERR.with(|stderr| Handle::current().block_on((&*stderr).write(buf)))
190    }
191    fn flush(&mut self) -> io::Result<()> {
192        Ok(())
193    }
194}
195
196#[typetag::serde(name = "tokio_process_stderr")]
197impl WasiFile for Stderr {
198    fn last_accessed(&self) -> u64 {
199        0
200    }
201    fn last_modified(&self) -> u64 {
202        0
203    }
204    fn created_time(&self) -> u64 {
205        0
206    }
207    fn size(&self) -> u64 {
208        0
209    }
210    fn set_len(&mut self, _new_size: wasi_types::__wasi_filesize_t) -> Result<(), WasiFsError> {
211        Err(WasiFsError::PermissionDenied)
212    }
213    fn unlink(&mut self) -> Result<(), WasiFsError> {
214        Ok(())
215    }
216
217    fn bytes_available(&self) -> Result<usize, WasiFsError> {
218        Err(WasiFsError::InvalidInput)
219    }
220
221    fn get_raw_fd(&self) -> Option<i32> {
222        None
223    }
224}