]>
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 | ||
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 | ||
abf6a9dc | 59 | /* Make sure the FD provided is ok. If not, return non-zero |
dedcc91d SC |
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 | { | |
abf6a9dc JW |
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; | |
dedcc91d SC |
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 | { | |
abf6a9dc JW |
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; | |
dedcc91d SC |
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 | { | |
abf6a9dc JW |
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; | |
dedcc91d SC |
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 | { | |
abf6a9dc JW |
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; | |
dedcc91d SC |
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 | { | |
abf6a9dc JW |
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; | |
dedcc91d SC |
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 | |
abf6a9dc | 211 | return os_write (p, 1, buf, len); |
dedcc91d SC |
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 | |
d950d986 | 301 | os_printf_filtered (host_callback *p, const char *format, ...) |
dedcc91d SC |
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 | }; |