xref: /netbsd-src/external/gpl3/gdb.old/dist/sim/common/sim-io.c (revision 8b657b0747480f8989760d71343d6dd33f8d4cf9)
1 /* The common simulator framework for GDB, the GNU Debugger.
2 
3    Copyright 2002-2023 Free Software Foundation, Inc.
4 
5    Contributed by Andrew Cagney and Red Hat.
6 
7    This file is part of GDB.
8 
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13 
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
21 
22 /* This must come before any other includes.  */
23 #include "defs.h"
24 
25 #include <errno.h>
26 #if HAVE_FCNTL_H
27 #include <fcntl.h>
28 #endif
29 #include <stdarg.h>
30 #include <stdint.h>
31 #include <stdlib.h>
32 #if HAVE_UNISTD_H
33 #include <unistd.h>
34 #endif
35 
36 #undef open
37 
38 #include "sim-main.h"
39 #include "sim-io.h"
40 #include "sim/callback.h"
41 
42 /* Define the rate at which the simulator should poll the host
43    for a quit. */
44 #ifndef POLL_QUIT_INTERVAL
45 #define POLL_QUIT_INTERVAL 0x10
46 #endif
47 
48 static int poll_quit_count = POLL_QUIT_INTERVAL;
49 
50 /* See the file include/callbacks.h for a description */
51 
52 
53 int
54 sim_io_init (SIM_DESC sd)
55 {
56   return STATE_CALLBACK (sd)->init (STATE_CALLBACK (sd));
57 }
58 
59 
60 int
61 sim_io_shutdown (SIM_DESC sd)
62 {
63   return STATE_CALLBACK (sd)->shutdown (STATE_CALLBACK (sd));
64 }
65 
66 
67 int
68 sim_io_unlink (SIM_DESC sd,
69 	       const char *f1)
70 {
71   return STATE_CALLBACK (sd)->unlink (STATE_CALLBACK (sd), f1);
72 }
73 
74 
75 int64_t
76 sim_io_time (SIM_DESC sd)
77 {
78   return STATE_CALLBACK (sd)->time (STATE_CALLBACK (sd));
79 }
80 
81 
82 int
83 sim_io_system (SIM_DESC sd, const char *s)
84 {
85   return STATE_CALLBACK (sd)->system (STATE_CALLBACK (sd), s);
86 }
87 
88 
89 int
90 sim_io_rename (SIM_DESC sd,
91 	       const char *f1,
92 	       const char *f2)
93 {
94   return STATE_CALLBACK (sd)->rename (STATE_CALLBACK (sd), f1, f2);
95 }
96 
97 
98 int
99 sim_io_write_stdout (SIM_DESC sd,
100 		     const char *buf,
101 		     int len)
102 {
103   switch (CURRENT_STDIO) {
104   case DO_USE_STDIO:
105     return STATE_CALLBACK (sd)->write_stdout (STATE_CALLBACK (sd), buf, len);
106     break;
107   case DONT_USE_STDIO:
108     return STATE_CALLBACK (sd)->write (STATE_CALLBACK (sd), 1, buf, len);
109     break;
110   default:
111     sim_io_error (sd, "sim_io_write_stdout: unaccounted switch\n");
112     break;
113   }
114   return 0;
115 }
116 
117 
118 void
119 sim_io_flush_stdout (SIM_DESC sd)
120 {
121   switch (CURRENT_STDIO) {
122   case DO_USE_STDIO:
123     STATE_CALLBACK (sd)->flush_stdout (STATE_CALLBACK (sd));
124     break;
125   case DONT_USE_STDIO:
126     break;
127   default:
128     sim_io_error (sd, "sim_io_flush_stdout: unaccounted switch\n");
129     break;
130   }
131 }
132 
133 
134 int
135 sim_io_write_stderr (SIM_DESC sd,
136 		     const char *buf,
137 		     int len)
138 {
139   switch (CURRENT_STDIO) {
140   case DO_USE_STDIO:
141     return STATE_CALLBACK (sd)->write_stderr (STATE_CALLBACK (sd), buf, len);
142     break;
143   case DONT_USE_STDIO:
144     return STATE_CALLBACK (sd)->write (STATE_CALLBACK (sd), 2, buf, len);
145     break;
146   default:
147     sim_io_error (sd, "sim_io_write_stderr: unaccounted switch\n");
148     break;
149   }
150   return 0;
151 }
152 
153 
154 void
155 sim_io_flush_stderr (SIM_DESC sd)
156 {
157   switch (CURRENT_STDIO) {
158   case DO_USE_STDIO:
159     STATE_CALLBACK (sd)->flush_stderr (STATE_CALLBACK (sd));
160     break;
161   case DONT_USE_STDIO:
162     break;
163   default:
164     sim_io_error (sd, "sim_io_flush_stderr: unaccounted switch\n");
165     break;
166   }
167 }
168 
169 
170 int
171 sim_io_write (SIM_DESC sd,
172 	      int fd,
173 	      const char *buf,
174 	      int len)
175 {
176   return STATE_CALLBACK (sd)->write (STATE_CALLBACK (sd), fd, buf, len);
177 }
178 
179 
180 int
181 sim_io_read_stdin (SIM_DESC sd,
182 		   char *buf,
183 		   int len)
184 {
185   switch (CURRENT_STDIO) {
186   case DO_USE_STDIO:
187     return STATE_CALLBACK (sd)->read_stdin (STATE_CALLBACK (sd), buf, len);
188     break;
189   case DONT_USE_STDIO:
190     return STATE_CALLBACK (sd)->read (STATE_CALLBACK (sd), 0, buf, len);
191     break;
192   default:
193     sim_io_error (sd, "sim_io_read_stdin: unaccounted switch\n");
194     break;
195   }
196   return 0;
197 }
198 
199 
200 int
201 sim_io_read (SIM_DESC sd, int fd,
202 	     char *buf,
203 	     int len)
204 {
205   return STATE_CALLBACK (sd)->read (STATE_CALLBACK (sd), fd, buf, len);
206 }
207 
208 
209 int
210 sim_io_open (SIM_DESC sd,
211 	     const char *name,
212 	     int flags)
213 {
214   return STATE_CALLBACK (sd)->open (STATE_CALLBACK (sd), name, flags);
215 }
216 
217 
218 int64_t
219 sim_io_lseek (SIM_DESC sd,
220 	      int fd,
221 	      int64_t off,
222 	      int way)
223 {
224   return STATE_CALLBACK (sd)->lseek (STATE_CALLBACK (sd), fd, off, way);
225 }
226 
227 
228 int
229 sim_io_isatty (SIM_DESC sd,
230 	       int fd)
231 {
232   return STATE_CALLBACK (sd)->isatty (STATE_CALLBACK (sd), fd);
233 }
234 
235 
236 int
237 sim_io_get_errno (SIM_DESC sd)
238 {
239   return STATE_CALLBACK (sd)->get_errno (STATE_CALLBACK (sd));
240 }
241 
242 
243 int
244 sim_io_close (SIM_DESC sd,
245 	      int fd)
246 {
247   return STATE_CALLBACK (sd)->close (STATE_CALLBACK (sd), fd);
248 }
249 
250 
251 void
252 sim_io_printf (SIM_DESC sd,
253 	       const char *fmt,
254 	       ...)
255 {
256   va_list ap;
257   va_start (ap, fmt);
258   STATE_CALLBACK (sd)->vprintf_filtered (STATE_CALLBACK (sd), fmt, ap);
259   va_end (ap);
260 }
261 
262 
263 void
264 sim_io_vprintf (SIM_DESC sd,
265 		const char *fmt,
266 		va_list ap)
267 {
268   STATE_CALLBACK (sd)->vprintf_filtered (STATE_CALLBACK (sd), fmt, ap);
269 }
270 
271 
272 void
273 sim_io_eprintf (SIM_DESC sd,
274 	       const char *fmt,
275 	       ...)
276 {
277   va_list ap;
278   va_start (ap, fmt);
279   STATE_CALLBACK (sd)->evprintf_filtered (STATE_CALLBACK (sd), fmt, ap);
280   va_end (ap);
281 }
282 
283 
284 void
285 sim_io_evprintf (SIM_DESC sd,
286 		 const char *fmt,
287 		 va_list ap)
288 {
289   STATE_CALLBACK (sd)->evprintf_filtered (STATE_CALLBACK (sd), fmt, ap);
290 }
291 
292 
293 void
294 sim_io_error (SIM_DESC sd,
295 	      const char *fmt,
296 	      ...)
297 {
298   if (sd == NULL || STATE_CALLBACK (sd) == NULL) {
299     va_list ap;
300     va_start (ap, fmt);
301     vfprintf (stderr, fmt, ap);
302     va_end (ap);
303     fprintf (stderr, "\n");
304     abort ();
305   }
306   else {
307     va_list ap;
308     va_start (ap, fmt);
309     STATE_CALLBACK (sd)->evprintf_filtered (STATE_CALLBACK (sd), fmt, ap);
310     va_end (ap);
311     /* The %s avoids empty printf compiler warnings.  Not ideal, but we want
312        error's side-effect where it halts processing.  */
313     STATE_CALLBACK (sd)->error (STATE_CALLBACK (sd), "%s", "");
314   }
315 }
316 
317 
318 void
319 sim_io_poll_quit (SIM_DESC sd)
320 {
321   if (STATE_CALLBACK (sd)->poll_quit != NULL && poll_quit_count-- < 0)
322     {
323       poll_quit_count = POLL_QUIT_INTERVAL;
324       if (STATE_CALLBACK (sd)->poll_quit (STATE_CALLBACK (sd)))
325 	sim_stop (sd);
326     }
327 }
328 
329 
330 /* Based on gdb-4.17/sim/ppc/main.c:sim_io_read_stdin().
331 
332    FIXME: Should not be calling fcntl() or grubbing around inside of
333    ->fdmap and ->errno.
334 
335    FIXME: Some completly new mechanism for handling the general
336    problem of asynchronous IO is needed.
337 
338    FIXME: This function does not supress the echoing (ECHO) of input.
339    Consequently polled input is always displayed.
340 
341    FIXME: This function does not perform uncooked reads.
342    Consequently, data will not be read until an EOLN character has
343    been entered. A cntrl-d may force the early termination of a line */
344 
345 
346 int
347 sim_io_poll_read (SIM_DESC sd,
348 		  int sim_io_fd,
349 		  char *buf,
350 		  int sizeof_buf)
351 {
352 #if defined(O_NONBLOCK) && defined(F_GETFL) && defined(F_SETFL)
353   int fd = STATE_CALLBACK (sd)->fdmap[sim_io_fd];
354   int flags;
355   int status;
356   int nr_read;
357   int result;
358   STATE_CALLBACK (sd)->last_errno = 0;
359   /* get the old status */
360   flags = fcntl (fd, F_GETFL, 0);
361   if (flags == -1)
362     {
363       perror ("sim_io_poll_read");
364       return 0;
365     }
366   /* temp, disable blocking IO */
367   status = fcntl (fd, F_SETFL, flags | O_NONBLOCK);
368   if (status == -1)
369     {
370       perror ("sim_io_read_stdin");
371       return 0;
372     }
373   /* try for input */
374   nr_read = read (fd, buf, sizeof_buf);
375   if (nr_read >= 0)
376     {
377       /* printf ("<nr-read=%d>\n", nr_read); */
378       result = nr_read;
379     }
380   else
381     { /* nr_read < 0 */
382       result = -1;
383       STATE_CALLBACK (sd)->last_errno = errno;
384     }
385   /* return to regular vewing */
386   status = fcntl (fd, F_SETFL, flags);
387   if (status == -1)
388     {
389       perror ("sim_io_read_stdin");
390       /* return 0; */
391     }
392   return result;
393 #else
394   return sim_io_read (sd, sim_io_fd, buf, sizeof_buf);
395 #endif
396 }
397 
398 int
399 sim_io_stat (SIM_DESC sd, const char *path, struct stat *buf)
400 {
401   return STATE_CALLBACK (sd)->to_stat (STATE_CALLBACK (sd), path, buf);
402 }
403 
404 int
405 sim_io_fstat (SIM_DESC sd, int fd, struct stat *buf)
406 {
407   return STATE_CALLBACK (sd)->to_fstat (STATE_CALLBACK (sd), fd, buf);
408 }
409