Commit | Line | Data |
---|---|---|
a1dc3945 AC |
1 | /* This file is part of the program psim. |
2 | ||
3 | Copyright (C) 1994-1997, Andrew Cagney <cagney@highland.com.au> | |
844f40d3 | 4 | Copyright (C) 1998, Cygnus Solutions. |
a1dc3945 AC |
5 | |
6 | This program is free software; you can redistribute it and/or modify | |
7 | it under the terms of the GNU General Public License as published by | |
8 | the Free Software Foundation; either version 2 of the License, or | |
9 | (at your option) any later version. | |
10 | ||
11 | This program is distributed in the hope that it will be useful, | |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | GNU General Public License for more details. | |
15 | ||
16 | You should have received a copy of the GNU General Public License | |
17 | along with this program; if not, write to the Free Software | |
18 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
19 | ||
20 | */ | |
21 | ||
22 | ||
69628a60 MM |
23 | #include "sim-main.h" |
24 | #include "sim-io.h" | |
25 | #include "targ-vals.h" | |
a1dc3945 | 26 | |
844f40d3 AC |
27 | #if HAVE_FCNTL_H |
28 | #include <fcntl.h> | |
29 | #endif | |
30 | ||
31 | ||
a1dc3945 AC |
32 | /* See the file include/callbacks.h for a description */ |
33 | ||
34 | ||
69628a60 | 35 | int |
fa21d299 | 36 | sim_io_init(SIM_DESC sd) |
a1dc3945 | 37 | { |
69628a60 | 38 | return STATE_CALLBACK (sd)->init (STATE_CALLBACK (sd)); |
a1dc3945 AC |
39 | } |
40 | ||
41 | ||
69628a60 | 42 | int |
fa21d299 | 43 | sim_io_shutdown(SIM_DESC sd) |
a1dc3945 | 44 | { |
69628a60 | 45 | return STATE_CALLBACK (sd)->shutdown (STATE_CALLBACK (sd)); |
a1dc3945 AC |
46 | } |
47 | ||
48 | ||
69628a60 | 49 | int |
fa21d299 | 50 | sim_io_unlink(SIM_DESC sd, |
a1dc3945 AC |
51 | const char *f1) |
52 | { | |
69628a60 | 53 | return STATE_CALLBACK (sd)->unlink (STATE_CALLBACK (sd), f1); |
a1dc3945 AC |
54 | } |
55 | ||
56 | ||
69628a60 | 57 | long |
fa21d299 | 58 | sim_io_time(SIM_DESC sd, |
a1dc3945 AC |
59 | long *t) |
60 | { | |
69628a60 | 61 | return STATE_CALLBACK (sd)->time (STATE_CALLBACK (sd), t); |
a1dc3945 AC |
62 | } |
63 | ||
64 | ||
69628a60 | 65 | int |
fa21d299 | 66 | sim_io_system(SIM_DESC sd, const char *s) |
a1dc3945 | 67 | { |
69628a60 | 68 | return STATE_CALLBACK (sd)->system (STATE_CALLBACK (sd), s); |
a1dc3945 AC |
69 | } |
70 | ||
71 | ||
69628a60 | 72 | int |
fa21d299 | 73 | sim_io_rename(SIM_DESC sd, |
a1dc3945 AC |
74 | const char *f1, |
75 | const char *f2) | |
76 | { | |
69628a60 | 77 | return STATE_CALLBACK (sd)->rename (STATE_CALLBACK (sd), f1, f2); |
a1dc3945 AC |
78 | } |
79 | ||
80 | ||
69628a60 | 81 | int |
fa21d299 | 82 | sim_io_write_stdout(SIM_DESC sd, |
a1dc3945 AC |
83 | const char *buf, |
84 | int len) | |
85 | { | |
86 | switch (CURRENT_STDIO) { | |
87 | case DO_USE_STDIO: | |
69628a60 | 88 | return STATE_CALLBACK (sd)->write_stdout (STATE_CALLBACK (sd), buf, len); |
a1dc3945 AC |
89 | break; |
90 | case DONT_USE_STDIO: | |
69628a60 | 91 | return STATE_CALLBACK (sd)->write (STATE_CALLBACK (sd), 1, buf, len); |
a1dc3945 AC |
92 | break; |
93 | default: | |
fa21d299 | 94 | sim_io_error (sd, "sim_io_write_stdout: unaccounted switch\n"); |
a1dc3945 AC |
95 | break; |
96 | } | |
97 | return 0; | |
98 | } | |
99 | ||
100 | ||
69628a60 | 101 | void |
fa21d299 | 102 | sim_io_flush_stdout(SIM_DESC sd) |
a1dc3945 AC |
103 | { |
104 | switch (CURRENT_STDIO) { | |
105 | case DO_USE_STDIO: | |
69628a60 | 106 | STATE_CALLBACK (sd)->flush_stdout (STATE_CALLBACK (sd)); |
a1dc3945 AC |
107 | break; |
108 | case DONT_USE_STDIO: | |
109 | break; | |
110 | default: | |
fa21d299 | 111 | sim_io_error (sd, "sim_io_flush_stdout: unaccounted switch\n"); |
a1dc3945 AC |
112 | break; |
113 | } | |
114 | } | |
115 | ||
116 | ||
69628a60 | 117 | int |
fa21d299 | 118 | sim_io_write_stderr(SIM_DESC sd, |
a1dc3945 AC |
119 | const char *buf, |
120 | int len) | |
121 | { | |
122 | switch (CURRENT_STDIO) { | |
123 | case DO_USE_STDIO: | |
69628a60 | 124 | return STATE_CALLBACK (sd)->write_stderr (STATE_CALLBACK (sd), buf, len); |
a1dc3945 AC |
125 | break; |
126 | case DONT_USE_STDIO: | |
69628a60 | 127 | return STATE_CALLBACK (sd)->write (STATE_CALLBACK (sd), 2, buf, len); |
a1dc3945 AC |
128 | break; |
129 | default: | |
fa21d299 | 130 | sim_io_error (sd, "sim_io_write_stderr: unaccounted switch\n"); |
a1dc3945 AC |
131 | break; |
132 | } | |
133 | return 0; | |
134 | } | |
135 | ||
136 | ||
69628a60 | 137 | void |
fa21d299 | 138 | sim_io_flush_stderr(SIM_DESC sd) |
a1dc3945 AC |
139 | { |
140 | switch (CURRENT_STDIO) { | |
141 | case DO_USE_STDIO: | |
69628a60 | 142 | STATE_CALLBACK (sd)->flush_stderr (STATE_CALLBACK (sd)); |
a1dc3945 AC |
143 | break; |
144 | case DONT_USE_STDIO: | |
145 | break; | |
146 | default: | |
fa21d299 | 147 | sim_io_error (sd, "sim_io_flush_stderr: unaccounted switch\n"); |
a1dc3945 AC |
148 | break; |
149 | } | |
150 | } | |
151 | ||
152 | ||
69628a60 | 153 | int |
fa21d299 | 154 | sim_io_write(SIM_DESC sd, |
a1dc3945 AC |
155 | int fd, |
156 | const char *buf, | |
157 | int len) | |
158 | { | |
69628a60 | 159 | return STATE_CALLBACK (sd)->write (STATE_CALLBACK (sd), fd, buf, len); |
a1dc3945 AC |
160 | } |
161 | ||
162 | ||
69628a60 | 163 | int |
fa21d299 | 164 | sim_io_read_stdin(SIM_DESC sd, |
a1dc3945 AC |
165 | char *buf, |
166 | int len) | |
167 | { | |
168 | switch (CURRENT_STDIO) { | |
169 | case DO_USE_STDIO: | |
69628a60 | 170 | return STATE_CALLBACK (sd)->read_stdin (STATE_CALLBACK (sd), buf, len); |
a1dc3945 AC |
171 | break; |
172 | case DONT_USE_STDIO: | |
69628a60 | 173 | return STATE_CALLBACK (sd)->read (STATE_CALLBACK (sd), 0, buf, len); |
a1dc3945 AC |
174 | break; |
175 | default: | |
fa21d299 | 176 | sim_io_error (sd, "sim_io_read_stdin: unaccounted switch\n"); |
a1dc3945 AC |
177 | break; |
178 | } | |
179 | return 0; | |
180 | } | |
181 | ||
182 | ||
69628a60 | 183 | int |
fa21d299 | 184 | sim_io_read(SIM_DESC sd, int fd, |
a1dc3945 AC |
185 | char *buf, |
186 | int len) | |
187 | { | |
69628a60 | 188 | return STATE_CALLBACK (sd)->read (STATE_CALLBACK (sd), fd, buf, len); |
a1dc3945 AC |
189 | } |
190 | ||
191 | ||
69628a60 | 192 | int |
fa21d299 | 193 | sim_io_open(SIM_DESC sd, |
a1dc3945 AC |
194 | const char *name, |
195 | int flags) | |
196 | { | |
69628a60 | 197 | return STATE_CALLBACK (sd)->open (STATE_CALLBACK (sd), name, flags); |
a1dc3945 AC |
198 | } |
199 | ||
200 | ||
69628a60 | 201 | int |
fa21d299 | 202 | sim_io_lseek(SIM_DESC sd, |
a1dc3945 AC |
203 | int fd, |
204 | long off, | |
205 | int way) | |
206 | { | |
69628a60 | 207 | return STATE_CALLBACK (sd)->lseek (STATE_CALLBACK (sd), fd, off, way); |
a1dc3945 AC |
208 | } |
209 | ||
210 | ||
69628a60 | 211 | int |
fa21d299 | 212 | sim_io_isatty(SIM_DESC sd, |
a1dc3945 AC |
213 | int fd) |
214 | { | |
69628a60 | 215 | return STATE_CALLBACK (sd)->isatty (STATE_CALLBACK (sd), fd); |
a1dc3945 AC |
216 | } |
217 | ||
218 | ||
69628a60 | 219 | int |
fa21d299 | 220 | sim_io_get_errno(SIM_DESC sd) |
a1dc3945 | 221 | { |
69628a60 | 222 | return STATE_CALLBACK (sd)->get_errno (STATE_CALLBACK (sd)); |
a1dc3945 AC |
223 | } |
224 | ||
225 | ||
69628a60 | 226 | int |
fa21d299 | 227 | sim_io_close(SIM_DESC sd, |
a1dc3945 AC |
228 | int fd) |
229 | { | |
69628a60 | 230 | return STATE_CALLBACK (sd)->close (STATE_CALLBACK (sd), fd); |
a1dc3945 AC |
231 | } |
232 | ||
233 | ||
69628a60 | 234 | void |
fa21d299 | 235 | sim_io_printf(SIM_DESC sd, |
a1dc3945 AC |
236 | const char *fmt, |
237 | ...) | |
238 | { | |
239 | va_list ap; | |
240 | va_start(ap, fmt); | |
69628a60 | 241 | STATE_CALLBACK (sd)->vprintf_filtered (STATE_CALLBACK (sd), fmt, ap); |
a1dc3945 AC |
242 | va_end(ap); |
243 | } | |
244 | ||
245 | ||
69628a60 | 246 | void |
fa21d299 | 247 | sim_io_vprintf(SIM_DESC sd, |
a1dc3945 AC |
248 | const char *fmt, |
249 | va_list ap) | |
250 | { | |
69628a60 | 251 | STATE_CALLBACK (sd)->vprintf_filtered (STATE_CALLBACK (sd), fmt, ap); |
a1dc3945 AC |
252 | } |
253 | ||
254 | ||
69628a60 | 255 | void |
fa21d299 | 256 | sim_io_eprintf(SIM_DESC sd, |
a1dc3945 AC |
257 | const char *fmt, |
258 | ...) | |
259 | { | |
260 | va_list ap; | |
261 | va_start(ap, fmt); | |
69628a60 | 262 | STATE_CALLBACK (sd)->evprintf_filtered (STATE_CALLBACK (sd), fmt, ap); |
a1dc3945 AC |
263 | va_end(ap); |
264 | } | |
265 | ||
266 | ||
69628a60 | 267 | void |
fa21d299 | 268 | sim_io_evprintf(SIM_DESC sd, |
a1dc3945 AC |
269 | const char *fmt, |
270 | va_list ap) | |
271 | { | |
69628a60 | 272 | STATE_CALLBACK (sd)->evprintf_filtered (STATE_CALLBACK (sd), fmt, ap); |
a1dc3945 AC |
273 | } |
274 | ||
275 | ||
69628a60 | 276 | void |
fa21d299 | 277 | sim_io_error(SIM_DESC sd, |
a1dc3945 AC |
278 | const char *fmt, |
279 | ...) | |
280 | { | |
69628a60 | 281 | if (sd == NULL || STATE_CALLBACK (sd) == NULL) { |
fa21d299 AC |
282 | va_list ap; |
283 | va_start(ap, fmt); | |
284 | vfprintf (stderr, fmt, ap); | |
285 | va_end(ap); | |
69628a60 | 286 | fprintf (stderr, "\n"); |
fa21d299 AC |
287 | abort (); |
288 | } | |
289 | else { | |
290 | va_list ap; | |
291 | va_start(ap, fmt); | |
69628a60 | 292 | STATE_CALLBACK (sd)->evprintf_filtered (STATE_CALLBACK (sd), fmt, ap); |
fa21d299 | 293 | va_end(ap); |
69628a60 | 294 | STATE_CALLBACK (sd)->error (STATE_CALLBACK (sd), ""); |
fa21d299 | 295 | } |
a1dc3945 AC |
296 | } |
297 | ||
69628a60 MM |
298 | |
299 | void | |
300 | sim_io_poll_quit(SIM_DESC sd) | |
301 | { | |
302 | if (STATE_CALLBACK (sd)->poll_quit != NULL) | |
303 | if (STATE_CALLBACK (sd)->poll_quit (STATE_CALLBACK (sd))) | |
304 | sim_stop (sd); | |
305 | } | |
306 | ||
307 | ||
844f40d3 | 308 | /* Based on gdb-4.17/sim/ppc/main.c:sim_io_read_stdin(). |
69628a60 | 309 | |
844f40d3 AC |
310 | FIXME: Should not be calling fcntl() or grubbing around inside of |
311 | ->fdmap and ->errno. | |
69628a60 | 312 | |
844f40d3 AC |
313 | FIXME: Some completly new mechanism for handling the general |
314 | problem of asynchronous IO is needed. | |
69628a60 | 315 | |
844f40d3 AC |
316 | FIXME: This function does not supress the echoing (ECHO) of input. |
317 | Consequently polled input is always displayed. | |
318 | ||
319 | FIXME: This function does not perform uncooked reads. | |
320 | Consequently, data will not be read until an EOLN character has | |
321 | been entered. A cntrl-d may force the early termination of a line */ | |
69628a60 | 322 | |
69628a60 | 323 | |
844f40d3 AC |
324 | int |
325 | sim_io_poll_read (SIM_DESC sd, | |
326 | int sim_io_fd, | |
327 | char *buf, | |
328 | int sizeof_buf) | |
329 | { | |
330 | #if defined(O_NDELAY) && defined(F_GETFL) && defined(F_SETFL) | |
331 | int fd = STATE_CALLBACK (sd)->fdmap[sim_io_fd]; | |
332 | int flags; | |
333 | int status; | |
334 | int nr_read; | |
335 | int result; | |
336 | STATE_CALLBACK (sd)->last_errno = 0; | |
337 | /* get the old status */ | |
338 | flags = fcntl (fd, F_GETFL, 0); | |
339 | if (flags == -1) | |
69628a60 | 340 | { |
844f40d3 AC |
341 | perror ("sim_io_poll_read"); |
342 | return 0; | |
69628a60 | 343 | } |
844f40d3 AC |
344 | /* temp, disable blocking IO */ |
345 | status = fcntl (fd, F_SETFL, flags | O_NDELAY); | |
346 | if (status == -1) | |
347 | { | |
348 | perror ("sim_io_read_stdin"); | |
349 | return 0; | |
350 | } | |
351 | /* try for input */ | |
352 | nr_read = read (fd, buf, sizeof_buf); | |
353 | if (nr_read >= 0) | |
354 | { | |
355 | /* printf ("<nr-read=%d>\n", nr_read); */ | |
356 | result = nr_read; | |
357 | } | |
358 | else | |
359 | { /* nr_read < 0 */ | |
360 | result = -1; | |
361 | STATE_CALLBACK (sd)->last_errno = errno; | |
362 | } | |
363 | /* return to regular vewing */ | |
364 | status = fcntl (fd, F_SETFL, flags); | |
365 | if (status == -1) | |
366 | { | |
367 | perror ("sim_io_read_stdin"); | |
368 | /* return 0; */ | |
369 | } | |
370 | return result; | |
371 | #else | |
372 | return sim_io_read (sd, sim_io_fd, buf, sizeof_buf); | |
373 | #endif | |
69628a60 | 374 | } |