5
5
use std:: cell:: { Cell , OnceCell , RefCell } ;
6
6
use std:: collections:: VecDeque ;
7
7
use std:: io;
8
- use std:: io:: { ErrorKind , Read } ;
8
+ use std:: io:: ErrorKind ;
9
9
10
10
use rustc_abi:: Size ;
11
11
@@ -92,10 +92,10 @@ impl FileDescription for AnonSocket {
92
92
_communicate_allowed : bool ,
93
93
ptr : Pointer ,
94
94
len : usize ,
95
- dest : & MPlaceTy < ' tcx > ,
96
95
ecx : & mut MiriInterpCx < ' tcx > ,
96
+ finish : DynMachineCallback < ' tcx , Result < usize , IoError > > ,
97
97
) -> InterpResult < ' tcx > {
98
- anonsocket_read ( self , len , ptr, dest , ecx)
98
+ anonsocket_read ( self , ptr, len , ecx, finish )
99
99
}
100
100
101
101
fn write < ' tcx > (
@@ -205,14 +205,14 @@ fn anonsocket_write<'tcx>(
205
205
/// Read from AnonSocket and return the number of bytes read.
206
206
fn anonsocket_read < ' tcx > (
207
207
self_ref : FileDescriptionRef < AnonSocket > ,
208
- len : usize ,
209
208
ptr : Pointer ,
210
- dest : & MPlaceTy < ' tcx > ,
209
+ len : usize ,
211
210
ecx : & mut MiriInterpCx < ' tcx > ,
211
+ finish : DynMachineCallback < ' tcx , Result < usize , IoError > > ,
212
212
) -> InterpResult < ' tcx > {
213
213
// Always succeed on read size 0.
214
214
if len == 0 {
215
- return ecx . return_read_success ( ptr , & [ ] , 0 , dest ) ;
215
+ return finish . call ( ecx , Ok ( 0 ) ) ;
216
216
}
217
217
218
218
let Some ( readbuf) = & self_ref. readbuf else {
@@ -225,43 +225,41 @@ fn anonsocket_read<'tcx>(
225
225
if self_ref. peer_fd ( ) . upgrade ( ) . is_none ( ) {
226
226
// Socketpair with no peer and empty buffer.
227
227
// 0 bytes successfully read indicates end-of-file.
228
- return ecx . return_read_success ( ptr , & [ ] , 0 , dest ) ;
228
+ return finish . call ( ecx , Ok ( 0 ) ) ;
229
229
} else if self_ref. is_nonblock {
230
230
// Non-blocking socketpair with writer and empty buffer.
231
231
// https://linux.die.net/man/2/read
232
232
// EAGAIN or EWOULDBLOCK can be returned for socket,
233
233
// POSIX.1-2001 allows either error to be returned for this case.
234
234
// 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 ( ) ) ) ;
236
236
} else {
237
237
self_ref. blocked_read_tid . borrow_mut ( ) . push ( ecx. active_thread ( ) ) ;
238
238
// Blocking socketpair with writer and empty buffer.
239
239
// Block the current thread; only keep a weak ref for this.
240
240
let weak_self_ref = FileDescriptionRef :: downgrade ( & self_ref) ;
241
- let dest = dest. clone ( ) ;
242
241
ecx. block_thread (
243
242
BlockReason :: UnnamedSocket ,
244
243
None ,
245
244
callback ! (
246
245
@capture<' tcx> {
247
246
weak_self_ref: WeakFileDescriptionRef <AnonSocket >,
248
- len: usize ,
249
247
ptr: Pointer ,
250
- dest: MPlaceTy <' tcx>,
248
+ len: usize ,
249
+ finish: DynMachineCallback <' tcx, Result <usize , IoError >>,
251
250
}
252
251
|this, unblock: UnblockKind | {
253
252
assert_eq!( unblock, UnblockKind :: Ready ) ;
254
253
// If we got unblocked, then our peer successfully upgraded its weak
255
254
// ref to us. That means we can also upgrade our weak ref.
256
255
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 )
258
257
}
259
258
) ,
260
259
) ;
261
260
}
262
261
} else {
263
262
// There's data to be read!
264
- let mut bytes = vec ! [ 0 ; len] ;
265
263
let mut readbuf = readbuf. borrow_mut ( ) ;
266
264
// Synchronize with all previous writes to this buffer.
267
265
// FIXME: this over-synchronizes; a more precise approach would be to
@@ -270,7 +268,7 @@ fn anonsocket_read<'tcx>(
270
268
271
269
// Do full read / partial read based on the space available.
272
270
// 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 ( ) ;
274
272
275
273
// Need to drop before others can access the readbuf again.
276
274
drop ( readbuf) ;
@@ -293,7 +291,7 @@ fn anonsocket_read<'tcx>(
293
291
ecx. check_and_update_readiness ( peer_fd) ?;
294
292
} ;
295
293
296
- return ecx . return_read_success ( ptr , & bytes , actual_read_size , dest ) ;
294
+ return finish . call ( ecx , Ok ( read_size ) ) ;
297
295
}
298
296
interp_ok ( ( ) )
299
297
}
0 commit comments