b878f770e95eccd2071e7c1280b53ddd835296c5
[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 -1
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   return fdbad (p, fd) || wrap (p, close (fdmap (p, fd)));
89 }
90
91 int 
92 os_get_errno (p)
93      host_callback *p;
94 {
95   /* !!! fixme, translate from host to taget errno value */
96   return p->last_errno;
97 }
98
99
100 int 
101 os_isatty (p, fd)
102      host_callback *p;
103      int fd;
104 {
105   return fdbad (p, fd) || wrap (p, isatty (fdmap (fd)));
106 }
107
108 int 
109 os_lseek (p, fd, off, way)
110      host_callback *p;
111      int fd;
112      long off;
113      int way;
114 {
115   return fdbad (p, fd) || lseek (fdmap (p, fd), off, way);
116 }
117
118 int 
119 os_open (p, name, flags)
120      host_callback *p;
121      const char *name;
122      int flags;
123 {
124   int i;
125   for (i = 0; i < MAX_CALLBACK_FDS; i++)
126     {
127       if (!p->fdopen[i])
128         {
129           int f = open (name, flags);
130           if (f < 0)
131             {
132               p->last_errno = errno;
133               return f;
134             }
135           p->fdopen[i] = 1;
136           p->fdmap[i] = f;
137           return i;
138         }
139     }
140   p->last_errno = EMFILE;
141   return -1;
142 }
143
144 int 
145 os_read (p, fd, buf, len)
146      host_callback *p;
147      int fd;
148      char *buf;
149      int len;
150 {
151   return fdbad (p, fd) || wrap (p, read (fdmap (p, fd), buf, len));
152 }
153
154 int 
155 os_read_stdin (p, buf, len)
156      host_callback *p;
157      char *buf;
158      int len;
159 {
160   return wrap (p, read (0, buf, len));
161 }
162
163 int 
164 os_write (p, fd, buf, len)
165      host_callback *p;
166      int fd;
167      const char *buf;
168      int len;
169 {
170   return fdbad (p, fd) || wrap (p, write (fdmap (p, fd), buf, len));
171 }
172
173 /* ignore the grossness of INSIDE_SIMULATOR, it will go away one day. */
174 int 
175 os_write_stdout (p, buf, len)
176      host_callback *p;
177      const char *buf;
178      int len;
179 {
180 #ifdef INSIDE_SIMULATOR
181   return os_write (1, buf, len);
182 #else
183   int i;
184   char b[2];
185   for (i = 0; i< len; i++) 
186     {
187       b[0] = buf[i];
188       b[1] = 0;
189       if (target_output_hook)
190         target_output_hook (b);
191       else
192         fputs_filtered (b, gdb_stdout);
193     }
194   return len;
195 #endif
196 }
197
198 int 
199 os_rename (p, f1, f2)
200      host_callback *p;
201      const char *f1;
202      const char *f2;
203 {
204   return wrap (p, rename (f1, f2));
205 }
206
207
208 int
209 os_system (p, s)
210      host_callback *p;
211      const char *s;
212 {
213   return wrap (p, system (s));
214 }
215
216 long 
217 os_time (p, t)
218      host_callback *p;
219      long *t;
220 {
221   return wrap (p, time (t));
222 }
223
224
225 int 
226 os_unlink (p, f1)
227      host_callback *p;
228      const char *f1;
229 {
230   return wrap (p, unlink (f1));
231 }
232
233
234 int
235 os_shutdown (p)
236 host_callback *p;
237 {
238   int i;
239   for (i = 0; i < MAX_CALLBACK_FDS; i++)
240     {
241       if (p->fdopen[i] && !p->alwaysopen[i]) {
242         close (p->fdmap[i]);
243         p->fdopen[i] = 0;
244       }
245     }
246   return 1;
247 }
248
249 int os_init(p)
250 host_callback *p;
251 {
252   int i;
253   os_shutdown (p);
254   for (i= 0; i < 3; i++)
255     {
256       p->fdmap[i] = i;
257       p->fdopen[i] = 1;
258       p->alwaysopen[i] = 1;
259     }
260   return 1;
261 }
262
263
264 /* !!fixme!!
265    This bit is ugly.  When the interface has settled down I'll 
266    move the whole file into sim/common and remove this bit. */
267
268 /* VARARGS */
269 void
270 #ifdef ANSI_PROTOTYPES
271 os_printf_filtered (host_callback *p, const char *format, ...)
272 #else
273 os_printf_filtered (p, va_alist)
274      host_callback *p;
275      va_dcl
276 #endif
277 {
278   va_list args;
279 #ifdef ANSI_PROTOTYPES
280   va_start (args, format);
281 #else
282   char *format;
283
284   va_start (args);
285   format = va_arg (args, char *);
286 #endif
287
288 #ifdef INSIDE_SIMULATOR
289   vprintf (format, args);
290 #else
291   vfprintf_filtered (stdout, format, args);
292 #endif
293
294   va_end (args);
295 }
296
297 host_callback default_callback =
298 {
299   os_close,
300   os_get_errno,
301   os_isatty,
302   os_lseek,
303   os_open,
304   os_read,
305   os_read_stdin,
306   os_rename,
307   os_system,
308   os_time,
309   os_unlink,
310   os_write,
311   os_write_stdout,
312
313   os_shutdown,
314   os_init,
315
316   os_printf_filtered,
317
318   0,            /* last errno */
319 };