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