Add comment.
[deliverable/binutils-gdb.git] / sim / common / callback.c
1 /* Host callback routines for GDB.
2 Copyright 1995, 1996, 1997 Free Software Foundation, Inc.
3 Contributed by Cygnus Support.
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20
21 /* This file provides a standard way for targets to talk to the host OS
22 level. */
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27 #include "ansidecl.h"
28 #ifdef ANSI_PROTOTYPES
29 #include <stdarg.h>
30 #else
31 #include <varargs.h>
32 #endif
33 #include <stdio.h>
34 #ifdef HAVE_STDLIB_H
35 #include <stdlib.h>
36 #endif
37 #include <errno.h>
38 #include <fcntl.h>
39 #include <time.h>
40 #include "callback.h"
41 #include "targ-vals.h"
42
43 #ifdef HAVE_UNISTD_H
44 #include <unistd.h>
45 #endif
46
47 extern int system PARAMS ((const char *));
48
49 static int os_init PARAMS ((host_callback *));
50 static int os_shutdown PARAMS ((host_callback *));
51 static int os_unlink PARAMS ((host_callback *, const char *));
52 static long os_time PARAMS ((host_callback *, long *));
53 static int os_system PARAMS ((host_callback *, const char *));
54 static int os_rename PARAMS ((host_callback *, const char *, const char *));
55 static int os_write_stdout PARAMS ((host_callback *, const char *, int));
56 static void os_flush_stdout PARAMS ((host_callback *));
57 static int os_write_stderr PARAMS ((host_callback *, const char *, int));
58 static void os_flush_stderr PARAMS ((host_callback *));
59 static int os_write PARAMS ((host_callback *, int, const char *, int));
60 static int os_read_stdin PARAMS ((host_callback *, char *, int));
61 static int os_read PARAMS ((host_callback *, int, char *, int));
62 static int os_open PARAMS ((host_callback *, const char *, int));
63 static int os_lseek PARAMS ((host_callback *, int, long, int));
64 static int os_isatty PARAMS ((host_callback *, int));
65 static int os_get_errno PARAMS ((host_callback *));
66 static int os_close PARAMS ((host_callback *, int));
67 static void os_vprintf_filtered PARAMS ((host_callback *, const char *, va_list));
68 static void os_evprintf_filtered PARAMS ((host_callback *, const char *, va_list));
69 static void os_error PARAMS ((host_callback *, const char *, ...));
70 static int fdmap PARAMS ((host_callback *, int));
71 static int fdbad PARAMS ((host_callback *, int));
72 static int wrap PARAMS ((host_callback *, int));
73
74 /* Set the callback copy of errno from what we see now. */
75
76 static int
77 wrap (p, val)
78 host_callback *p;
79 int val;
80 {
81 p->last_errno = errno;
82 return val;
83 }
84
85 /* Make sure the FD provided is ok. If not, return non-zero
86 and set errno. */
87
88 static int
89 fdbad (p, fd)
90 host_callback *p;
91 int fd;
92 {
93 if (fd < 0 || fd > MAX_CALLBACK_FDS || !p->fdopen[fd])
94 {
95 p->last_errno = EINVAL;
96 return -1;
97 }
98 return 0;
99 }
100
101 static int
102 fdmap (p, fd)
103 host_callback *p;
104 int fd;
105 {
106 return p->fdmap[fd];
107 }
108
109 static int
110 os_close (p, fd)
111 host_callback *p;
112 int fd;
113 {
114 int result;
115
116 result = fdbad (p, fd);
117 if (result)
118 return result;
119 result = wrap (p, close (fdmap (p, fd)));
120 if(result == 0 && !p->alwaysopen[fd])
121 p->fdopen[fd] = 0;
122
123 return result;
124 }
125
126
127 /* taken from gdb/util.c - should be in a library */
128
129
130 #if defined(__GO32__) || defined (_WIN32)
131 static int
132 os_poll_quit (p)
133 host_callback *p;
134 {
135 #ifndef _MSC_VER
136 if (kbhit ())
137 {
138 int k = getkey ();
139 if (k == 1)
140 {
141 return 1;
142 }
143 else if (k == 2)
144 {
145 return 1;
146 }
147 else
148 {
149 sim_cb_eprintf (p, "CTRL-A to quit, CTRL-B to quit harder\n");
150 }
151 }
152 #else /* !_MSC_VER */
153 /* NB - this will not compile! */
154 int k = win32pollquit();
155 if (k == 1)
156 return 1;
157 else if (k == 2)
158 return 1;
159 #endif /* !_MSC_VER */
160 return 0;
161 }
162 #else
163 #define os_poll_quit 0
164 #endif /* defined(__GO32__) || defined(_WIN32) */
165
166 static int
167 os_get_errno (p)
168 host_callback *p;
169 {
170 return host_to_target_errno (p->last_errno);
171 }
172
173
174 static int
175 os_isatty (p, fd)
176 host_callback *p;
177 int fd;
178 {
179 int result;
180
181 result = fdbad (p, fd);
182 if (result)
183 return result;
184 result = wrap (p, isatty (fdmap (p, fd)));
185
186 return result;
187 }
188
189 static int
190 os_lseek (p, fd, off, way)
191 host_callback *p;
192 int fd;
193 long off;
194 int way;
195 {
196 int result;
197
198 result = fdbad (p, fd);
199 if (result)
200 return result;
201 result = lseek (fdmap (p, fd), off, way);
202 return result;
203 }
204
205 static int
206 os_open (p, name, flags)
207 host_callback *p;
208 const char *name;
209 int flags;
210 {
211 int i;
212 for (i = 0; i < MAX_CALLBACK_FDS; i++)
213 {
214 if (!p->fdopen[i])
215 {
216 int f = open (name, target_to_host_open (flags), 0644);
217 if (f < 0)
218 {
219 p->last_errno = errno;
220 return f;
221 }
222 p->fdopen[i] = 1;
223 p->fdmap[i] = f;
224 return i;
225 }
226 }
227 p->last_errno = EMFILE;
228 return -1;
229 }
230
231 static int
232 os_read (p, fd, buf, len)
233 host_callback *p;
234 int fd;
235 char *buf;
236 int len;
237 {
238 int result;
239
240 result = fdbad (p, fd);
241 if (result)
242 return result;
243 result = wrap (p, read (fdmap (p, fd), buf, len));
244 return result;
245 }
246
247 static int
248 os_read_stdin (p, buf, len)
249 host_callback *p;
250 char *buf;
251 int len;
252 {
253 return wrap (p, read (0, buf, len));
254 }
255
256 static int
257 os_write (p, fd, buf, len)
258 host_callback *p;
259 int fd;
260 const char *buf;
261 int len;
262 {
263 int result;
264
265 result = fdbad (p, fd);
266 if (result)
267 return result;
268 result = wrap (p, write (fdmap (p, fd), buf, len));
269 return result;
270 }
271
272 static int
273 os_write_stdout (p, buf, len)
274 host_callback *p;
275 const char *buf;
276 int len;
277 {
278 return fwrite(buf, 1, len, stdout);
279 }
280
281 static void
282 os_flush_stdout (p)
283 host_callback *p;
284 {
285 fflush (stdout);
286 }
287
288 static int
289 os_write_stderr (p, buf, len)
290 host_callback *p;
291 const char *buf;
292 int len;
293 {
294 return fwrite(buf, 1, len, stderr);
295 }
296
297 static void
298 os_flush_stderr (p)
299 host_callback *p;
300 {
301 fflush (stderr);
302 }
303
304 static int
305 os_rename (p, f1, f2)
306 host_callback *p;
307 const char *f1;
308 const char *f2;
309 {
310 return wrap (p, rename (f1, f2));
311 }
312
313
314 static int
315 os_system (p, s)
316 host_callback *p;
317 const char *s;
318 {
319 return wrap (p, system (s));
320 }
321
322 static long
323 os_time (p, t)
324 host_callback *p;
325 long *t;
326 {
327 return wrap (p, time (t));
328 }
329
330
331 static int
332 os_unlink (p, f1)
333 host_callback *p;
334 const char *f1;
335 {
336 return wrap (p, unlink (f1));
337 }
338
339
340 static int
341 os_shutdown (p)
342 host_callback *p;
343 {
344 int i;
345 for (i = 0; i < MAX_CALLBACK_FDS; i++)
346 {
347 if (p->fdopen[i] && !p->alwaysopen[i]) {
348 close (p->fdmap[i]);
349 p->fdopen[i] = 0;
350 }
351 }
352 return 1;
353 }
354
355 static int
356 os_init(p)
357 host_callback *p;
358 {
359 int i;
360 os_shutdown (p);
361 for (i= 0; i < 3; i++)
362 {
363 p->fdmap[i] = i;
364 p->fdopen[i] = 1;
365 p->alwaysopen[i] = 1;
366 }
367 return 1;
368 }
369
370 /* DEPRECIATED */
371
372 /* VARARGS */
373 static void
374 #ifdef ANSI_PROTOTYPES
375 os_printf_filtered (host_callback *p, const char *format, ...)
376 #else
377 os_printf_filtered (p, va_alist)
378 host_callback *p;
379 va_dcl
380 #endif
381 {
382 va_list args;
383 #ifdef ANSI_PROTOTYPES
384 va_start (args, format);
385 #else
386 char *format;
387
388 va_start (args);
389 format = va_arg (args, char *);
390 #endif
391
392 vfprintf (stdout, format, args);
393 va_end (args);
394 }
395
396 /* VARARGS */
397 static void
398 #ifdef ANSI_PROTOTYPES
399 os_vprintf_filtered (host_callback *p, const char *format, va_list args)
400 #else
401 os_vprintf_filtered (p, format, args)
402 host_callback *p;
403 const char *format;
404 va_list args;
405 #endif
406 {
407 vprintf (format, args);
408 }
409
410 /* VARARGS */
411 static void
412 #ifdef ANSI_PROTOTYPES
413 os_evprintf_filtered (host_callback *p, const char *format, va_list args)
414 #else
415 os_evprintf_filtered (p, format, args)
416 host_callback *p;
417 const char *format;
418 va_list args;
419 #endif
420 {
421 vfprintf (stderr, format, args);
422 }
423
424 /* VARARGS */
425 static void
426 #ifdef ANSI_PROTOTYPES
427 os_error (host_callback *p, const char *format, ...)
428 #else
429 os_error (p, va_alist)
430 host_callback *p;
431 va_dcl
432 #endif
433 {
434 va_list args;
435 #ifdef ANSI_PROTOTYPES
436 va_start (args, format);
437 #else
438 char *format;
439
440 va_start (args);
441 format = va_arg (args, char *);
442 #endif
443
444 vfprintf (stderr, format, args);
445 fprintf (stderr, "\n");
446
447 va_end (args);
448 exit (1);
449 }
450
451 host_callback default_callback =
452 {
453 os_close,
454 os_get_errno,
455 os_isatty,
456 os_lseek,
457 os_open,
458 os_read,
459 os_read_stdin,
460 os_rename,
461 os_system,
462 os_time,
463 os_unlink,
464 os_write,
465 os_write_stdout,
466 os_flush_stdout,
467 os_write_stderr,
468 os_flush_stderr,
469
470 os_poll_quit,
471
472 os_shutdown,
473 os_init,
474
475 os_printf_filtered, /* depreciated */
476
477 os_vprintf_filtered,
478 os_evprintf_filtered,
479 os_error,
480
481 0, /* last errno */
482
483 { 0, }, /* fdmap */
484 { 0, }, /* fdopen */
485 { 0, }, /* alwaysopen */
486
487 HOST_CALLBACK_MAGIC,
488 };
489 \f
490 /* FIXME: Need to add hooks so target can tweak as necessary. */
491
492 /* FIXME: struct stat conversion is missing. */
493
494 /* FIXME: sort tables if large.
495 Alternatively, an obvious improvement for errno conversion is
496 to machine generate a function with a large switch(). */
497
498 int
499 host_to_target_errno (host_val)
500 int host_val;
501 {
502 target_defs_map *m;
503
504 for (m = &errno_map[0]; m->host_val; ++m)
505 if (m->host_val == host_val)
506 return m->target_val;
507
508 /* ??? Which error to return in this case is up for grabs.
509 Note that some missing values may have standard alternatives.
510 For now return 0 and require caller to deal with it. */
511 return 0;
512 }
513
514 /* Given a set of target bitmasks for the open system call,
515 return the host equivalent.
516 Mapping open flag values is best done by looping so there's no need
517 to machine generate this function. */
518
519 int
520 target_to_host_open (target_val)
521 int target_val;
522 {
523 int host_val = 0;
524 target_defs_map *m;
525
526 for (m = &open_map[0]; m->host_val != -1; ++m)
527 {
528 switch (m->target_val)
529 {
530 /* O_RDONLY can be (and usually is) 0 which needs to be treated
531 specially. */
532 case TARGET_O_RDONLY :
533 case TARGET_O_WRONLY :
534 case TARGET_O_RDWR :
535 if ((target_val & (TARGET_O_RDONLY | TARGET_O_WRONLY | TARGET_O_RDWR))
536 == m->target_val)
537 host_val |= m->host_val;
538 /* Handle the host/target differentiating between binary and
539 text mode. Only one case is of importance */
540 #if ! defined (TARGET_O_BINARY) && defined (O_BINARY)
541 host_val |= O_BINARY;
542 #endif
543 break;
544 default :
545 if ((m->target_val & target_val) == m->target_val)
546 host_val |= m->host_val;
547 break;
548 }
549 }
550
551 return host_val;
552 }
553 \f
554 /* Cover functions to the vfprintf callbacks.
555
556 ??? If one thinks of the callbacks as a subsystem onto itself [or part of
557 a larger "remote target subsystem"] with a well defined interface, then
558 one would think that the subsystem would provide these. However, until
559 one is allowed to create such a subsystem (with its own source tree
560 independent of any particular user), such a critter can't exist. Thus
561 these functions are here for the time being. */
562
563 void
564 sim_cb_printf (host_callback *p, const char *fmt, ...)
565 {
566 va_list ap;
567
568 va_start (ap, fmt);
569 p->vprintf_filtered (p, fmt, ap);
570 va_end (ap);
571 }
572
573 void
574 sim_cb_eprintf (host_callback *p, const char *fmt, ...)
575 {
576 va_list ap;
577
578 va_start (ap, fmt);
579 p->evprintf_filtered (p, fmt, ap);
580 va_end (ap);
581 }
This page took 0.049774 seconds and 5 git commands to generate.