* callback.c (os_close): Mark the descriptor as being
[deliverable/binutils-gdb.git] / sim / common / callback.c
1 /* Host callback routines for GDB.
2 Copyright 1995, 1996 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 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 p->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 {
210 int i;
211 for (i = 0; i < MAX_CALLBACK_FDS; i++)
212 {
213 if (!p->fdopen[i])
214 {
215 int f = open (name, target_to_host_open (flags), 0644);
216 if (f < 0)
217 {
218 p->last_errno = errno;
219 return f;
220 }
221 p->fdopen[i] = 1;
222 p->fdmap[i] = f;
223 return i;
224 }
225 }
226 p->last_errno = EMFILE;
227 return -1;
228 }
229
230 static int
231 os_read (p, fd, buf, len)
232 host_callback *p;
233 int fd;
234 char *buf;
235 int len;
236 {
237 int result;
238
239 result = fdbad (p, fd);
240 if (result)
241 return result;
242 result = wrap (p, read (fdmap (p, fd), buf, len));
243 return result;
244 }
245
246 static int
247 os_read_stdin (p, buf, len)
248 host_callback *p;
249 char *buf;
250 int len;
251 {
252 return wrap (p, read (0, buf, len));
253 }
254
255 static int
256 os_write (p, fd, buf, len)
257 host_callback *p;
258 int fd;
259 const char *buf;
260 int len;
261 {
262 int result;
263
264 result = fdbad (p, fd);
265 if (result)
266 return result;
267 result = wrap (p, write (fdmap (p, fd), buf, len));
268 return result;
269 }
270
271 static int
272 os_write_stdout (p, buf, len)
273 host_callback *p;
274 const char *buf;
275 int len;
276 {
277 return fwrite(buf, 1, len, stdout);
278 }
279
280 static void
281 os_flush_stdout (p)
282 host_callback *p;
283 {
284 fflush (stdout);
285 }
286
287 static int
288 os_write_stderr (p, buf, len)
289 host_callback *p;
290 const char *buf;
291 int len;
292 {
293 return fwrite(buf, 1, len, stderr);
294 }
295
296 static void
297 os_flush_stderr (p)
298 host_callback *p;
299 {
300 fflush (stderr);
301 }
302
303 static int
304 os_rename (p, f1, f2)
305 host_callback *p;
306 const char *f1;
307 const char *f2;
308 {
309 return wrap (p, rename (f1, f2));
310 }
311
312
313 static int
314 os_system (p, s)
315 host_callback *p;
316 const char *s;
317 {
318 return wrap (p, system (s));
319 }
320
321 static long
322 os_time (p, t)
323 host_callback *p;
324 long *t;
325 {
326 return wrap (p, time (t));
327 }
328
329
330 static int
331 os_unlink (p, f1)
332 host_callback *p;
333 const char *f1;
334 {
335 return wrap (p, unlink (f1));
336 }
337
338
339 static int
340 os_shutdown (p)
341 host_callback *p;
342 {
343 int i;
344 for (i = 0; i < MAX_CALLBACK_FDS; i++)
345 {
346 if (p->fdopen[i] && !p->alwaysopen[i]) {
347 close (p->fdmap[i]);
348 p->fdopen[i] = 0;
349 }
350 }
351 return 1;
352 }
353
354 static int
355 os_init(p)
356 host_callback *p;
357 {
358 int i;
359 os_shutdown (p);
360 for (i= 0; i < 3; i++)
361 {
362 p->fdmap[i] = i;
363 p->fdopen[i] = 1;
364 p->alwaysopen[i] = 1;
365 }
366 return 1;
367 }
368
369 /* DEPRECIATED */
370
371 /* VARARGS */
372 static void
373 #ifdef ANSI_PROTOTYPES
374 os_printf_filtered (host_callback *p, const char *format, ...)
375 #else
376 os_printf_filtered (p, va_alist)
377 host_callback *p;
378 va_dcl
379 #endif
380 {
381 va_list args;
382 #ifdef ANSI_PROTOTYPES
383 va_start (args, format);
384 #else
385 char *format;
386
387 va_start (args);
388 format = va_arg (args, char *);
389 #endif
390
391 vfprintf (stdout, format, args);
392 va_end (args);
393 }
394
395 /* VARARGS */
396 static void
397 #ifdef ANSI_PROTOTYPES
398 os_vprintf_filtered (host_callback *p, const char *format, va_list args)
399 #else
400 os_vprintf_filtered (p, format, args)
401 host_callback *p;
402 const char *format;
403 va_list args;
404 #endif
405 {
406 vprintf (format, args);
407 }
408
409 /* VARARGS */
410 static void
411 #ifdef ANSI_PROTOTYPES
412 os_evprintf_filtered (host_callback *p, const char *format, va_list args)
413 #else
414 os_evprintf_filtered (p, format, args)
415 host_callback *p;
416 const char *format;
417 va_list args;
418 #endif
419 {
420 vfprintf (stderr, format, args);
421 }
422
423 /* VARARGS */
424 static void
425 #ifdef ANSI_PROTOTYPES
426 os_error (host_callback *p, const char *format, ...)
427 #else
428 os_error (p, va_alist)
429 host_callback *p;
430 va_dcl
431 #endif
432 {
433 va_list args;
434 #ifdef ANSI_PROTOTYPES
435 va_start (args, format);
436 #else
437 char *format;
438
439 va_start (args);
440 format = va_arg (args, char *);
441 #endif
442
443 vfprintf (stderr, format, args);
444 fprintf (stderr, "\n");
445
446 va_end (args);
447 exit (1);
448 }
449
450 host_callback default_callback =
451 {
452 os_close,
453 os_get_errno,
454 os_isatty,
455 os_lseek,
456 os_open,
457 os_read,
458 os_read_stdin,
459 os_rename,
460 os_system,
461 os_time,
462 os_unlink,
463 os_write,
464 os_write_stdout,
465 os_flush_stdout,
466 os_write_stderr,
467 os_flush_stderr,
468
469 os_poll_quit,
470
471 os_shutdown,
472 os_init,
473
474 os_printf_filtered, /* depreciated */
475
476 os_vprintf_filtered,
477 os_evprintf_filtered,
478 os_error,
479
480 0, /* last errno */
481
482 { 0, }, /* fdmap */
483 { 0, }, /* fdopen */
484 { 0, }, /* alwaysopen */
485
486 HOST_CALLBACK_MAGIC,
487 };
488 \f
489 /* FIXME: Need to add hooks so target can tweak as necessary. */
490
491 /* FIXME: struct stat conversion is missing. */
492
493 /* FIXME: sort tables if large.
494 Alternatively, an obvious improvement for errno conversion is
495 to machine generate a function with a large switch(). */
496
497 int
498 host_to_target_errno (host_val)
499 int host_val;
500 {
501 target_defs_map *m;
502
503 for (m = &errno_map[0]; m->host_val; ++m)
504 if (m->host_val == host_val)
505 return m->target_val;
506
507 /* ??? Which error to return in this case is up for grabs.
508 Note that some missing values may have standard alternatives.
509 For now return 0 and require caller to deal with it. */
510 return 0;
511 }
512
513 /* Given a set of target bitmasks for the open system call,
514 return the host equivalent.
515 Mapping open flag values is best done by looping so there's no need
516 to machine generate this function. */
517
518 int
519 target_to_host_open (target_val)
520 int target_val;
521 {
522 int host_val = 0;
523 target_defs_map *m;
524
525 for (m = &open_map[0]; m->host_val != -1; ++m)
526 {
527 switch (m->target_val)
528 {
529 /* O_RDONLY can be (and usually is) 0 which needs to be treated
530 specially. */
531 case TARGET_O_RDONLY :
532 case TARGET_O_WRONLY :
533 case TARGET_O_RDWR :
534 if ((target_val & (TARGET_O_RDONLY | TARGET_O_WRONLY | TARGET_O_RDWR))
535 == m->target_val)
536 host_val |= m->host_val;
537 break;
538 default :
539 if ((m->target_val & target_val) == m->target_val)
540 host_val |= m->host_val;
541 break;
542 }
543 }
544
545 return host_val;
546 }
This page took 0.077414 seconds and 5 git commands to generate.