@@ -48,11 +48,77 @@ impl<'tcx> FileDescriptor<'tcx> for FileHandle {
4848 }
4949}
5050
51- #[ derive( Debug , Default ) ]
51+ impl < ' tcx > FileDescriptor < ' tcx > for io:: Stdin {
52+ fn as_file_handle ( & self ) -> InterpResult < ' tcx , & FileHandle > {
53+ throw_unsup_format ! ( "stdin cannot be used as FileHandle" ) ;
54+ }
55+
56+ fn read ( & mut self , bytes : & mut [ u8 ] ) -> InterpResult < ' tcx , io:: Result < usize > > {
57+ Ok ( Read :: read ( self , bytes) )
58+ }
59+
60+ fn write ( & mut self , _bytes : & [ u8 ] ) -> InterpResult < ' tcx , io:: Result < usize > > {
61+ throw_unsup_format ! ( "cannot write to stdin" ) ;
62+ }
63+
64+ fn seek ( & mut self , _offset : SeekFrom ) -> InterpResult < ' tcx , io:: Result < u64 > > {
65+ throw_unsup_format ! ( "cannot seek on stdin" ) ;
66+ }
67+ }
68+
69+ impl < ' tcx > FileDescriptor < ' tcx > for io:: Stdout {
70+ fn as_file_handle ( & self ) -> InterpResult < ' tcx , & FileHandle > {
71+ throw_unsup_format ! ( "stdout cannot be used as FileHandle" ) ;
72+ }
73+
74+ fn read ( & mut self , _bytes : & mut [ u8 ] ) -> InterpResult < ' tcx , io:: Result < usize > > {
75+ throw_unsup_format ! ( "cannot read from stdout" ) ;
76+ }
77+
78+ fn write ( & mut self , bytes : & [ u8 ] ) -> InterpResult < ' tcx , io:: Result < usize > > {
79+ Ok ( Write :: write ( self , bytes) )
80+ }
81+
82+ fn seek ( & mut self , _offset : SeekFrom ) -> InterpResult < ' tcx , io:: Result < u64 > > {
83+ throw_unsup_format ! ( "cannot seek on stdout" ) ;
84+ }
85+ }
86+
87+ impl < ' tcx > FileDescriptor < ' tcx > for io:: Stderr {
88+ fn as_file_handle ( & self ) -> InterpResult < ' tcx , & FileHandle > {
89+ throw_unsup_format ! ( "stdout cannot be used as FileHandle" ) ;
90+ }
91+
92+ fn read ( & mut self , _bytes : & mut [ u8 ] ) -> InterpResult < ' tcx , io:: Result < usize > > {
93+ throw_unsup_format ! ( "cannot read from stderr" ) ;
94+ }
95+
96+ fn write ( & mut self , bytes : & [ u8 ] ) -> InterpResult < ' tcx , io:: Result < usize > > {
97+ Ok ( Write :: write ( self , bytes) )
98+ }
99+
100+ fn seek ( & mut self , _offset : SeekFrom ) -> InterpResult < ' tcx , io:: Result < u64 > > {
101+ throw_unsup_format ! ( "cannot seek on stderr" ) ;
102+ }
103+ }
104+
105+ #[ derive( Debug ) ]
52106pub struct FileHandler < ' tcx > {
53107 handles : BTreeMap < i32 , Box < dyn FileDescriptor < ' tcx > > > ,
54108}
55109
110+ impl < ' tcx > Default for FileHandler < ' tcx > {
111+ fn default ( ) -> Self {
112+ let mut handles = BTreeMap :: new ( ) ;
113+ handles. insert ( 0i32 , Box :: new ( io:: stdin ( ) ) as Box < dyn FileDescriptor < ' _ > > ) ;
114+ handles. insert ( 1i32 , Box :: new ( io:: stdout ( ) ) as Box < dyn FileDescriptor < ' _ > > ) ;
115+ handles. insert ( 2i32 , Box :: new ( io:: stderr ( ) ) as Box < dyn FileDescriptor < ' _ > > ) ;
116+ FileHandler {
117+ handles
118+ }
119+ }
120+ }
121+
56122
57123// fd numbers 0, 1, and 2 are reserved for stdin, stdout, and stderr
58124const MIN_NORMAL_FILE_FD : i32 = 3 ;
@@ -485,7 +551,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
485551 let this = self . eval_context_mut ( ) ;
486552
487553 this. check_no_isolation ( "read" ) ?;
488- assert ! ( fd >= 3 ) ;
489554
490555 trace ! ( "Reading from FD {}, size {}" , fd, count) ;
491556
@@ -537,8 +602,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
537602 ) -> InterpResult < ' tcx , i64 > {
538603 let this = self . eval_context_mut ( ) ;
539604
540- this. check_no_isolation ( "write" ) ?;
541- assert ! ( fd >= 3 ) ;
605+ if fd >= 3 {
606+ this. check_no_isolation ( "write" ) ?;
607+ }
542608
543609 // Check that the *entire* buffer is actually valid memory.
544610 this. memory . check_ptr_access (
0 commit comments