Fri Sep 29 02:10:05 1995 steve chamberlain <sac@slash.cygnus.com>
[binutils-gdb.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 };