@@ -163,7 +163,7 @@ impl FileDescription for AnonSocket {
163
163
} else {
164
164
// Blocking socketpair with writer and empty buffer.
165
165
// FIXME: blocking is currently not supported
166
- throw_unsup_format ! ( "socketpair read: blocking isn't supported yet" ) ;
166
+ throw_unsup_format ! ( "socketpair/pipe/pipe2 read: blocking isn't supported yet" ) ;
167
167
}
168
168
}
169
169
}
@@ -230,7 +230,7 @@ impl FileDescription for AnonSocket {
230
230
return ecx. set_last_error_and_return ( ErrorKind :: WouldBlock , dest) ;
231
231
} else {
232
232
// Blocking socketpair with a full buffer.
233
- throw_unsup_format ! ( "socketpair write: blocking isn't supported yet" ) ;
233
+ throw_unsup_format ! ( "socketpair/pipe/pipe2 write: blocking isn't supported yet" ) ;
234
234
}
235
235
}
236
236
// Remember this clock so `read` can synchronize with us.
@@ -267,21 +267,24 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
267
267
let this = self . eval_context_mut ( ) ;
268
268
269
269
let domain = this. read_scalar ( domain) ?. to_i32 ( ) ?;
270
- let mut type_ = this. read_scalar ( type_) ?. to_i32 ( ) ?;
270
+ let mut flags = this. read_scalar ( type_) ?. to_i32 ( ) ?;
271
271
let protocol = this. read_scalar ( protocol) ?. to_i32 ( ) ?;
272
272
let sv = this. deref_pointer ( sv) ?;
273
273
274
274
let mut is_sock_nonblock = false ;
275
275
276
- // Parse and remove the type flags that we support.
277
- // SOCK_NONBLOCK only exists on Linux .
276
+ // Interpret the flag. Every flag we recognize is "subtracted" from `flags`, so
277
+ // if there is anything left at the end, that's an unsupported flag .
278
278
if this. tcx . sess . target . os == "linux" {
279
- if type_ & this. eval_libc_i32 ( "SOCK_NONBLOCK" ) == this. eval_libc_i32 ( "SOCK_NONBLOCK" ) {
279
+ // SOCK_NONBLOCK only exists on Linux.
280
+ let sock_nonblock = this. eval_libc_i32 ( "SOCK_NONBLOCK" ) ;
281
+ let sock_cloexec = this. eval_libc_i32 ( "SOCK_CLOEXEC" ) ;
282
+ if flags & sock_nonblock == sock_nonblock {
280
283
is_sock_nonblock = true ;
281
- type_ &= !( this . eval_libc_i32 ( "SOCK_NONBLOCK" ) ) ;
284
+ flags &= !sock_nonblock ;
282
285
}
283
- if type_ & this . eval_libc_i32 ( "SOCK_CLOEXEC" ) == this . eval_libc_i32 ( "SOCK_CLOEXEC" ) {
284
- type_ &= !( this . eval_libc_i32 ( "SOCK_CLOEXEC" ) ) ;
286
+ if flags & sock_cloexec == sock_cloexec {
287
+ flags &= !sock_cloexec ;
285
288
}
286
289
}
287
290
@@ -294,11 +297,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
294
297
and AF_LOCAL are allowed",
295
298
domain
296
299
) ;
297
- } else if type_ != this. eval_libc_i32 ( "SOCK_STREAM" ) {
300
+ } else if flags != this. eval_libc_i32 ( "SOCK_STREAM" ) {
298
301
throw_unsup_format ! (
299
302
"socketpair: type {:#x} is unsupported, only SOCK_STREAM, \
300
303
SOCK_CLOEXEC and SOCK_NONBLOCK are allowed",
301
- type_
304
+ flags
302
305
) ;
303
306
} else if protocol != 0 {
304
307
throw_unsup_format ! (
@@ -347,14 +350,26 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
347
350
let this = self . eval_context_mut ( ) ;
348
351
349
352
let pipefd = this. deref_pointer_as ( pipefd, this. machine . layouts . i32 ) ?;
350
- let flags = match flags {
353
+ let mut flags = match flags {
351
354
Some ( flags) => this. read_scalar ( flags) ?. to_i32 ( ) ?,
352
355
None => 0 ,
353
356
} ;
354
357
355
- // As usual we ignore CLOEXEC.
356
358
let cloexec = this. eval_libc_i32 ( "O_CLOEXEC" ) ;
357
- if flags != 0 && flags != cloexec {
359
+ let o_nonblock = this. eval_libc_i32 ( "O_NONBLOCK" ) ;
360
+
361
+ // Interpret the flag. Every flag we recognize is "subtracted" from `flags`, so
362
+ // if there is anything left at the end, that's an unsupported flag.
363
+ let mut is_nonblock = false ;
364
+ if flags & o_nonblock == o_nonblock {
365
+ is_nonblock = true ;
366
+ flags &= !o_nonblock;
367
+ }
368
+ // As usual we ignore CLOEXEC.
369
+ if flags & cloexec == cloexec {
370
+ flags &= !cloexec;
371
+ }
372
+ if flags != 0 {
358
373
throw_unsup_format ! ( "unsupported flags in `pipe2`" ) ;
359
374
}
360
375
@@ -365,13 +380,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
365
380
readbuf : Some ( RefCell :: new ( Buffer :: new ( ) ) ) ,
366
381
peer_fd : OnceCell :: new ( ) ,
367
382
peer_lost_data : Cell :: new ( false ) ,
368
- is_nonblock : false ,
383
+ is_nonblock,
369
384
} ) ;
370
385
let fd1 = fds. new_ref ( AnonSocket {
371
386
readbuf : None ,
372
387
peer_fd : OnceCell :: new ( ) ,
373
388
peer_lost_data : Cell :: new ( false ) ,
374
- is_nonblock : false ,
389
+ is_nonblock,
375
390
} ) ;
376
391
377
392
// Make the file descriptions point to each other.
0 commit comments