1/* The common simulator framework for GDB, the GNU Debugger. 2 3 Copyright 2002, 2007 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 23#include "sim-main.h" 24#include "sim-io.h" 25#include "targ-vals.h" 26 27#include <errno.h> 28#if HAVE_FCNTL_H 29#include <fcntl.h> 30#endif 31 32#if HAVE_UNISTD_H 33#include <unistd.h> 34#endif 35 36/* Define the rate at which the simulator should poll the host 37 for a quit. */ 38#ifndef POLL_QUIT_INTERVAL 39#define POLL_QUIT_INTERVAL 0x10 40#endif 41 42static int poll_quit_count = POLL_QUIT_INTERVAL; 43 44/* See the file include/callbacks.h for a description */ 45 46 47int 48sim_io_init(SIM_DESC sd) 49{ 50 return STATE_CALLBACK (sd)->init (STATE_CALLBACK (sd)); 51} 52 53 54int 55sim_io_shutdown(SIM_DESC sd) 56{ 57 return STATE_CALLBACK (sd)->shutdown (STATE_CALLBACK (sd)); 58} 59 60 61int 62sim_io_unlink(SIM_DESC sd, 63 const char *f1) 64{ 65 return STATE_CALLBACK (sd)->unlink (STATE_CALLBACK (sd), f1); 66} 67 68 69long 70sim_io_time(SIM_DESC sd, 71 long *t) 72{ 73 return STATE_CALLBACK (sd)->time (STATE_CALLBACK (sd), t); 74} 75 76 77int 78sim_io_system(SIM_DESC sd, const char *s) 79{ 80 return STATE_CALLBACK (sd)->system (STATE_CALLBACK (sd), s); 81} 82 83 84int 85sim_io_rename(SIM_DESC sd, 86 const char *f1, 87 const char *f2) 88{ 89 return STATE_CALLBACK (sd)->rename (STATE_CALLBACK (sd), f1, f2); 90} 91 92 93int 94sim_io_write_stdout(SIM_DESC sd, 95 const char *buf, 96 int len) 97{ 98 switch (CURRENT_STDIO) { 99 case DO_USE_STDIO: 100 return STATE_CALLBACK (sd)->write_stdout (STATE_CALLBACK (sd), buf, len); 101 break; 102 case DONT_USE_STDIO: 103 return STATE_CALLBACK (sd)->write (STATE_CALLBACK (sd), 1, buf, len); 104 break; 105 default: 106 sim_io_error (sd, "sim_io_write_stdout: unaccounted switch\n"); 107 break; 108 } 109 return 0; 110} 111 112 113void 114sim_io_flush_stdout(SIM_DESC sd) 115{ 116 switch (CURRENT_STDIO) { 117 case DO_USE_STDIO: 118 STATE_CALLBACK (sd)->flush_stdout (STATE_CALLBACK (sd)); 119 break; 120 case DONT_USE_STDIO: 121 break; 122 default: 123 sim_io_error (sd, "sim_io_flush_stdout: unaccounted switch\n"); 124 break; 125 } 126} 127 128 129int 130sim_io_write_stderr(SIM_DESC sd, 131 const char *buf, 132 int len) 133{ 134 switch (CURRENT_STDIO) { 135 case DO_USE_STDIO: 136 return STATE_CALLBACK (sd)->write_stderr (STATE_CALLBACK (sd), buf, len); 137 break; 138 case DONT_USE_STDIO: 139 return STATE_CALLBACK (sd)->write (STATE_CALLBACK (sd), 2, buf, len); 140 break; 141 default: 142 sim_io_error (sd, "sim_io_write_stderr: unaccounted switch\n"); 143 break; 144 } 145 return 0; 146} 147 148 149void 150sim_io_flush_stderr(SIM_DESC sd) 151{ 152 switch (CURRENT_STDIO) { 153 case DO_USE_STDIO: 154 STATE_CALLBACK (sd)->flush_stderr (STATE_CALLBACK (sd)); 155 break; 156 case DONT_USE_STDIO: 157 break; 158 default: 159 sim_io_error (sd, "sim_io_flush_stderr: unaccounted switch\n"); 160 break; 161 } 162} 163 164 165int 166sim_io_write(SIM_DESC sd, 167 int fd, 168 const char *buf, 169 int len) 170{ 171 return STATE_CALLBACK (sd)->write (STATE_CALLBACK (sd), fd, buf, len); 172} 173 174 175int 176sim_io_read_stdin(SIM_DESC sd, 177 char *buf, 178 int len) 179{ 180 switch (CURRENT_STDIO) { 181 case DO_USE_STDIO: 182 return STATE_CALLBACK (sd)->read_stdin (STATE_CALLBACK (sd), buf, len); 183 break; 184 case DONT_USE_STDIO: 185 return STATE_CALLBACK (sd)->read (STATE_CALLBACK (sd), 0, buf, len); 186 break; 187 default: 188 sim_io_error (sd, "sim_io_read_stdin: unaccounted switch\n"); 189 break; 190 } 191 return 0; 192} 193 194 195int 196sim_io_read(SIM_DESC sd, int fd, 197 char *buf, 198 int len) 199{ 200 return STATE_CALLBACK (sd)->read (STATE_CALLBACK (sd), fd, buf, len); 201} 202 203 204int 205sim_io_open(SIM_DESC sd, 206 const char *name, 207 int flags) 208{ 209 return STATE_CALLBACK (sd)->open (STATE_CALLBACK (sd), name, flags); 210} 211 212 213int 214sim_io_lseek(SIM_DESC sd, 215 int fd, 216 long off, 217 int way) 218{ 219 return STATE_CALLBACK (sd)->lseek (STATE_CALLBACK (sd), fd, off, way); 220} 221 222 223int 224sim_io_isatty(SIM_DESC sd, 225 int fd) 226{ 227 return STATE_CALLBACK (sd)->isatty (STATE_CALLBACK (sd), fd); 228} 229 230 231int 232sim_io_get_errno(SIM_DESC sd) 233{ 234 return STATE_CALLBACK (sd)->get_errno (STATE_CALLBACK (sd)); 235} 236 237 238int 239sim_io_close(SIM_DESC sd, 240 int fd) 241{ 242 return STATE_CALLBACK (sd)->close (STATE_CALLBACK (sd), fd); 243} 244 245 246void 247sim_io_printf(SIM_DESC sd, 248 const char *fmt, 249 ...) 250{ 251 va_list ap; 252 va_start(ap, fmt); 253 STATE_CALLBACK (sd)->vprintf_filtered (STATE_CALLBACK (sd), fmt, ap); 254 va_end(ap); 255} 256 257 258void 259sim_io_vprintf(SIM_DESC sd, 260 const char *fmt, 261 va_list ap) 262{ 263 STATE_CALLBACK (sd)->vprintf_filtered (STATE_CALLBACK (sd), fmt, ap); 264} 265 266 267void 268sim_io_eprintf(SIM_DESC sd, 269 const char *fmt, 270 ...) 271{ 272 va_list ap; 273 va_start(ap, fmt); 274 STATE_CALLBACK (sd)->evprintf_filtered (STATE_CALLBACK (sd), fmt, ap); 275 va_end(ap); 276} 277 278 279void 280sim_io_evprintf(SIM_DESC sd, 281 const char *fmt, 282 va_list ap) 283{ 284 STATE_CALLBACK (sd)->evprintf_filtered (STATE_CALLBACK (sd), fmt, ap); 285} 286 287 288void 289sim_io_error(SIM_DESC sd, 290 const char *fmt, 291 ...) 292{ 293 if (sd == NULL || STATE_CALLBACK (sd) == NULL) { 294 va_list ap; 295 va_start(ap, fmt); 296 vfprintf (stderr, fmt, ap); 297 va_end(ap); 298 fprintf (stderr, "\n"); 299 abort (); 300 } 301 else { 302 va_list ap; 303 va_start(ap, fmt); 304 STATE_CALLBACK (sd)->evprintf_filtered (STATE_CALLBACK (sd), fmt, ap); 305 va_end(ap); 306 STATE_CALLBACK (sd)->error (STATE_CALLBACK (sd), ""); 307 } 308} 309 310 311void 312sim_io_poll_quit(SIM_DESC sd) 313{ 314 if (STATE_CALLBACK (sd)->poll_quit != NULL && poll_quit_count-- < 0) 315 { 316 poll_quit_count = POLL_QUIT_INTERVAL; 317 if (STATE_CALLBACK (sd)->poll_quit (STATE_CALLBACK (sd))) 318 sim_stop (sd); 319 } 320} 321 322 323/* Based on gdb-4.17/sim/ppc/main.c:sim_io_read_stdin(). 324 325 FIXME: Should not be calling fcntl() or grubbing around inside of 326 ->fdmap and ->errno. 327 328 FIXME: Some completly new mechanism for handling the general 329 problem of asynchronous IO is needed. 330 331 FIXME: This function does not supress the echoing (ECHO) of input. 332 Consequently polled input is always displayed. 333 334 FIXME: This function does not perform uncooked reads. 335 Consequently, data will not be read until an EOLN character has 336 been entered. A cntrl-d may force the early termination of a line */ 337 338 339int 340sim_io_poll_read (SIM_DESC sd, 341 int sim_io_fd, 342 char *buf, 343 int sizeof_buf) 344{ 345#if defined(O_NDELAY) && defined(F_GETFL) && defined(F_SETFL) 346 int fd = STATE_CALLBACK (sd)->fdmap[sim_io_fd]; 347 int flags; 348 int status; 349 int nr_read; 350 int result; 351 STATE_CALLBACK (sd)->last_errno = 0; 352 /* get the old status */ 353 flags = fcntl (fd, F_GETFL, 0); 354 if (flags == -1) 355 { 356 perror ("sim_io_poll_read"); 357 return 0; 358 } 359 /* temp, disable blocking IO */ 360 status = fcntl (fd, F_SETFL, flags | O_NDELAY); 361 if (status == -1) 362 { 363 perror ("sim_io_read_stdin"); 364 return 0; 365 } 366 /* try for input */ 367 nr_read = read (fd, buf, sizeof_buf); 368 if (nr_read >= 0) 369 { 370 /* printf ("<nr-read=%d>\n", nr_read); */ 371 result = nr_read; 372 } 373 else 374 { /* nr_read < 0 */ 375 result = -1; 376 STATE_CALLBACK (sd)->last_errno = errno; 377 } 378 /* return to regular vewing */ 379 status = fcntl (fd, F_SETFL, flags); 380 if (status == -1) 381 { 382 perror ("sim_io_read_stdin"); 383 /* return 0; */ 384 } 385 return result; 386#else 387 return sim_io_read (sd, sim_io_fd, buf, sizeof_buf); 388#endif 389} 390