@@ -328,22 +328,18 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
328328
329329 this. check_no_isolation ( "fcntl" ) ?;
330330
331- let ( fd, cmd, start) = if args. len ( ) == 2 {
332- let & [ fd, cmd] = check_arg_count ( args) ?;
333- ( fd, cmd, None )
334- } else {
335- // If args.len() isn't 2 or 3 this will error appropriately.
336- let & [ fd, cmd, start] = check_arg_count ( args) ?;
337- ( fd, cmd, Some ( start) )
338- } ;
339- let fd = this. read_scalar ( fd) ?. to_i32 ( ) ?;
340- let cmd = this. read_scalar ( cmd) ?. to_i32 ( ) ?;
331+ if args. len ( ) < 2 {
332+ throw_ub_format ! ( "incorrect number of arguments for fcntl: got {}, expected at least 2" , args. len( ) ) ;
333+ }
334+ let cmd = this. read_scalar ( args[ 1 ] ) ?. to_i32 ( ) ?;
341335 // We only support getting the flags for a descriptor.
342336 if cmd == this. eval_libc_i32 ( "F_GETFD" ) ? {
343337 // Currently this is the only flag that `F_GETFD` returns. It is OK to just return the
344338 // `FD_CLOEXEC` value without checking if the flag is set for the file because `std`
345339 // always sets this flag when opening a file. However we still need to check that the
346340 // file itself is open.
341+ let & [ fd, _] = check_arg_count ( args) ?;
342+ let fd = this. read_scalar ( fd) ?. to_i32 ( ) ?;
347343 if this. machine . file_handler . handles . contains_key ( & fd) {
348344 Ok ( this. eval_libc_i32 ( "FD_CLOEXEC" ) ?)
349345 } else {
@@ -356,15 +352,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
356352 // because exec() isn't supported. The F_DUPFD and F_DUPFD_CLOEXEC commands only
357353 // differ in whether the FD_CLOEXEC flag is pre-set on the new file descriptor,
358354 // thus they can share the same implementation here.
355+ let & [ fd, _, start] = check_arg_count ( args) ?;
356+ let fd = this. read_scalar ( fd) ?. to_i32 ( ) ?;
357+ let start = this. read_scalar ( start) ?. to_i32 ( ) ?;
359358 if fd < MIN_NORMAL_FILE_FD {
360359 throw_unsup_format ! ( "duplicating file descriptors for stdin, stdout, or stderr is not supported" )
361360 }
362- let start = start. ok_or_else ( || {
363- err_unsup_format ! (
364- "fcntl with command F_DUPFD or F_DUPFD_CLOEXEC requires a third argument"
365- )
366- } ) ?;
367- let start = this. read_scalar ( start) ?. to_i32 ( ) ?;
368361 let fh = & mut this. machine . file_handler ;
369362 let ( file_result, writable) = match fh. handles . get ( & fd) {
370363 Some ( FileHandle { file, writable } ) => ( file. try_clone ( ) , * writable) ,
0 commit comments