1 /* Serial interface for local (hardwired) serial ports on Un*x like systems 2 Copyright 1992, 1993, 1994 Free Software Foundation, Inc. 3 4 This file is part of GDB. 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, write to the Free Software 18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 19 20 #include "defs.h" 21 #include "serial.h" 22 #include <fcntl.h> 23 #include <sys/types.h> 24 #include "terminal.h" 25 #ifdef HAVE_UNISTD_H 26 #include <unistd.h> 27 #endif 28 29 #ifdef HAVE_TERMIOS 30 31 struct hardwire_ttystate 32 { 33 struct termios termios; 34 }; 35 #endif /* termios */ 36 37 #ifdef HAVE_TERMIO 38 39 /* It is believed that all systems which have added job control to SVR3 40 (e.g. sco) have also added termios. Even if not, trying to figure out 41 all the variations (TIOCGPGRP vs. TCGETPGRP, etc.) would be pretty 42 bewildering. So we don't attempt it. */ 43 44 struct hardwire_ttystate 45 { 46 struct termio termio; 47 }; 48 #endif /* termio */ 49 50 #ifdef HAVE_SGTTY 51 /* Needed for the code which uses select(). We would include <sys/select.h> 52 too if it existed on all systems. */ 53 #include <sys/time.h> 54 55 struct hardwire_ttystate 56 { 57 struct sgttyb sgttyb; 58 struct tchars tc; 59 struct ltchars ltc; 60 /* Line discipline flags. */ 61 int lmode; 62 }; 63 #endif /* sgtty */ 64 65 static int hardwire_open PARAMS ((serial_t scb, const char *name)); 66 static void hardwire_raw PARAMS ((serial_t scb)); 67 static int wait_for PARAMS ((serial_t scb, int timeout)); 68 static int hardwire_readchar PARAMS ((serial_t scb, int timeout)); 69 static int rate_to_code PARAMS ((int rate)); 70 static int hardwire_setbaudrate PARAMS ((serial_t scb, int rate)); 71 static int hardwire_write PARAMS ((serial_t scb, const char *str, int len)); 72 static void hardwire_close PARAMS ((serial_t scb)); 73 static int get_tty_state PARAMS ((serial_t scb, struct hardwire_ttystate *state)); 74 static int set_tty_state PARAMS ((serial_t scb, struct hardwire_ttystate *state)); 75 static serial_ttystate hardwire_get_tty_state PARAMS ((serial_t scb)); 76 static int hardwire_set_tty_state PARAMS ((serial_t scb, serial_ttystate state)); 77 static int hardwire_noflush_set_tty_state PARAMS ((serial_t, serial_ttystate, 78 serial_ttystate)); 79 static void hardwire_print_tty_state PARAMS ((serial_t, serial_ttystate)); 80 static int hardwire_flush_output PARAMS ((serial_t)); 81 static int hardwire_flush_input PARAMS ((serial_t)); 82 static int hardwire_send_break PARAMS ((serial_t)); 83 static int hardwire_setstopbits PARAMS ((serial_t, int)); 84 85 /* Open up a real live device for serial I/O */ 86 87 static int 88 hardwire_open(scb, name) 89 serial_t scb; 90 const char *name; 91 { 92 scb->fd = open (name, O_RDWR); 93 if (scb->fd < 0) 94 return -1; 95 96 return 0; 97 } 98 99 static int 100 get_tty_state(scb, state) 101 serial_t scb; 102 struct hardwire_ttystate *state; 103 { 104 #ifdef HAVE_TERMIOS 105 extern int errno; 106 107 if (tcgetattr(scb->fd, &state->termios) < 0) 108 return -1; 109 110 return 0; 111 #endif 112 113 #ifdef HAVE_TERMIO 114 if (ioctl (scb->fd, TCGETA, &state->termio) < 0) 115 return -1; 116 return 0; 117 #endif 118 119 #ifdef HAVE_SGTTY 120 if (ioctl (scb->fd, TIOCGETP, &state->sgttyb) < 0) 121 return -1; 122 if (ioctl (scb->fd, TIOCGETC, &state->tc) < 0) 123 return -1; 124 if (ioctl (scb->fd, TIOCGLTC, &state->ltc) < 0) 125 return -1; 126 if (ioctl (scb->fd, TIOCLGET, &state->lmode) < 0) 127 return -1; 128 129 return 0; 130 #endif 131 } 132 133 static int 134 set_tty_state(scb, state) 135 serial_t scb; 136 struct hardwire_ttystate *state; 137 { 138 #ifdef HAVE_TERMIOS 139 if (tcsetattr(scb->fd, TCSANOW, &state->termios) < 0) 140 return -1; 141 142 return 0; 143 #endif 144 145 #ifdef HAVE_TERMIO 146 if (ioctl (scb->fd, TCSETA, &state->termio) < 0) 147 return -1; 148 return 0; 149 #endif 150 151 #ifdef HAVE_SGTTY 152 if (ioctl (scb->fd, TIOCSETN, &state->sgttyb) < 0) 153 return -1; 154 if (ioctl (scb->fd, TIOCSETC, &state->tc) < 0) 155 return -1; 156 if (ioctl (scb->fd, TIOCSLTC, &state->ltc) < 0) 157 return -1; 158 if (ioctl (scb->fd, TIOCLSET, &state->lmode) < 0) 159 return -1; 160 161 return 0; 162 #endif 163 } 164 165 static serial_ttystate 166 hardwire_get_tty_state(scb) 167 serial_t scb; 168 { 169 struct hardwire_ttystate *state; 170 171 state = (struct hardwire_ttystate *)xmalloc(sizeof *state); 172 173 if (get_tty_state(scb, state)) 174 return NULL; 175 176 return (serial_ttystate)state; 177 } 178 179 static int 180 hardwire_set_tty_state(scb, ttystate) 181 serial_t scb; 182 serial_ttystate ttystate; 183 { 184 struct hardwire_ttystate *state; 185 186 state = (struct hardwire_ttystate *)ttystate; 187 188 return set_tty_state(scb, state); 189 } 190 191 static int 192 hardwire_noflush_set_tty_state (scb, new_ttystate, old_ttystate) 193 serial_t scb; 194 serial_ttystate new_ttystate; 195 serial_ttystate old_ttystate; 196 { 197 struct hardwire_ttystate new_state; 198 #ifdef HAVE_SGTTY 199 struct hardwire_ttystate *state = (struct hardwire_ttystate *) old_ttystate; 200 #endif 201 202 new_state = *(struct hardwire_ttystate *)new_ttystate; 203 204 /* Don't change in or out of raw mode; we don't want to flush input. 205 termio and termios have no such restriction; for them flushing input 206 is separate from setting the attributes. */ 207 208 #ifdef HAVE_SGTTY 209 if (state->sgttyb.sg_flags & RAW) 210 new_state.sgttyb.sg_flags |= RAW; 211 else 212 new_state.sgttyb.sg_flags &= ~RAW; 213 214 /* I'm not sure whether this is necessary; the manpage just mentions 215 RAW not CBREAK. */ 216 if (state->sgttyb.sg_flags & CBREAK) 217 new_state.sgttyb.sg_flags |= CBREAK; 218 else 219 new_state.sgttyb.sg_flags &= ~CBREAK; 220 #endif 221 222 return set_tty_state (scb, &new_state); 223 } 224 225 static void 226 hardwire_print_tty_state (scb, ttystate) 227 serial_t scb; 228 serial_ttystate ttystate; 229 { 230 struct hardwire_ttystate *state = (struct hardwire_ttystate *) ttystate; 231 int i; 232 233 #ifdef HAVE_TERMIOS 234 printf_filtered ("c_iflag = 0x%x, c_oflag = 0x%x,\n", 235 state->termios.c_iflag, state->termios.c_oflag); 236 printf_filtered ("c_cflag = 0x%x, c_lflag = 0x%x\n", 237 state->termios.c_cflag, state->termios.c_lflag); 238 #if 0 239 /* This not in POSIX, and is not really documented by those systems 240 which have it (at least not Sun). */ 241 printf_filtered ("c_line = 0x%x.\n", state->termios.c_line); 242 #endif 243 printf_filtered ("c_cc: "); 244 for (i = 0; i < NCCS; i += 1) 245 printf_filtered ("0x%x ", state->termios.c_cc[i]); 246 printf_filtered ("\n"); 247 #endif 248 249 #ifdef HAVE_TERMIO 250 printf_filtered ("c_iflag = 0x%x, c_oflag = 0x%x,\n", 251 state->termio.c_iflag, state->termio.c_oflag); 252 printf_filtered ("c_cflag = 0x%x, c_lflag = 0x%x, c_line = 0x%x.\n", 253 state->termio.c_cflag, state->termio.c_lflag, 254 state->termio.c_line); 255 printf_filtered ("c_cc: "); 256 for (i = 0; i < NCC; i += 1) 257 printf_filtered ("0x%x ", state->termio.c_cc[i]); 258 printf_filtered ("\n"); 259 #endif 260 261 #ifdef HAVE_SGTTY 262 printf_filtered ("sgttyb.sg_flags = 0x%x.\n", state->sgttyb.sg_flags); 263 264 printf_filtered ("tchars: "); 265 for (i = 0; i < (int)sizeof (struct tchars); i++) 266 printf_filtered ("0x%x ", ((unsigned char *)&state->tc)[i]); 267 printf_filtered ("\n"); 268 269 printf_filtered ("ltchars: "); 270 for (i = 0; i < (int)sizeof (struct ltchars); i++) 271 printf_filtered ("0x%x ", ((unsigned char *)&state->ltc)[i]); 272 printf_filtered ("\n"); 273 274 printf_filtered ("lmode: 0x%x\n", state->lmode); 275 #endif 276 } 277 278 static int 279 hardwire_flush_output (scb) 280 serial_t scb; 281 { 282 #ifdef HAVE_TERMIOS 283 return tcflush (scb->fd, TCOFLUSH); 284 #endif 285 286 #ifdef HAVE_TERMIO 287 return ioctl (scb->fd, TCFLSH, 1); 288 #endif 289 290 #ifdef HAVE_SGTTY 291 /* This flushes both input and output, but we can't do better. */ 292 return ioctl (scb->fd, TIOCFLUSH, 0); 293 #endif 294 } 295 296 static int 297 hardwire_flush_input (scb) 298 serial_t scb; 299 { 300 scb->bufcnt = 0; 301 scb->bufp = scb->buf; 302 303 #ifdef HAVE_TERMIOS 304 return tcflush (scb->fd, TCIFLUSH); 305 #endif 306 307 #ifdef HAVE_TERMIO 308 return ioctl (scb->fd, TCFLSH, 0); 309 #endif 310 311 #ifdef HAVE_SGTTY 312 /* This flushes both input and output, but we can't do better. */ 313 return ioctl (scb->fd, TIOCFLUSH, 0); 314 #endif 315 } 316 317 static int 318 hardwire_send_break (scb) 319 serial_t scb; 320 { 321 #ifdef HAVE_TERMIOS 322 return tcsendbreak (scb->fd, 0); 323 #endif 324 325 #ifdef HAVE_TERMIO 326 return ioctl (scb->fd, TCSBRK, 0); 327 #endif 328 329 #ifdef HAVE_SGTTY 330 { 331 int status; 332 struct timeval timeout; 333 334 status = ioctl (scb->fd, TIOCSBRK, 0); 335 336 /* Can't use usleep; it doesn't exist in BSD 4.2. */ 337 /* Note that if this select() is interrupted by a signal it will not wait 338 the full length of time. I think that is OK. */ 339 timeout.tv_sec = 0; 340 timeout.tv_usec = 250000; 341 select (0, 0, 0, 0, &timeout); 342 status = ioctl (scb->fd, TIOCCBRK, 0); 343 return status; 344 } 345 #endif 346 } 347 348 static void 349 hardwire_raw(scb) 350 serial_t scb; 351 { 352 struct hardwire_ttystate state; 353 354 if (get_tty_state(scb, &state)) 355 fprintf_unfiltered(gdb_stderr, "get_tty_state failed: %s\n", safe_strerror(errno)); 356 357 #ifdef HAVE_TERMIOS 358 state.termios.c_iflag = 0; 359 state.termios.c_oflag = 0; 360 state.termios.c_lflag = 0; 361 state.termios.c_cflag &= ~(CSIZE|PARENB); 362 state.termios.c_cflag |= CLOCAL | CS8; 363 state.termios.c_cc[VMIN] = 0; 364 state.termios.c_cc[VTIME] = 0; 365 #endif 366 367 #ifdef HAVE_TERMIO 368 state.termio.c_iflag = 0; 369 state.termio.c_oflag = 0; 370 state.termio.c_lflag = 0; 371 state.termio.c_cflag &= ~(CSIZE|PARENB); 372 state.termio.c_cflag |= CLOCAL | CS8; 373 state.termio.c_cc[VMIN] = 0; 374 state.termio.c_cc[VTIME] = 0; 375 #endif 376 377 #ifdef HAVE_SGTTY 378 state.sgttyb.sg_flags |= RAW | ANYP; 379 state.sgttyb.sg_flags &= ~(CBREAK | ECHO); 380 #endif 381 382 scb->current_timeout = 0; 383 384 if (set_tty_state (scb, &state)) 385 fprintf_unfiltered(gdb_stderr, "set_tty_state failed: %s\n", safe_strerror(errno)); 386 } 387 388 /* Wait for input on scb, with timeout seconds. Returns 0 on success, 389 otherwise SERIAL_TIMEOUT or SERIAL_ERROR. 390 391 For termio{s}, we actually just setup VTIME if necessary, and let the 392 timeout occur in the read() in hardwire_read(). 393 */ 394 395 static int 396 wait_for(scb, timeout) 397 serial_t scb; 398 int timeout; 399 { 400 scb->timeout_remaining = 0; 401 402 #ifdef HAVE_SGTTY 403 { 404 struct timeval tv; 405 fd_set readfds; 406 407 FD_ZERO (&readfds); 408 409 tv.tv_sec = timeout; 410 tv.tv_usec = 0; 411 412 FD_SET(scb->fd, &readfds); 413 414 while (1) 415 { 416 int numfds; 417 418 if (timeout >= 0) 419 numfds = select(scb->fd+1, &readfds, 0, 0, &tv); 420 else 421 numfds = select(scb->fd+1, &readfds, 0, 0, 0); 422 423 if (numfds <= 0) 424 if (numfds == 0) 425 return SERIAL_TIMEOUT; 426 else if (errno == EINTR) 427 continue; 428 else 429 return SERIAL_ERROR; /* Got an error from select or poll */ 430 431 return 0; 432 } 433 } 434 #endif /* HAVE_SGTTY */ 435 436 #if defined HAVE_TERMIO || defined HAVE_TERMIOS 437 if (timeout == scb->current_timeout) 438 return 0; 439 440 scb->current_timeout = timeout; 441 442 { 443 struct hardwire_ttystate state; 444 445 if (get_tty_state(scb, &state)) 446 fprintf_unfiltered(gdb_stderr, "get_tty_state failed: %s\n", safe_strerror(errno)); 447 448 #ifdef HAVE_TERMIOS 449 if (timeout < 0) 450 { 451 /* No timeout. */ 452 state.termios.c_cc[VTIME] = 0; 453 state.termios.c_cc[VMIN] = 1; 454 } 455 else 456 { 457 state.termios.c_cc[VMIN] = 0; 458 state.termios.c_cc[VTIME] = timeout * 10; 459 if (state.termios.c_cc[VTIME] != timeout * 10) 460 { 461 462 /* If c_cc is an 8-bit signed character, we can't go 463 bigger than this. If it is always unsigned, we could use 464 25. */ 465 466 scb->current_timeout = 12; 467 state.termios.c_cc[VTIME] = scb->current_timeout * 10; 468 scb->timeout_remaining = timeout - scb->current_timeout; 469 } 470 } 471 #endif 472 473 #ifdef HAVE_TERMIO 474 if (timeout < 0) 475 { 476 /* No timeout. */ 477 state.termio.c_cc[VTIME] = 0; 478 state.termio.c_cc[VMIN] = 1; 479 } 480 else 481 { 482 state.termio.c_cc[VMIN] = 0; 483 state.termio.c_cc[VTIME] = timeout * 10; 484 if (state.termio.c_cc[VTIME] != timeout * 10) 485 { 486 /* If c_cc is an 8-bit signed character, we can't go 487 bigger than this. If it is always unsigned, we could use 488 25. */ 489 490 scb->current_timeout = 12; 491 state.termio.c_cc[VTIME] = scb->current_timeout * 10; 492 scb->timeout_remaining = timeout - scb->current_timeout; 493 } 494 } 495 #endif 496 497 if (set_tty_state (scb, &state)) 498 fprintf_unfiltered(gdb_stderr, "set_tty_state failed: %s\n", safe_strerror(errno)); 499 500 return 0; 501 } 502 #endif /* HAVE_TERMIO || HAVE_TERMIOS */ 503 } 504 505 /* Read a character with user-specified timeout. TIMEOUT is number of seconds 506 to wait, or -1 to wait forever. Use timeout of 0 to effect a poll. Returns 507 char if successful. Returns SERIAL_TIMEOUT if timeout expired, EOF if line 508 dropped dead, or SERIAL_ERROR for any other error (see errno in that case). */ 509 510 static int 511 hardwire_readchar(scb, timeout) 512 serial_t scb; 513 int timeout; 514 { 515 int status; 516 517 if (scb->bufcnt-- > 0) 518 return *scb->bufp++; 519 520 while (1) 521 { 522 status = wait_for (scb, timeout); 523 524 if (status < 0) 525 return status; 526 527 scb->bufcnt = read (scb->fd, scb->buf, BUFSIZ); 528 529 if (scb->bufcnt <= 0) 530 { 531 if (scb->bufcnt == 0) 532 { 533 /* Zero characters means timeout (it could also be EOF, but 534 we don't (yet at least) distinguish). */ 535 if (scb->timeout_remaining > 0) 536 { 537 timeout = scb->timeout_remaining; 538 continue; 539 } 540 else 541 return SERIAL_TIMEOUT; 542 } 543 else if (errno == EINTR) 544 continue; 545 else 546 return SERIAL_ERROR; /* Got an error from read */ 547 } 548 549 scb->bufcnt--; 550 scb->bufp = scb->buf; 551 return *scb->bufp++; 552 } 553 } 554 555 #ifndef B19200 556 #define B19200 EXTA 557 #endif 558 559 #ifndef B38400 560 #define B38400 EXTB 561 #endif 562 563 /* Translate baud rates from integers to damn B_codes. Unix should 564 have outgrown this crap years ago, but even POSIX wouldn't buck it. */ 565 566 static struct 567 { 568 int rate; 569 int code; 570 } 571 baudtab[] = 572 { 573 {50, B50}, 574 {75, B75}, 575 {110, B110}, 576 {134, B134}, 577 {150, B150}, 578 {200, B200}, 579 {300, B300}, 580 {600, B600}, 581 {1200, B1200}, 582 {1800, B1800}, 583 {2400, B2400}, 584 {4800, B4800}, 585 {9600, B9600}, 586 {19200, B19200}, 587 {38400, B38400}, 588 {-1, -1}, 589 }; 590 591 static int 592 rate_to_code(rate) 593 int rate; 594 { 595 int i; 596 597 for (i = 0; baudtab[i].rate != -1; i++) 598 if (rate == baudtab[i].rate) 599 return baudtab[i].code; 600 601 return -1; 602 } 603 604 static int 605 hardwire_setbaudrate(scb, rate) 606 serial_t scb; 607 int rate; 608 { 609 struct hardwire_ttystate state; 610 611 if (get_tty_state(scb, &state)) 612 return -1; 613 614 #ifdef HAVE_TERMIOS 615 cfsetospeed (&state.termios, rate_to_code (rate)); 616 cfsetispeed (&state.termios, rate_to_code (rate)); 617 #endif 618 619 #ifdef HAVE_TERMIO 620 #ifndef CIBAUD 621 #define CIBAUD CBAUD 622 #endif 623 624 state.termio.c_cflag &= ~(CBAUD | CIBAUD); 625 state.termio.c_cflag |= rate_to_code (rate); 626 #endif 627 628 #ifdef HAVE_SGTTY 629 state.sgttyb.sg_ispeed = rate_to_code (rate); 630 state.sgttyb.sg_ospeed = rate_to_code (rate); 631 #endif 632 633 return set_tty_state (scb, &state); 634 } 635 636 static int 637 hardwire_setstopbits(scb, num) 638 serial_t scb; 639 int num; 640 { 641 struct hardwire_ttystate state; 642 int newbit; 643 644 if (get_tty_state(scb, &state)) 645 return -1; 646 647 switch (num) 648 { 649 case SERIAL_1_STOPBITS: 650 newbit = 0; 651 break; 652 case SERIAL_1_AND_A_HALF_STOPBITS: 653 case SERIAL_2_STOPBITS: 654 newbit = 1; 655 break; 656 default: 657 return 1; 658 } 659 660 #ifdef HAVE_TERMIOS 661 if (!newbit) 662 state.termios.c_cflag &= ~CSTOPB; 663 else 664 state.termios.c_cflag |= CSTOPB; /* two bits */ 665 #endif 666 667 #ifdef HAVE_TERMIO 668 if (!newbit) 669 state.termio.c_cflag &= ~CSTOPB; 670 else 671 state.termio.c_cflag |= CSTOPB; /* two bits */ 672 #endif 673 674 #ifdef HAVE_SGTTY 675 return 0; /* sgtty doesn't support this */ 676 #endif 677 678 return set_tty_state (scb, &state); 679 } 680 681 static int 682 hardwire_write(scb, str, len) 683 serial_t scb; 684 const char *str; 685 int len; 686 { 687 int cc; 688 689 while (len > 0) 690 { 691 cc = write(scb->fd, str, len); 692 693 if (cc < 0) 694 return 1; 695 len -= cc; 696 str += cc; 697 } 698 return 0; 699 } 700 701 static void 702 hardwire_close(scb) 703 serial_t scb; 704 { 705 if (scb->fd < 0) 706 return; 707 708 close(scb->fd); 709 scb->fd = -1; 710 } 711 712 static struct serial_ops hardwire_ops = 713 { 714 "hardwire", 715 0, 716 hardwire_open, 717 hardwire_close, 718 hardwire_readchar, 719 hardwire_write, 720 hardwire_flush_output, 721 hardwire_flush_input, 722 hardwire_send_break, 723 hardwire_raw, 724 hardwire_get_tty_state, 725 hardwire_set_tty_state, 726 hardwire_print_tty_state, 727 hardwire_noflush_set_tty_state, 728 hardwire_setbaudrate, 729 hardwire_setstopbits, 730 }; 731 732 void 733 _initialize_ser_hardwire () 734 { 735 serial_add_interface (&hardwire_ops); 736 } 737