@@ -7,8 +7,6 @@ use std::collections::VecDeque;
77use std:: io;
88use std:: io:: ErrorKind ;
99
10- use rustc_abi:: Size ;
11-
1210use crate :: concurrency:: VClock ;
1311use crate :: shims:: files:: {
1412 EvalContextExt as _, FileDescription , FileDescriptionRef , WeakFileDescriptionRef ,
@@ -103,10 +101,10 @@ impl FileDescription for AnonSocket {
103101 _communicate_allowed : bool ,
104102 ptr : Pointer ,
105103 len : usize ,
106- dest : & MPlaceTy < ' tcx > ,
107104 ecx : & mut MiriInterpCx < ' tcx > ,
105+ finish : DynMachineCallback < ' tcx , Result < usize , IoError > > ,
108106 ) -> InterpResult < ' tcx > {
109- anonsocket_write ( self , ptr, len, dest , ecx )
107+ anonsocket_write ( self , ptr, len, ecx , finish )
110108 }
111109
112110 fn as_unix ( & self ) -> & dyn UnixFileDescription {
@@ -119,39 +117,38 @@ fn anonsocket_write<'tcx>(
119117 self_ref : FileDescriptionRef < AnonSocket > ,
120118 ptr : Pointer ,
121119 len : usize ,
122- dest : & MPlaceTy < ' tcx > ,
123120 ecx : & mut MiriInterpCx < ' tcx > ,
121+ finish : DynMachineCallback < ' tcx , Result < usize , IoError > > ,
124122) -> InterpResult < ' tcx > {
125123 // Always succeed on write size 0.
126124 // ("If count is zero and fd refers to a file other than a regular file, the results are not specified.")
127125 if len == 0 {
128- return ecx . return_write_success ( 0 , dest ) ;
126+ return finish . call ( ecx , Ok ( 0 ) ) ;
129127 }
130128
131129 // We are writing to our peer's readbuf.
132130 let Some ( peer_fd) = self_ref. peer_fd ( ) . upgrade ( ) else {
133131 // If the upgrade from Weak to Rc fails, it indicates that all read ends have been
134132 // closed. It is an error to write even if there would be space.
135- return ecx . set_last_error_and_return ( ErrorKind :: BrokenPipe , dest ) ;
133+ return finish . call ( ecx , Err ( ErrorKind :: BrokenPipe . into ( ) ) ) ;
136134 } ;
137135
138136 let Some ( writebuf) = & peer_fd. readbuf else {
139137 // Writing to the read end of a pipe.
140- return ecx . set_last_error_and_return ( IoError :: LibcError ( "EBADF" ) , dest ) ;
138+ return finish . call ( ecx , Err ( IoError :: LibcError ( "EBADF" ) ) ) ;
141139 } ;
142140
143141 // Let's see if we can write.
144142 let available_space = MAX_SOCKETPAIR_BUFFER_CAPACITY . strict_sub ( writebuf. borrow ( ) . buf . len ( ) ) ;
145143 if available_space == 0 {
146144 if self_ref. is_nonblock {
147145 // Non-blocking socketpair with a full buffer.
148- return ecx . set_last_error_and_return ( ErrorKind :: WouldBlock , dest ) ;
146+ return finish . call ( ecx , Err ( ErrorKind :: WouldBlock . into ( ) ) ) ;
149147 } else {
150148 self_ref. blocked_write_tid . borrow_mut ( ) . push ( ecx. active_thread ( ) ) ;
151149 // Blocking socketpair with a full buffer.
152150 // Block the current thread; only keep a weak ref for this.
153151 let weak_self_ref = FileDescriptionRef :: downgrade ( & self_ref) ;
154- let dest = dest. clone ( ) ;
155152 ecx. block_thread (
156153 BlockReason :: UnnamedSocket ,
157154 None ,
@@ -160,14 +157,14 @@ fn anonsocket_write<'tcx>(
160157 weak_self_ref: WeakFileDescriptionRef <AnonSocket >,
161158 ptr: Pointer ,
162159 len: usize ,
163- dest : MPlaceTy <' tcx>,
160+ finish : DynMachineCallback <' tcx, Result < usize , IoError > >,
164161 }
165162 |this, unblock: UnblockKind | {
166163 assert_eq!( unblock, UnblockKind :: Ready ) ;
167164 // If we got unblocked, then our peer successfully upgraded its weak
168165 // ref to us. That means we can also upgrade our weak ref.
169166 let self_ref = weak_self_ref. upgrade( ) . unwrap( ) ;
170- anonsocket_write( self_ref, ptr, len, & dest , this )
167+ anonsocket_write( self_ref, ptr, len, this , finish )
171168 }
172169 ) ,
173170 ) ;
@@ -180,9 +177,9 @@ fn anonsocket_write<'tcx>(
180177 writebuf. clock . join ( clock) ;
181178 } ) ;
182179 // Do full write / partial write based on the space available.
183- let actual_write_size = len. min ( available_space) ;
184- let bytes = ecx. read_bytes_ptr_strip_provenance ( ptr , Size :: from_bytes ( len ) ) ? ;
185- writebuf . buf . extend ( & bytes [ .. actual_write_size] ) ;
180+ let write_size = len. min ( available_space) ;
181+ let actual_write_size = ecx. write_to_host ( & mut writebuf . buf , write_size , ptr ) ? . unwrap ( ) ;
182+ assert_eq ! ( actual_write_size, write_size ) ;
186183
187184 // Need to stop accessing peer_fd so that it can be notified.
188185 drop ( writebuf) ;
@@ -197,7 +194,7 @@ fn anonsocket_write<'tcx>(
197194 // The kernel does this even if the fd was already readable before, so we follow suit.
198195 ecx. check_and_update_readiness ( peer_fd) ?;
199196
200- return ecx . return_write_success ( actual_write_size , dest ) ;
197+ return finish . call ( ecx , Ok ( write_size ) ) ;
201198 }
202199 interp_ok ( ( ) )
203200}
0 commit comments