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