@@ -48,11 +48,77 @@ impl<'tcx> FileDescriptor<'tcx> for FileHandle {
48
48
}
49
49
}
50
50
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 ) ]
52
106
pub struct FileHandler < ' tcx > {
53
107
handles : BTreeMap < i32 , Box < dyn FileDescriptor < ' tcx > > > ,
54
108
}
55
109
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
+
56
122
57
123
// fd numbers 0, 1, and 2 are reserved for stdin, stdout, and stderr
58
124
const MIN_NORMAL_FILE_FD : i32 = 3 ;
@@ -485,7 +551,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
485
551
let this = self . eval_context_mut ( ) ;
486
552
487
553
this. check_no_isolation ( "read" ) ?;
488
- assert ! ( fd >= 3 ) ;
489
554
490
555
trace ! ( "Reading from FD {}, size {}" , fd, count) ;
491
556
@@ -537,8 +602,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
537
602
) -> InterpResult < ' tcx , i64 > {
538
603
let this = self . eval_context_mut ( ) ;
539
604
540
- this. check_no_isolation ( "write" ) ?;
541
- assert ! ( fd >= 3 ) ;
605
+ if fd >= 3 {
606
+ this. check_no_isolation ( "write" ) ?;
607
+ }
542
608
543
609
// Check that the *entire* buffer is actually valid memory.
544
610
this. memory . check_ptr_access (
0 commit comments