* callback.c (os_close): Mark the descriptor as being
[deliverable/binutils-gdb.git] / sim / common / callback.c
CommitLineData
966f47b4
DE
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
c45adab0
MM
24#ifdef HAVE_CONFIG_H
25#include "config.h"
26#endif
966f47b4
DE
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
248c1fb8 43#ifdef HAVE_UNISTD_H
c45adab0
MM
44#include <unistd.h>
45#endif
46
47extern int system PARAMS ((const char *));
48
966f47b4
DE
49static int os_init PARAMS ((host_callback *));
50static int os_shutdown PARAMS ((host_callback *));
51static int os_unlink PARAMS ((host_callback *, const char *));
52static long os_time PARAMS ((host_callback *, long *));
53static int os_system PARAMS ((host_callback *, const char *));
54static int os_rename PARAMS ((host_callback *, const char *, const char *));
55static int os_write_stdout PARAMS ((host_callback *, const char *, int));
248c1fb8
JL
56static void os_flush_stdout PARAMS ((host_callback *));
57static int os_write_stderr PARAMS ((host_callback *, const char *, int));
58static void os_flush_stderr PARAMS ((host_callback *));
966f47b4
DE
59static int os_write PARAMS ((host_callback *, int, const char *, int));
60static int os_read_stdin PARAMS ((host_callback *, char *, int));
61static int os_read PARAMS ((host_callback *, int, char *, int));
62static int os_open PARAMS ((host_callback *, const char *, int));
63static int os_lseek PARAMS ((host_callback *, int, long, int));
64static int os_isatty PARAMS ((host_callback *, int));
65static int os_get_errno PARAMS ((host_callback *));
66static int os_close PARAMS ((host_callback *, int));
248c1fb8
JL
67static void os_vprintf_filtered PARAMS ((host_callback *, const char *, va_list));
68static void os_evprintf_filtered PARAMS ((host_callback *, const char *, va_list));
69static void os_error PARAMS ((host_callback *, const char *, ...));
966f47b4
DE
70static int fdmap PARAMS ((host_callback *, int));
71static int fdbad PARAMS ((host_callback *, int));
72static int wrap PARAMS ((host_callback *, int));
73
74/* Set the callback copy of errno from what we see now. */
75
76static int
77wrap (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
88static int
89fdbad (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
101static int
102fdmap (p, fd)
103 host_callback *p;
104 int fd;
105{
106 return p->fdmap[fd];
107}
108
109static int
110os_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)));
248c1fb8
JL
120 if(result == 0 && !p->alwaysopen[fd])
121 p->fdopen[fd] = 0;
122
966f47b4
DE
123 return result;
124}
125
248c1fb8
JL
126
127/* taken from gdb/util.c - should be in a library */
128
129
130#if defined(__GO32__) || defined (_WIN32)
131int
132os_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
966f47b4
DE
166static int
167os_get_errno (p)
168 host_callback *p;
169{
170 return host_to_target_errno (p->last_errno);
171}
172
173
174static int
175os_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)));
248c1fb8 185
966f47b4
DE
186 return result;
187}
188
189static int
190os_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
205static int
206os_open (p, name, flags)
207 host_callback *p;
208 const char *name;
966f47b4
DE
209{
210 int i;
211 for (i = 0; i < MAX_CALLBACK_FDS; i++)
212 {
213 if (!p->fdopen[i])
214 {
248c1fb8 215 int f = open (name, target_to_host_open (flags), 0644);
966f47b4
DE
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
230static int
231os_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
246static int
247os_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
255static int
256os_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
271static int
272os_write_stdout (p, buf, len)
273 host_callback *p;
274 const char *buf;
275 int len;
276{
248c1fb8
JL
277 return fwrite(buf, 1, len, stdout);
278}
279
280static void
281os_flush_stdout (p)
282 host_callback *p;
283{
284 fflush (stdout);
285}
286
287static int
288os_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
296static void
297os_flush_stderr (p)
298 host_callback *p;
299{
300 fflush (stderr);
966f47b4
DE
301}
302
303static int
304os_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
313static int
314os_system (p, s)
315 host_callback *p;
316 const char *s;
317{
318 return wrap (p, system (s));
319}
320
321static long
322os_time (p, t)
323 host_callback *p;
324 long *t;
325{
326 return wrap (p, time (t));
327}
328
329
330static int
331os_unlink (p, f1)
332 host_callback *p;
333 const char *f1;
334{
335 return wrap (p, unlink (f1));
336}
337
338
339static int
340os_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
354static int
355os_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
248c1fb8
JL
369/* DEPRECIATED */
370
966f47b4
DE
371/* VARARGS */
372static void
373#ifdef ANSI_PROTOTYPES
374os_printf_filtered (host_callback *p, const char *format, ...)
375#else
376os_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
248c1fb8
JL
391 vfprintf (stdout, format, args);
392 va_end (args);
393}
394
395/* VARARGS */
396static void
397#ifdef ANSI_PROTOTYPES
398os_vprintf_filtered (host_callback *p, const char *format, va_list args)
399#else
400os_vprintf_filtered (p, format, args)
401 host_callback *p;
402 const char *format;
403 va_list args;
404#endif
405{
966f47b4 406 vprintf (format, args);
248c1fb8 407}
966f47b4 408
248c1fb8
JL
409/* VARARGS */
410static void
411#ifdef ANSI_PROTOTYPES
412os_evprintf_filtered (host_callback *p, const char *format, va_list args)
413#else
414os_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);
966f47b4
DE
421}
422
423/* VARARGS */
424static void
425#ifdef ANSI_PROTOTYPES
426os_error (host_callback *p, const char *format, ...)
427#else
428os_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);
c45adab0 447 exit (1);
966f47b4
DE
448}
449
450host_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,
248c1fb8
JL
465 os_flush_stdout,
466 os_write_stderr,
467 os_flush_stderr,
468
469 os_poll_quit,
966f47b4
DE
470
471 os_shutdown,
472 os_init,
473
248c1fb8
JL
474 os_printf_filtered, /* depreciated */
475
476 os_vprintf_filtered,
477 os_evprintf_filtered,
966f47b4
DE
478 os_error,
479
480 0, /* last errno */
248c1fb8
JL
481
482 { 0, }, /* fdmap */
483 { 0, }, /* fdopen */
484 { 0, }, /* alwaysopen */
485
486 HOST_CALLBACK_MAGIC,
966f47b4
DE
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
497int
498host_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
518int
519target_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.055632 seconds and 4 git commands to generate.