* callback.c: #include <stdlib.h>
[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 #include "ansidecl.h"
25 #ifdef ANSI_PROTOTYPES
26 #include <stdarg.h>
27 #else
28 #include <varargs.h>
29 #endif
30 #include <stdio.h>
31 #ifdef HAVE_STDLIB_H
32 #include <stdlib.h>
33 #endif
34 #include <errno.h>
35 #include <fcntl.h>
36 #include <time.h>
37 #include "callback.h"
38 #include "targ-vals.h"
39
40 static int os_init PARAMS ((host_callback *));
41 static int os_shutdown PARAMS ((host_callback *));
42 static int os_unlink PARAMS ((host_callback *, const char *));
43 static long os_time PARAMS ((host_callback *, long *));
44 static int os_system PARAMS ((host_callback *, const char *));
45 static int os_rename PARAMS ((host_callback *, const char *, const char *));
46 static int os_write_stdout PARAMS ((host_callback *, const char *, int));
47 static int os_write PARAMS ((host_callback *, int, const char *, int));
48 static int os_read_stdin PARAMS ((host_callback *, char *, int));
49 static int os_read PARAMS ((host_callback *, int, char *, int));
50 static int os_open PARAMS ((host_callback *, const char *, int));
51 static int os_lseek PARAMS ((host_callback *, int, long, int));
52 static int os_isatty PARAMS ((host_callback *, int));
53 static int os_get_errno PARAMS ((host_callback *));
54 static int os_close PARAMS ((host_callback *, int));
55 static int fdmap PARAMS ((host_callback *, int));
56 static int fdbad PARAMS ((host_callback *, int));
57 static int wrap PARAMS ((host_callback *, int));
58
59 /* Set the callback copy of errno from what we see now. */
60
61 static int
62 wrap (p, val)
63 host_callback *p;
64 int val;
65 {
66 p->last_errno = errno;
67 return val;
68 }
69
70 /* Make sure the FD provided is ok. If not, return non-zero
71 and set errno. */
72
73 static int
74 fdbad (p, fd)
75 host_callback *p;
76 int fd;
77 {
78 if (fd < 0 || fd > MAX_CALLBACK_FDS || !p->fdopen[fd])
79 {
80 p->last_errno = EINVAL;
81 return -1;
82 }
83 return 0;
84 }
85
86 static int
87 fdmap (p, fd)
88 host_callback *p;
89 int fd;
90 {
91 return p->fdmap[fd];
92 }
93
94 static int
95 os_close (p, fd)
96 host_callback *p;
97 int fd;
98 {
99 int result;
100
101 result = fdbad (p, fd);
102 if (result)
103 return result;
104 result = wrap (p, close (fdmap (p, fd)));
105 return result;
106 }
107
108 static int
109 os_get_errno (p)
110 host_callback *p;
111 {
112 return host_to_target_errno (p->last_errno);
113 }
114
115
116 static int
117 os_isatty (p, fd)
118 host_callback *p;
119 int fd;
120 {
121 int result;
122
123 result = fdbad (p, fd);
124 if (result)
125 return result;
126 result = wrap (p, isatty (fdmap (p, fd)));
127 return result;
128 }
129
130 static int
131 os_lseek (p, fd, off, way)
132 host_callback *p;
133 int fd;
134 long off;
135 int way;
136 {
137 int result;
138
139 result = fdbad (p, fd);
140 if (result)
141 return result;
142 result = lseek (fdmap (p, fd), off, way);
143 return result;
144 }
145
146 static int
147 os_open (p, name, flags)
148 host_callback *p;
149 const char *name;
150 int flags;
151 {
152 int i;
153 for (i = 0; i < MAX_CALLBACK_FDS; i++)
154 {
155 if (!p->fdopen[i])
156 {
157 int f = open (name, target_to_host_open (flags));
158 if (f < 0)
159 {
160 p->last_errno = errno;
161 return f;
162 }
163 p->fdopen[i] = 1;
164 p->fdmap[i] = f;
165 return i;
166 }
167 }
168 p->last_errno = EMFILE;
169 return -1;
170 }
171
172 static int
173 os_read (p, fd, buf, len)
174 host_callback *p;
175 int fd;
176 char *buf;
177 int len;
178 {
179 int result;
180
181 result = fdbad (p, fd);
182 if (result)
183 return result;
184 result = wrap (p, read (fdmap (p, fd), buf, len));
185 return result;
186 }
187
188 static int
189 os_read_stdin (p, buf, len)
190 host_callback *p;
191 char *buf;
192 int len;
193 {
194 return wrap (p, read (0, buf, len));
195 }
196
197 static int
198 os_write (p, fd, buf, len)
199 host_callback *p;
200 int fd;
201 const char *buf;
202 int len;
203 {
204 int result;
205
206 result = fdbad (p, fd);
207 if (result)
208 return result;
209 result = wrap (p, write (fdmap (p, fd), buf, len));
210 return result;
211 }
212
213 static int
214 os_write_stdout (p, buf, len)
215 host_callback *p;
216 const char *buf;
217 int len;
218 {
219 return os_write (p, 1, buf, len);
220 }
221
222 static int
223 os_rename (p, f1, f2)
224 host_callback *p;
225 const char *f1;
226 const char *f2;
227 {
228 return wrap (p, rename (f1, f2));
229 }
230
231
232 static int
233 os_system (p, s)
234 host_callback *p;
235 const char *s;
236 {
237 return wrap (p, system (s));
238 }
239
240 static long
241 os_time (p, t)
242 host_callback *p;
243 long *t;
244 {
245 return wrap (p, time (t));
246 }
247
248
249 static int
250 os_unlink (p, f1)
251 host_callback *p;
252 const char *f1;
253 {
254 return wrap (p, unlink (f1));
255 }
256
257
258 static int
259 os_shutdown (p)
260 host_callback *p;
261 {
262 int i;
263 for (i = 0; i < MAX_CALLBACK_FDS; i++)
264 {
265 if (p->fdopen[i] && !p->alwaysopen[i]) {
266 close (p->fdmap[i]);
267 p->fdopen[i] = 0;
268 }
269 }
270 return 1;
271 }
272
273 static int
274 os_init(p)
275 host_callback *p;
276 {
277 int i;
278 os_shutdown (p);
279 for (i= 0; i < 3; i++)
280 {
281 p->fdmap[i] = i;
282 p->fdopen[i] = 1;
283 p->alwaysopen[i] = 1;
284 }
285 return 1;
286 }
287
288 /* VARARGS */
289 static void
290 #ifdef ANSI_PROTOTYPES
291 os_printf_filtered (host_callback *p, const char *format, ...)
292 #else
293 os_printf_filtered (p, va_alist)
294 host_callback *p;
295 va_dcl
296 #endif
297 {
298 va_list args;
299 #ifdef ANSI_PROTOTYPES
300 va_start (args, format);
301 #else
302 char *format;
303
304 va_start (args);
305 format = va_arg (args, char *);
306 #endif
307
308 vprintf (format, args);
309
310 va_end (args);
311 }
312
313 /* VARARGS */
314 static void
315 #ifdef ANSI_PROTOTYPES
316 os_error (host_callback *p, const char *format, ...)
317 #else
318 os_error (p, va_alist)
319 host_callback *p;
320 va_dcl
321 #endif
322 {
323 va_list args;
324 #ifdef ANSI_PROTOTYPES
325 va_start (args, format);
326 #else
327 char *format;
328
329 va_start (args);
330 format = va_arg (args, char *);
331 #endif
332
333 vfprintf (stderr, format, args);
334 fprintf (stderr, "\n");
335
336 va_end (args);
337 exit (EXIT_FAILURE);
338 }
339
340 host_callback default_callback =
341 {
342 os_close,
343 os_get_errno,
344 os_isatty,
345 os_lseek,
346 os_open,
347 os_read,
348 os_read_stdin,
349 os_rename,
350 os_system,
351 os_time,
352 os_unlink,
353 os_write,
354 os_write_stdout,
355
356 os_shutdown,
357 os_init,
358
359 os_printf_filtered,
360 os_error,
361
362 0, /* last errno */
363 };
364 \f
365 /* FIXME: Need to add hooks so target can tweak as necessary. */
366
367 /* FIXME: struct stat conversion is missing. */
368
369 /* FIXME: sort tables if large.
370 Alternatively, an obvious improvement for errno conversion is
371 to machine generate a function with a large switch(). */
372
373 int
374 host_to_target_errno (host_val)
375 int host_val;
376 {
377 target_defs_map *m;
378
379 for (m = &errno_map[0]; m->host_val; ++m)
380 if (m->host_val == host_val)
381 return m->target_val;
382
383 /* ??? Which error to return in this case is up for grabs.
384 Note that some missing values may have standard alternatives.
385 For now return 0 and require caller to deal with it. */
386 return 0;
387 }
388
389 /* Given a set of target bitmasks for the open system call,
390 return the host equivalent.
391 Mapping open flag values is best done by looping so there's no need
392 to machine generate this function. */
393
394 int
395 target_to_host_open (target_val)
396 int target_val;
397 {
398 int host_val = 0;
399 target_defs_map *m;
400
401 for (m = &open_map[0]; m->host_val != -1; ++m)
402 {
403 switch (m->target_val)
404 {
405 /* O_RDONLY can be (and usually is) 0 which needs to be treated
406 specially. */
407 case TARGET_O_RDONLY :
408 case TARGET_O_WRONLY :
409 case TARGET_O_RDWR :
410 if ((target_val & (TARGET_O_RDONLY | TARGET_O_WRONLY | TARGET_O_RDWR))
411 == m->target_val)
412 host_val |= m->host_val;
413 break;
414 default :
415 if ((m->target_val & target_val) == m->target_val)
416 host_val |= m->host_val;
417 break;
418 }
419 }
420
421 return host_val;
422 }
This page took 0.079731 seconds and 5 git commands to generate.