Changes to make the simulator work again.
[external/binutils.git] / gdb / callback.c
1 /* Host callback routines for GDB.
2    Copyright 1995 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
22 /* This file provides a standard way for targets to talk to the host OS
23    level.
24
25    This interface will probably need a bit more banging to make it
26    smooth.  Currently the simulator uses this file to provide the
27    callbacks for itself when it's built standalone, which is rather
28    ugly. */
29
30 #ifndef INSIDE_SIMULATOR
31 #include "defs.h"
32 #endif
33
34 #include "ansidecl.h"
35 #include "callback.h"
36 #ifdef ANSI_PROTOTYPES
37 #include <stdarg.h>
38 #else
39 #include <varargs.h>
40 #endif
41
42 #include <stdio.h>
43 #include <errno.h>
44 #include <fcntl.h>
45 #include <time.h>
46
47
48
49 /* Set the callback copy of errno from what we see now. */
50 static int 
51 wrap (p, val)
52      host_callback *p;
53      int val;
54 {
55   p->last_errno = errno;
56   return val;
57 }
58
59 /* Make sure the FD provided is ok.  If not, return non-zero
60    and set errno. */
61
62 static int 
63 fdbad (p, fd)
64      host_callback *p;
65      int fd;
66 {
67   if (fd < 0 || fd > MAX_CALLBACK_FDS || !p->fdopen[fd])
68     {
69       p->last_errno = EINVAL;
70       return -1;
71     }
72   return 0;
73 }
74
75 static int 
76 fdmap (p, fd)
77      host_callback *p;
78      int fd;
79 {
80   return p->fdmap[fd];
81 }
82
83 int 
84 os_close (p, fd)
85      host_callback *p;
86      int fd;
87 {
88   int result;
89
90   result = fdbad (p, fd);
91   if (result)
92     return result;
93   result = wrap (p, close (fdmap (p, fd)));
94   return result;
95 }
96
97 int 
98 os_get_errno (p)
99      host_callback *p;
100 {
101   /* !!! fixme, translate from host to taget errno value */
102   return p->last_errno;
103 }
104
105
106 int 
107 os_isatty (p, fd)
108      host_callback *p;
109      int fd;
110 {
111   int result;
112
113   result = fdbad (p, fd);
114   if (result)
115     return result;
116   result = wrap (p, isatty (fdmap (fd)));
117   return result;
118 }
119
120 int 
121 os_lseek (p, fd, off, way)
122      host_callback *p;
123      int fd;
124      long off;
125      int way;
126 {
127   int result;
128
129   result = fdbad (p, fd);
130   if (result)
131     return result;
132   result = lseek (fdmap (p, fd), off, way);
133   return result;
134 }
135
136 int 
137 os_open (p, name, flags)
138      host_callback *p;
139      const char *name;
140      int flags;
141 {
142   int i;
143   for (i = 0; i < MAX_CALLBACK_FDS; i++)
144     {
145       if (!p->fdopen[i])
146         {
147           int f = open (name, flags);
148           if (f < 0)
149             {
150               p->last_errno = errno;
151               return f;
152             }
153           p->fdopen[i] = 1;
154           p->fdmap[i] = f;
155           return i;
156         }
157     }
158   p->last_errno = EMFILE;
159   return -1;
160 }
161
162 int 
163 os_read (p, fd, buf, len)
164      host_callback *p;
165      int fd;
166      char *buf;
167      int len;
168 {
169   int result;
170
171   result = fdbad (p, fd);
172   if (result)
173     return result;
174   result = wrap (p, read (fdmap (p, fd), buf, len));
175   return result;
176 }
177
178 int 
179 os_read_stdin (p, buf, len)
180      host_callback *p;
181      char *buf;
182      int len;
183 {
184   return wrap (p, read (0, buf, len));
185 }
186
187 int 
188 os_write (p, fd, buf, len)
189      host_callback *p;
190      int fd;
191      const char *buf;
192      int len;
193 {
194   int result;
195
196   result = fdbad (p, fd);
197   if (result)
198     return result;
199   result = wrap (p, write (fdmap (p, fd), buf, len));
200   return result;
201 }
202
203 /* ignore the grossness of INSIDE_SIMULATOR, it will go away one day. */
204 int 
205 os_write_stdout (p, buf, len)
206      host_callback *p;
207      const char *buf;
208      int len;
209 {
210 #ifdef INSIDE_SIMULATOR
211   return os_write (p, 1, buf, len);
212 #else
213   int i;
214   char b[2];
215   for (i = 0; i< len; i++) 
216     {
217       b[0] = buf[i];
218       b[1] = 0;
219       if (target_output_hook)
220         target_output_hook (b);
221       else
222         fputs_filtered (b, gdb_stdout);
223     }
224   return len;
225 #endif
226 }
227
228 int 
229 os_rename (p, f1, f2)
230      host_callback *p;
231      const char *f1;
232      const char *f2;
233 {
234   return wrap (p, rename (f1, f2));
235 }
236
237
238 int
239 os_system (p, s)
240      host_callback *p;
241      const char *s;
242 {
243   return wrap (p, system (s));
244 }
245
246 long 
247 os_time (p, t)
248      host_callback *p;
249      long *t;
250 {
251   return wrap (p, time (t));
252 }
253
254
255 int 
256 os_unlink (p, f1)
257      host_callback *p;
258      const char *f1;
259 {
260   return wrap (p, unlink (f1));
261 }
262
263
264 int
265 os_shutdown (p)
266 host_callback *p;
267 {
268   int i;
269   for (i = 0; i < MAX_CALLBACK_FDS; i++)
270     {
271       if (p->fdopen[i] && !p->alwaysopen[i]) {
272         close (p->fdmap[i]);
273         p->fdopen[i] = 0;
274       }
275     }
276   return 1;
277 }
278
279 int os_init(p)
280 host_callback *p;
281 {
282   int i;
283   os_shutdown (p);
284   for (i= 0; i < 3; i++)
285     {
286       p->fdmap[i] = i;
287       p->fdopen[i] = 1;
288       p->alwaysopen[i] = 1;
289     }
290   return 1;
291 }
292
293
294 /* !!fixme!!
295    This bit is ugly.  When the interface has settled down I'll 
296    move the whole file into sim/common and remove this bit. */
297
298 /* VARARGS */
299 void
300 #ifdef ANSI_PROTOTYPES
301 os_printf_filtered (host_callback *p, const char *format, ...)
302 #else
303 os_printf_filtered (p, va_alist)
304      host_callback *p;
305      va_dcl
306 #endif
307 {
308   va_list args;
309 #ifdef ANSI_PROTOTYPES
310   va_start (args, format);
311 #else
312   char *format;
313
314   va_start (args);
315   format = va_arg (args, char *);
316 #endif
317
318 #ifdef INSIDE_SIMULATOR
319   vprintf (format, args);
320 #else
321   vfprintf_filtered (stdout, format, args);
322 #endif
323
324   va_end (args);
325 }
326
327 host_callback default_callback =
328 {
329   os_close,
330   os_get_errno,
331   os_isatty,
332   os_lseek,
333   os_open,
334   os_read,
335   os_read_stdin,
336   os_rename,
337   os_system,
338   os_time,
339   os_unlink,
340   os_write,
341   os_write_stdout,
342
343   os_shutdown,
344   os_init,
345
346   os_printf_filtered,
347
348   0,            /* last errno */
349 };