@@ -48,11 +48,85 @@ 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
+ let result = Write :: write ( self , bytes) ;
80
+ // Stdout is buffered, flush to make sure it appears on the
81
+ // screen. This is the write() syscall of the interpreted
82
+ // program, we want it to correspond to a write() syscall on
83
+ // the host -- there is no good in adding extra buffering
84
+ // here.
85
+ io:: stdout ( ) . flush ( ) . unwrap ( ) ;
86
+
87
+ Ok ( result)
88
+ }
89
+
90
+ fn seek ( & mut self , _offset : SeekFrom ) -> InterpResult < ' tcx , io:: Result < u64 > > {
91
+ throw_unsup_format ! ( "cannot seek on stdout" ) ;
92
+ }
93
+ }
94
+
95
+ impl < ' tcx > FileDescriptor < ' tcx > for io:: Stderr {
96
+ fn as_file_handle ( & self ) -> InterpResult < ' tcx , & FileHandle > {
97
+ throw_unsup_format ! ( "stdout cannot be used as FileHandle" ) ;
98
+ }
99
+
100
+ fn read ( & mut self , _bytes : & mut [ u8 ] ) -> InterpResult < ' tcx , io:: Result < usize > > {
101
+ throw_unsup_format ! ( "cannot read from stderr" ) ;
102
+ }
103
+
104
+ fn write ( & mut self , bytes : & [ u8 ] ) -> InterpResult < ' tcx , io:: Result < usize > > {
105
+ Ok ( Write :: write ( self , bytes) )
106
+ }
107
+
108
+ fn seek ( & mut self , _offset : SeekFrom ) -> InterpResult < ' tcx , io:: Result < u64 > > {
109
+ throw_unsup_format ! ( "cannot seek on stderr" ) ;
110
+ }
111
+ }
112
+
113
+ #[ derive( Debug ) ]
52
114
pub struct FileHandler < ' tcx > {
53
115
handles : BTreeMap < i32 , Box < dyn FileDescriptor < ' tcx > > > ,
54
116
}
55
117
118
+ impl < ' tcx > Default for FileHandler < ' tcx > {
119
+ fn default ( ) -> Self {
120
+ let mut handles = BTreeMap :: new ( ) ;
121
+ handles. insert ( 0i32 , Box :: new ( io:: stdin ( ) ) as Box < dyn FileDescriptor < ' _ > > ) ;
122
+ handles. insert ( 1i32 , Box :: new ( io:: stdout ( ) ) as Box < dyn FileDescriptor < ' _ > > ) ;
123
+ handles. insert ( 2i32 , Box :: new ( io:: stderr ( ) ) as Box < dyn FileDescriptor < ' _ > > ) ;
124
+ FileHandler {
125
+ handles
126
+ }
127
+ }
128
+ }
129
+
56
130
57
131
// fd numbers 0, 1, and 2 are reserved for stdin, stdout, and stderr
58
132
const MIN_NORMAL_FILE_FD : i32 = 3 ;
@@ -485,7 +559,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
485
559
let this = self . eval_context_mut ( ) ;
486
560
487
561
this. check_no_isolation ( "read" ) ?;
488
- assert ! ( fd >= 3 ) ;
489
562
490
563
trace ! ( "Reading from FD {}, size {}" , fd, count) ;
491
564
@@ -537,8 +610,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
537
610
) -> InterpResult < ' tcx , i64 > {
538
611
let this = self . eval_context_mut ( ) ;
539
612
540
- this. check_no_isolation ( "write" ) ?;
541
- assert ! ( fd >= 3 ) ;
613
+ if fd >= 3 {
614
+ this. check_no_isolation ( "write" ) ?;
615
+ }
542
616
543
617
// Check that the *entire* buffer is actually valid memory.
544
618
this. memory . check_ptr_access (
0 commit comments