]>
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 | ||
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 | |
d950d986 | 271 | os_printf_filtered (host_callback *p, const char *format, ...) |
dedcc91d SC |
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 | }; |