55use std:: cell:: { Cell , OnceCell , RefCell } ;
66use std:: collections:: VecDeque ;
77use std:: io;
8- use std:: io:: { ErrorKind , Read } ;
8+ use std:: io:: ErrorKind ;
99
1010use rustc_abi:: Size ;
1111
@@ -92,10 +92,10 @@ impl FileDescription for AnonSocket {
9292 _communicate_allowed : bool ,
9393 ptr : Pointer ,
9494 len : usize ,
95- dest : & MPlaceTy < ' tcx > ,
9695 ecx : & mut MiriInterpCx < ' tcx > ,
96+ finish : DynMachineCallback < ' tcx , Result < usize , IoError > > ,
9797 ) -> InterpResult < ' tcx > {
98- anonsocket_read ( self , len , ptr, dest , ecx)
98+ anonsocket_read ( self , ptr, len , ecx, finish )
9999 }
100100
101101 fn write < ' tcx > (
@@ -205,14 +205,14 @@ fn anonsocket_write<'tcx>(
205205/// Read from AnonSocket and return the number of bytes read.
206206fn anonsocket_read < ' tcx > (
207207 self_ref : FileDescriptionRef < AnonSocket > ,
208- len : usize ,
209208 ptr : Pointer ,
210- dest : & MPlaceTy < ' tcx > ,
209+ len : usize ,
211210 ecx : & mut MiriInterpCx < ' tcx > ,
211+ finish : DynMachineCallback < ' tcx , Result < usize , IoError > > ,
212212) -> InterpResult < ' tcx > {
213213 // Always succeed on read size 0.
214214 if len == 0 {
215- return ecx . return_read_success ( ptr , & [ ] , 0 , dest ) ;
215+ return finish . call ( ecx , Ok ( 0 ) ) ;
216216 }
217217
218218 let Some ( readbuf) = & self_ref. readbuf else {
@@ -225,43 +225,41 @@ fn anonsocket_read<'tcx>(
225225 if self_ref. peer_fd ( ) . upgrade ( ) . is_none ( ) {
226226 // Socketpair with no peer and empty buffer.
227227 // 0 bytes successfully read indicates end-of-file.
228- return ecx . return_read_success ( ptr , & [ ] , 0 , dest ) ;
228+ return finish . call ( ecx , Ok ( 0 ) ) ;
229229 } else if self_ref. is_nonblock {
230230 // Non-blocking socketpair with writer and empty buffer.
231231 // https://linux.die.net/man/2/read
232232 // EAGAIN or EWOULDBLOCK can be returned for socket,
233233 // POSIX.1-2001 allows either error to be returned for this case.
234234 // Since there is no ErrorKind for EAGAIN, WouldBlock is used.
235- return ecx . set_last_error_and_return ( ErrorKind :: WouldBlock , dest ) ;
235+ return finish . call ( ecx , Err ( ErrorKind :: WouldBlock . into ( ) ) ) ;
236236 } else {
237237 self_ref. blocked_read_tid . borrow_mut ( ) . push ( ecx. active_thread ( ) ) ;
238238 // Blocking socketpair with writer and empty buffer.
239239 // Block the current thread; only keep a weak ref for this.
240240 let weak_self_ref = FileDescriptionRef :: downgrade ( & self_ref) ;
241- let dest = dest. clone ( ) ;
242241 ecx. block_thread (
243242 BlockReason :: UnnamedSocket ,
244243 None ,
245244 callback ! (
246245 @capture<' tcx> {
247246 weak_self_ref: WeakFileDescriptionRef <AnonSocket >,
248- len: usize ,
249247 ptr: Pointer ,
250- dest: MPlaceTy <' tcx>,
248+ len: usize ,
249+ finish: DynMachineCallback <' tcx, Result <usize , IoError >>,
251250 }
252251 |this, unblock: UnblockKind | {
253252 assert_eq!( unblock, UnblockKind :: Ready ) ;
254253 // If we got unblocked, then our peer successfully upgraded its weak
255254 // ref to us. That means we can also upgrade our weak ref.
256255 let self_ref = weak_self_ref. upgrade( ) . unwrap( ) ;
257- anonsocket_read( self_ref, len , ptr, & dest , this)
256+ anonsocket_read( self_ref, ptr, len , this, finish )
258257 }
259258 ) ,
260259 ) ;
261260 }
262261 } else {
263262 // There's data to be read!
264- let mut bytes = vec ! [ 0 ; len] ;
265263 let mut readbuf = readbuf. borrow_mut ( ) ;
266264 // Synchronize with all previous writes to this buffer.
267265 // FIXME: this over-synchronizes; a more precise approach would be to
@@ -270,7 +268,7 @@ fn anonsocket_read<'tcx>(
270268
271269 // Do full read / partial read based on the space available.
272270 // Conveniently, `read` exists on `VecDeque` and has exactly the desired behavior.
273- let actual_read_size = readbuf . buf . read ( & mut bytes [ .. ] ) . unwrap ( ) ;
271+ let read_size = ecx . read_from_host ( & mut readbuf . buf , len , ptr ) ? . unwrap ( ) ;
274272
275273 // Need to drop before others can access the readbuf again.
276274 drop ( readbuf) ;
@@ -293,7 +291,7 @@ fn anonsocket_read<'tcx>(
293291 ecx. check_and_update_readiness ( peer_fd) ?;
294292 } ;
295293
296- return ecx . return_read_success ( ptr , & bytes , actual_read_size , dest ) ;
294+ return finish . call ( ecx , Ok ( read_size ) ) ;
297295 }
298296 interp_ok ( ( ) )
299297}
0 commit comments