@@ -156,12 +156,12 @@ pub extern "C" fn wasi_config_inherit_stdout(config: &mut wasi_config_t) {
156156
157157struct CustomOutputStreamInner {
158158 foreign_data : crate :: ForeignData ,
159- callback : extern "C" fn ( * mut c_void , * const u8 , usize ) ,
159+ callback : extern "C" fn ( * mut c_void , * const u8 , usize ) -> isize ,
160160}
161161
162162impl CustomOutputStreamInner {
163- pub fn write ( & self , buf : & [ u8 ] ) {
164- ( self . callback ) ( self . foreign_data . data , buf. as_ptr ( ) , buf. len ( ) ) ;
163+ pub fn write ( & self , buf : & [ u8 ] ) -> isize {
164+ ( self . callback ) ( self . foreign_data . data , buf. as_ptr ( ) , buf. len ( ) )
165165 }
166166}
167167
@@ -172,7 +172,7 @@ pub struct CustomOutputStream {
172172impl CustomOutputStream {
173173 pub fn new (
174174 foreign_data : crate :: ForeignData ,
175- callback : extern "C" fn ( * mut c_void , * const u8 , usize ) ,
175+ callback : extern "C" fn ( * mut c_void , * const u8 , usize ) -> isize ,
176176 ) -> Self {
177177 Self {
178178 inner : std:: sync:: Arc :: new ( CustomOutputStreamInner {
@@ -199,16 +199,28 @@ impl wasmtime_wasi::p2::Pollable for CustomOutputStream {
199199#[ async_trait:: async_trait]
200200impl wasmtime_wasi:: p2:: OutputStream for CustomOutputStream {
201201 fn write ( & mut self , bytes : Bytes ) -> Result < ( ) , StreamError > {
202- self . inner . write ( & bytes) ;
203- // Always ready for writing
202+ let wrote = self . inner . write ( & bytes) ;
203+
204+ if wrote < 0 {
205+ return Err ( StreamError :: Trap ( anyhow:: anyhow!(
206+ "Custom write function failed with error code '{}'" ,
207+ wrote. abs( )
208+ ) ) ) ;
209+ }
210+
211+ if wrote as usize != bytes. len ( ) {
212+ return Err ( StreamError :: Trap ( anyhow:: anyhow!(
213+ "Partial writes in wasip2 implementation are not allowed"
214+ ) ) ) ;
215+ }
216+
204217 Ok ( ( ) )
205218 }
206219 fn flush ( & mut self ) -> Result < ( ) , StreamError > {
207- // This stream is always flushed
208220 Ok ( ( ) )
209221 }
210222 fn check_write ( & mut self ) -> Result < usize , StreamError > {
211- Ok ( 8192 )
223+ Ok ( usize :: MAX )
212224 }
213225}
214226
@@ -218,8 +230,18 @@ impl AsyncWrite for CustomOutputStream {
218230 _cx : & mut Context < ' _ > ,
219231 buf : & [ u8 ] ,
220232 ) -> Poll < io:: Result < usize > > {
221- self . inner . write ( buf) ;
222- Poll :: Ready ( Ok ( buf. len ( ) ) )
233+ let wrote = self . inner . write ( buf) ;
234+ Poll :: Ready ( if wrote >= 0 {
235+ Ok ( wrote as _ )
236+ } else {
237+ Err ( io:: Error :: new (
238+ io:: ErrorKind :: Other ,
239+ format ! (
240+ "Custom write function failed with error code '{}'" ,
241+ wrote. abs( )
242+ ) ,
243+ ) )
244+ } )
223245 }
224246 fn poll_flush ( self : Pin < & mut Self > , _cx : & mut Context < ' _ > ) -> Poll < io:: Result < ( ) > > {
225247 Poll :: Ready ( Ok ( ( ) ) )
@@ -244,13 +266,13 @@ impl wasmtime_wasi::cli::StdoutStream for CustomOutputStream {
244266#[ unsafe( no_mangle) ]
245267pub extern "C" fn wasi_config_set_stdout_custom (
246268 config : & mut wasi_config_t ,
247- callback : Option < extern "C" fn ( * mut c_void , * const u8 , usize ) > ,
269+ callback : extern "C" fn ( * mut c_void , * const u8 , usize ) -> isize ,
248270 data : * mut c_void ,
249271 finalizer : Option < extern "C" fn ( * mut c_void ) > ,
250272) {
251273 config. builder . stdout ( CustomOutputStream :: new (
252274 crate :: ForeignData { data, finalizer } ,
253- callback. expect ( "Callback must be provided" ) ,
275+ callback,
254276 ) ) ;
255277}
256278
@@ -279,13 +301,13 @@ pub extern "C" fn wasi_config_inherit_stderr(config: &mut wasi_config_t) {
279301#[ unsafe( no_mangle) ]
280302pub extern "C" fn wasi_config_set_stderr_custom (
281303 config : & mut wasi_config_t ,
282- callback : Option < extern "C" fn ( * mut c_void , * const u8 , usize ) > ,
304+ callback : extern "C" fn ( * mut c_void , * const u8 , usize ) -> isize ,
283305 data : * mut c_void ,
284306 finalizer : Option < extern "C" fn ( * mut c_void ) > ,
285307) {
286308 config. builder . stderr ( CustomOutputStream :: new (
287309 crate :: ForeignData { data, finalizer } ,
288- callback. expect ( "Callback must be provided" ) ,
310+ callback,
289311 ) ) ;
290312}
291313
0 commit comments