@@ -595,7 +595,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
595595 let communicate = this. machine . communicate ( ) ;
596596
597597 let Some ( fd) = this. machine . fds . get ( fd_num) else {
598- return interp_ok ( Scalar :: from_i64 ( this. fd_not_found ( ) ? ) ) ;
598+ return this. set_last_error_and_return_i64 ( LibcError ( "EBADF" ) ) ;
599599 } ;
600600 let result = fd. seek ( communicate, seek_from) ?. map ( |offset| i64:: try_from ( offset) . unwrap ( ) ) ;
601601 drop ( fd) ;
@@ -671,8 +671,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
671671
672672 // `stat` always follows symlinks.
673673 let metadata = match FileMetadata :: from_path ( this, & path, true ) ? {
674- Some ( metadata) => metadata,
675- None => return interp_ok ( Scalar :: from_i32 ( - 1 ) ) , // `FileMetadata` has set errno
674+ Ok ( metadata) => metadata,
675+ Err ( err ) => return this . set_last_error_and_return_i32 ( err ) ,
676676 } ;
677677
678678 interp_ok ( Scalar :: from_i32 ( this. macos_stat_write_buf ( metadata, buf_op) ?) )
@@ -700,8 +700,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
700700 }
701701
702702 let metadata = match FileMetadata :: from_path ( this, & path, false ) ? {
703- Some ( metadata) => metadata,
704- None => return interp_ok ( Scalar :: from_i32 ( - 1 ) ) , // `FileMetadata` has set errno
703+ Ok ( metadata) => metadata,
704+ Err ( err ) => return this . set_last_error_and_return_i32 ( err ) ,
705705 } ;
706706
707707 interp_ok ( Scalar :: from_i32 ( this. macos_stat_write_buf ( metadata, buf_op) ?) )
@@ -724,12 +724,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
724724 if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
725725 this. reject_in_isolation ( "`fstat`" , reject_with) ?;
726726 // Set error code as "EBADF" (bad fd)
727- return interp_ok ( Scalar :: from_i32 ( this. fd_not_found ( ) ? ) ) ;
727+ return this. set_last_error_and_return_i32 ( LibcError ( "EBADF" ) ) ;
728728 }
729729
730730 let metadata = match FileMetadata :: from_fd_num ( this, fd) ? {
731- Some ( metadata) => metadata,
732- None => return interp_ok ( Scalar :: from_i32 ( - 1 ) ) ,
731+ Ok ( metadata) => metadata,
732+ Err ( err ) => return this . set_last_error_and_return_i32 ( err ) ,
733733 } ;
734734 interp_ok ( Scalar :: from_i32 ( this. macos_stat_write_buf ( metadata, buf_op) ?) )
735735 }
@@ -816,8 +816,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
816816 FileMetadata :: from_path ( this, & path, follow_symlink) ?
817817 } ;
818818 let metadata = match metadata {
819- Some ( metadata) => metadata,
820- None => return interp_ok ( Scalar :: from_i32 ( - 1 ) ) ,
819+ Ok ( metadata) => metadata,
820+ Err ( err ) => return this . set_last_error_and_return_i32 ( err ) ,
821821 } ;
822822
823823 // The `mode` field specifies the type of the file and the permissions over the file for
@@ -1131,7 +1131,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
11311131 if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
11321132 this. reject_in_isolation ( "`readdir_r`" , reject_with) ?;
11331133 // Set error code as "EBADF" (bad fd)
1134- return interp_ok ( Scalar :: from_i32 ( this. fd_not_found ( ) ? ) ) ;
1134+ return this. set_last_error_and_return_i32 ( LibcError ( "EBADF" ) ) ;
11351135 }
11361136
11371137 let open_dir = this. machine . dirs . streams . get_mut ( & dirp) . ok_or_else ( || {
@@ -1242,20 +1242,20 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
12421242 let dirp = this. read_target_usize ( dirp_op) ?;
12431243
12441244 // Reject if isolation is enabled.
1245- interp_ok ( Scalar :: from_i32 (
1246- if let IsolatedOp :: Reject ( reject_with ) = this. machine . isolated_op {
1247- this. reject_in_isolation ( "`closedir`" , reject_with ) ? ;
1248- this . fd_not_found ( ) ?
1249- } else if let Some ( open_dir ) = this . machine . dirs . streams . remove ( & dirp ) {
1250- if let Some ( entry ) = open_dir . entry {
1251- this. deallocate_ptr ( entry , None , MiriMemoryKind :: Runtime . into ( ) ) ? ;
1252- }
1253- drop ( open_dir) ;
1254- 0
1255- } else {
1256- this . fd_not_found ( ) ?
1257- } ,
1258- ) )
1245+ if let IsolatedOp :: Reject ( reject_with ) = this . machine . isolated_op {
1246+ this. reject_in_isolation ( "`closedir`" , reject_with ) ? ;
1247+ return this. set_last_error_and_return_i32 ( LibcError ( "EBADF" ) ) ;
1248+ }
1249+
1250+ let Some ( open_dir ) = this . machine . dirs . streams . remove ( & dirp ) else {
1251+ return this. set_last_error_and_return_i32 ( LibcError ( "EBADF" ) ) ;
1252+ } ;
1253+ if let Some ( entry ) = open_dir. entry {
1254+ this . deallocate_ptr ( entry , None , MiriMemoryKind :: Runtime . into ( ) ) ? ;
1255+ }
1256+ drop ( open_dir ) ;
1257+
1258+ interp_ok ( Scalar :: from_i32 ( 0 ) )
12591259 }
12601260
12611261 fn ftruncate64 ( & mut self , fd_num : i32 , length : i128 ) -> InterpResult < ' tcx , Scalar > {
@@ -1265,11 +1265,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
12651265 if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
12661266 this. reject_in_isolation ( "`ftruncate64`" , reject_with) ?;
12671267 // Set error code as "EBADF" (bad fd)
1268- return interp_ok ( Scalar :: from_i32 ( this. fd_not_found ( ) ? ) ) ;
1268+ return this. set_last_error_and_return_i32 ( LibcError ( "EBADF" ) ) ;
12691269 }
12701270
12711271 let Some ( fd) = this. machine . fds . get ( fd_num) else {
1272- return interp_ok ( Scalar :: from_i32 ( this. fd_not_found ( ) ? ) ) ;
1272+ return this. set_last_error_and_return_i32 ( LibcError ( "EBADF" ) ) ;
12731273 } ;
12741274
12751275 // FIXME: Support ftruncate64 for all FDs
@@ -1308,7 +1308,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
13081308 if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
13091309 this. reject_in_isolation ( "`fsync`" , reject_with) ?;
13101310 // Set error code as "EBADF" (bad fd)
1311- return interp_ok ( Scalar :: from_i32 ( this. fd_not_found ( ) ? ) ) ;
1311+ return this. set_last_error_and_return_i32 ( LibcError ( "EBADF" ) ) ;
13121312 }
13131313
13141314 self . ffullsync_fd ( fd)
@@ -1317,7 +1317,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
13171317 fn ffullsync_fd ( & mut self , fd_num : i32 ) -> InterpResult < ' tcx , Scalar > {
13181318 let this = self . eval_context_mut ( ) ;
13191319 let Some ( fd) = this. machine . fds . get ( fd_num) else {
1320- return interp_ok ( Scalar :: from_i32 ( this. fd_not_found ( ) ? ) ) ;
1320+ return this. set_last_error_and_return_i32 ( LibcError ( "EBADF" ) ) ;
13211321 } ;
13221322 // Only regular files support synchronization.
13231323 let FileHandle { file, writable } = fd. downcast :: < FileHandle > ( ) . ok_or_else ( || {
@@ -1337,11 +1337,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
13371337 if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
13381338 this. reject_in_isolation ( "`fdatasync`" , reject_with) ?;
13391339 // Set error code as "EBADF" (bad fd)
1340- return interp_ok ( Scalar :: from_i32 ( this. fd_not_found ( ) ? ) ) ;
1340+ return this. set_last_error_and_return_i32 ( LibcError ( "EBADF" ) ) ;
13411341 }
13421342
13431343 let Some ( fd) = this. machine . fds . get ( fd) else {
1344- return interp_ok ( Scalar :: from_i32 ( this. fd_not_found ( ) ? ) ) ;
1344+ return this. set_last_error_and_return_i32 ( LibcError ( "EBADF" ) ) ;
13451345 } ;
13461346 // Only regular files support synchronization.
13471347 let FileHandle { file, writable } = fd. downcast :: < FileHandle > ( ) . ok_or_else ( || {
@@ -1380,11 +1380,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
13801380 if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
13811381 this. reject_in_isolation ( "`sync_file_range`" , reject_with) ?;
13821382 // Set error code as "EBADF" (bad fd)
1383- return interp_ok ( Scalar :: from_i32 ( this. fd_not_found ( ) ? ) ) ;
1383+ return this. set_last_error_and_return_i32 ( LibcError ( "EBADF" ) ) ;
13841384 }
13851385
13861386 let Some ( fd) = this. machine . fds . get ( fd) else {
1387- return interp_ok ( Scalar :: from_i32 ( this. fd_not_found ( ) ? ) ) ;
1387+ return this. set_last_error_and_return_i32 ( LibcError ( "EBADF" ) ) ;
13881388 } ;
13891389 // Only regular files support synchronization.
13901390 let FileHandle { file, writable } = fd. downcast :: < FileHandle > ( ) . ok_or_else ( || {
@@ -1667,7 +1667,7 @@ impl FileMetadata {
16671667 ecx : & mut MiriInterpCx < ' tcx > ,
16681668 path : & Path ,
16691669 follow_symlink : bool ,
1670- ) -> InterpResult < ' tcx , Option < FileMetadata > > {
1670+ ) -> InterpResult < ' tcx , Result < FileMetadata , IoError > > {
16711671 let metadata =
16721672 if follow_symlink { std:: fs:: metadata ( path) } else { std:: fs:: symlink_metadata ( path) } ;
16731673
@@ -1677,9 +1677,9 @@ impl FileMetadata {
16771677 fn from_fd_num < ' tcx > (
16781678 ecx : & mut MiriInterpCx < ' tcx > ,
16791679 fd_num : i32 ,
1680- ) -> InterpResult < ' tcx , Option < FileMetadata > > {
1680+ ) -> InterpResult < ' tcx , Result < FileMetadata , IoError > > {
16811681 let Some ( fd) = ecx. machine . fds . get ( fd_num) else {
1682- return ecx . fd_not_found ( ) . map ( |_ : i32 | None ) ;
1682+ return interp_ok ( Err ( LibcError ( "EBADF" ) ) ) ;
16831683 } ;
16841684
16851685 let file = & fd
@@ -1699,12 +1699,11 @@ impl FileMetadata {
16991699 fn from_meta < ' tcx > (
17001700 ecx : & mut MiriInterpCx < ' tcx > ,
17011701 metadata : Result < std:: fs:: Metadata , std:: io:: Error > ,
1702- ) -> InterpResult < ' tcx , Option < FileMetadata > > {
1702+ ) -> InterpResult < ' tcx , Result < FileMetadata , IoError > > {
17031703 let metadata = match metadata {
17041704 Ok ( metadata) => metadata,
17051705 Err ( e) => {
1706- ecx. set_last_error ( e) ?;
1707- return interp_ok ( None ) ;
1706+ return interp_ok ( Err ( e. into ( ) ) ) ;
17081707 }
17091708 } ;
17101709
@@ -1727,6 +1726,6 @@ impl FileMetadata {
17271726 let modified = extract_sec_and_nsec ( metadata. modified ( ) ) ?;
17281727
17291728 // FIXME: Provide more fields using platform specific methods.
1730- interp_ok ( Some ( FileMetadata { mode, size, created, accessed, modified } ) )
1729+ interp_ok ( Ok ( FileMetadata { mode, size, created, accessed, modified } ) )
17311730 }
17321731}
0 commit comments