1
1
use gdbstub:: target;
2
- use std:: io:: { Read , Seek , Write } ;
3
-
4
- use crate :: emu:: { Emu , FD_MAX } ;
5
-
6
2
use gdbstub:: target:: ext:: host_io:: {
7
3
FsKind , HostIoErrno , HostIoError , HostIoOpenFlags , HostIoOpenMode , HostIoOutput , HostIoResult ,
8
4
HostIoStat , HostIoToken ,
9
5
} ;
6
+ use std:: io:: { Read , Seek , Write } ;
7
+
8
+ use crate :: emu:: Emu ;
10
9
11
10
impl target:: ext:: host_io:: HostIo for Emu {
12
11
#[ inline( always) ]
@@ -29,6 +28,11 @@ impl target::ext::host_io::HostIo for Emu {
29
28
Some ( self )
30
29
}
31
30
31
+ #[ inline( always) ]
32
+ fn enable_fstat ( & mut self ) -> Option < target:: ext:: host_io:: HostIoFstatOps < Self > > {
33
+ Some ( self )
34
+ }
35
+
32
36
#[ inline( always) ]
33
37
fn enable_unlink ( & mut self ) -> Option < target:: ext:: host_io:: HostIoUnlinkOps < Self > > {
34
38
Some ( self )
@@ -52,10 +56,12 @@ impl target::ext::host_io::HostIoOpen for Emu {
52
56
flags : HostIoOpenFlags ,
53
57
_mode : HostIoOpenMode ,
54
58
) -> HostIoResult < u32 , Self > {
55
- let path = match std:: str:: from_utf8 ( filename) {
56
- Ok ( v) => v,
57
- Err ( _) => return Err ( HostIoError :: Errno ( HostIoErrno :: ENOENT ) ) ,
58
- } ;
59
+ if filename. starts_with ( b"/proc" ) {
60
+ return Err ( HostIoError :: Errno ( HostIoErrno :: ENOENT ) ) ;
61
+ }
62
+
63
+ let path =
64
+ std:: str:: from_utf8 ( filename) . map_err ( |_| HostIoError :: Errno ( HostIoErrno :: ENOENT ) ) ?;
59
65
60
66
let mut read = false ;
61
67
let mut write = false ;
@@ -77,27 +83,35 @@ impl target::ext::host_io::HostIoOpen for Emu {
77
83
. create_new ( flags. contains ( HostIoOpenFlags :: O_EXCL ) )
78
84
. open ( path) ?;
79
85
80
- let n = 0 ;
81
- for n in 0 .. FD_MAX {
82
- if self . files [ n as usize ] . is_none ( ) {
83
- break ;
86
+ let n = match self . files . iter_mut ( ) . enumerate ( ) . find ( | ( _ , f ) | f . is_none ( ) ) {
87
+ Some ( ( n , free_file ) ) => {
88
+ * free_file = Some ( file ) ;
89
+ n
84
90
}
85
- }
86
- if n == FD_MAX {
87
- return Err ( HostIoError :: Errno ( HostIoErrno :: ENFILE ) ) ;
88
- }
91
+ None => {
92
+ self . files . push ( Some ( file) ) ;
93
+ self . files . len ( ) - 1
94
+ }
95
+ } ;
89
96
90
- self . files [ n as usize ] = Some ( file) ;
91
- Ok ( n)
97
+ Ok ( n as u32 )
92
98
}
93
99
}
94
100
95
101
impl target:: ext:: host_io:: HostIoClose for Emu {
96
102
fn close ( & mut self , fd : u32 ) -> HostIoResult < ( ) , Self > {
97
- if fd < FD_MAX {
98
- self . files [ fd as usize ]
99
- . take ( )
100
- . ok_or ( HostIoError :: Errno ( HostIoErrno :: EBADF ) ) ?;
103
+ let fd: usize = fd as usize ;
104
+ if fd < self . files . len ( ) {
105
+ if fd == self . files . len ( ) - 1 {
106
+ self . files . pop ( ) ;
107
+ while let Some ( None ) = self . files . last ( ) {
108
+ self . files . pop ( ) ;
109
+ }
110
+ } else {
111
+ self . files [ fd]
112
+ . take ( )
113
+ . ok_or ( HostIoError :: Errno ( HostIoErrno :: EBADF ) ) ?;
114
+ }
101
115
Ok ( ( ) )
102
116
} else {
103
117
Err ( HostIoError :: Errno ( HostIoErrno :: EBADF ) )
@@ -113,8 +127,9 @@ impl target::ext::host_io::HostIoPread for Emu {
113
127
offset : u32 ,
114
128
output : HostIoOutput < ' a > ,
115
129
) -> HostIoResult < HostIoToken < ' a > , Self > {
116
- if fd < FD_MAX {
117
- if let Some ( ref mut file) = self . files [ fd as usize ] {
130
+ let fd: usize = fd as usize ;
131
+ if fd < self . files . len ( ) {
132
+ if let Some ( ref mut file) = self . files [ fd] {
118
133
let mut buffer = vec ! [ 0 ; count as usize ] ;
119
134
file. seek ( std:: io:: SeekFrom :: Start ( offset as u64 ) ) ?;
120
135
let n = file. read ( & mut buffer) ?;
@@ -130,8 +145,9 @@ impl target::ext::host_io::HostIoPread for Emu {
130
145
131
146
impl target:: ext:: host_io:: HostIoPwrite for Emu {
132
147
fn pwrite ( & mut self , fd : u32 , offset : u32 , data : & [ u8 ] ) -> HostIoResult < u32 , Self > {
133
- if fd < FD_MAX {
134
- if let Some ( ref mut file) = self . files [ fd as usize ] {
148
+ let fd: usize = fd as usize ;
149
+ if fd < self . files . len ( ) {
150
+ if let Some ( ref mut file) = self . files [ fd] {
135
151
file. seek ( std:: io:: SeekFrom :: Start ( offset as u64 ) ) ?;
136
152
let n = file. write ( data) ?;
137
153
Ok ( n as u32 )
@@ -146,27 +162,22 @@ impl target::ext::host_io::HostIoPwrite for Emu {
146
162
147
163
impl target:: ext:: host_io:: HostIoFstat for Emu {
148
164
fn fstat ( & mut self , fd : u32 ) -> HostIoResult < HostIoStat , Self > {
149
- if fd < FD_MAX {
150
- if let Some ( ref mut file) = self . files [ fd as usize ] {
165
+ let fd: usize = fd as usize ;
166
+ if fd < self . files . len ( ) {
167
+ if let Some ( ref mut file) = self . files [ fd] {
151
168
let metadata = file. metadata ( ) ?;
152
- let atime = metadata
153
- . accessed ( )
154
- . map_err ( |_| HostIoError :: Errno ( HostIoErrno :: EACCES ) ) ?
155
- . duration_since ( std:: time:: SystemTime :: UNIX_EPOCH )
156
- . map_err ( |_| HostIoError :: Errno ( HostIoErrno :: EACCES ) ) ?
157
- . as_secs ( ) as u32 ;
158
- let mtime = metadata
159
- . modified ( )
160
- . map_err ( |_| HostIoError :: Errno ( HostIoErrno :: EACCES ) ) ?
161
- . duration_since ( std:: time:: SystemTime :: UNIX_EPOCH )
162
- . map_err ( |_| HostIoError :: Errno ( HostIoErrno :: EACCES ) ) ?
163
- . as_secs ( ) as u32 ;
164
- let ctime = metadata
165
- . created ( )
166
- . map_err ( |_| HostIoError :: Errno ( HostIoErrno :: EACCES ) ) ?
167
- . duration_since ( std:: time:: SystemTime :: UNIX_EPOCH )
168
- . map_err ( |_| HostIoError :: Errno ( HostIoErrno :: EACCES ) ) ?
169
- . as_secs ( ) as u32 ;
169
+ macro_rules! time_to_secs {
170
+ ( $time: expr) => {
171
+ $time
172
+ . map_err( |_| HostIoError :: Errno ( HostIoErrno :: EACCES ) ) ?
173
+ . duration_since( std:: time:: SystemTime :: UNIX_EPOCH )
174
+ . map_err( |_| HostIoError :: Errno ( HostIoErrno :: EACCES ) ) ?
175
+ . as_secs( ) as u32
176
+ } ;
177
+ }
178
+ let atime = time_to_secs ! ( metadata. accessed( ) ) ;
179
+ let mtime = time_to_secs ! ( metadata. modified( ) ) ;
180
+ let ctime = time_to_secs ! ( metadata. created( ) ) ;
170
181
Ok ( HostIoStat {
171
182
st_dev : 0 ,
172
183
st_ino : 0 ,
@@ -193,10 +204,8 @@ impl target::ext::host_io::HostIoFstat for Emu {
193
204
194
205
impl target:: ext:: host_io:: HostIoUnlink for Emu {
195
206
fn unlink ( & mut self , filename : & [ u8 ] ) -> HostIoResult < ( ) , Self > {
196
- let path = match std:: str:: from_utf8 ( filename) {
197
- Ok ( v) => v,
198
- Err ( _) => return Err ( HostIoError :: Errno ( HostIoErrno :: ENOENT ) ) ,
199
- } ;
207
+ let path =
208
+ std:: str:: from_utf8 ( filename) . map_err ( |_| HostIoError :: Errno ( HostIoErrno :: ENOENT ) ) ?;
200
209
std:: fs:: remove_file ( path) ?;
201
210
Ok ( ( ) )
202
211
}
@@ -214,12 +223,12 @@ impl target::ext::host_io::HostIoReadlink for Emu {
214
223
} else if filename == b"/proc/1/cwd" {
215
224
// Support `info proc cwd` command
216
225
return Ok ( output. write ( b"/" ) ) ;
226
+ } else if filename. starts_with ( b"/proc" ) {
227
+ return Err ( HostIoError :: Errno ( HostIoErrno :: ENOENT ) ) ;
217
228
}
218
229
219
- let path = match std:: str:: from_utf8 ( filename) {
220
- Ok ( v) => v,
221
- Err ( _) => return Err ( HostIoError :: Errno ( HostIoErrno :: ENOENT ) ) ,
222
- } ;
230
+ let path =
231
+ std:: str:: from_utf8 ( filename) . map_err ( |_| HostIoError :: Errno ( HostIoErrno :: ENOENT ) ) ?;
223
232
Ok ( output. write (
224
233
std:: fs:: read_link ( path) ?
225
234
. to_str ( )
0 commit comments