set the other three terminal state pieces for systems that HAVE_SGTTY
[deliverable/binutils-gdb.git] / gdb / ser-unix.c
CommitLineData
4e772f44
SG
1/* Serial interface for local (hardwired) serial ports on Un*x like systems
2 Copyright 1992, 1993 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20#include "defs.h"
21#include "serial.h"
22#include <fcntl.h>
23#include <sys/types.h>
4e772f44
SG
24
25#if !defined (HAVE_TERMIOS) && !defined (HAVE_TERMIO) && !defined (HAVE_SGTTY)
26#define HAVE_SGTTY
27#endif
28
29#ifdef HAVE_TERMIOS
30#include <termios.h>
31#include <unistd.h>
38dc5e12
SG
32
33struct hardwire_ttystate
34{
35 struct termios termios;
36};
dc34b11d 37#endif /* termios */
38dc5e12 38
4e772f44 39#ifdef HAVE_TERMIO
ebd99d54 40#include <termio.h>
38dc5e12 41
dc34b11d
JK
42/* It is believed that all systems which have added job control to SVR3
43 (e.g. sco) have also added termios. Even if not, trying to figure out
44 all the variations (TIOCGPGRP vs. TCGETPGRP, etc.) would be pretty
45 bewildering. So we don't attempt it. */
46
38dc5e12
SG
47struct hardwire_ttystate
48{
49 struct termio termio;
50};
dc34b11d 51#endif /* termio */
38dc5e12 52
4e772f44 53#ifdef HAVE_SGTTY
68d2db62
JK
54/* Needed for the code which uses select(). We would include <sys/select.h>
55 too if it existed on all systems. */
56#include <sys/time.h>
57
4e772f44 58#include <sgtty.h>
38dc5e12
SG
59
60struct hardwire_ttystate
61{
62 struct sgttyb sgttyb;
c2e247c4
JK
63 struct tchars tc;
64 struct ltchars ltc;
65 /* Line discipline flags. */
66 int lmode;
38dc5e12 67};
dc34b11d 68#endif /* sgtty */
4e772f44 69
9775789d
SG
70static int hardwire_open PARAMS ((serial_t scb, const char *name));
71static void hardwire_raw PARAMS ((serial_t scb));
72static int wait_for PARAMS ((serial_t scb, int timeout));
73static int hardwire_readchar PARAMS ((serial_t scb, int timeout));
74static int rate_to_code PARAMS ((int rate));
75static int hardwire_setbaudrate PARAMS ((serial_t scb, int rate));
76static int hardwire_write PARAMS ((serial_t scb, const char *str, int len));
0ac0a9f6 77/* FIXME: static void hardwire_restore PARAMS ((serial_t scb)); */
9775789d 78static void hardwire_close PARAMS ((serial_t scb));
38dc5e12
SG
79static int get_tty_state PARAMS ((serial_t scb, struct hardwire_ttystate *state));
80static int set_tty_state PARAMS ((serial_t scb, struct hardwire_ttystate *state));
81static serial_ttystate hardwire_get_tty_state PARAMS ((serial_t scb));
82static int hardwire_set_tty_state PARAMS ((serial_t scb, serial_ttystate state));
9775789d 83
4e772f44
SG
84/* Open up a real live device for serial I/O */
85
86static int
87hardwire_open(scb, name)
88 serial_t scb;
89 const char *name;
90{
91 scb->fd = open (name, O_RDWR);
92 if (scb->fd < 0)
4febd102 93 return -1;
4e772f44
SG
94
95 return 0;
96}
97
38dc5e12
SG
98static int
99get_tty_state(scb, state)
4e772f44 100 serial_t scb;
38dc5e12 101 struct hardwire_ttystate *state;
4e772f44
SG
102{
103#ifdef HAVE_TERMIOS
057c2f47 104 extern int errno;
c2e247c4
JK
105
106 if (tcgetattr(scb->fd, &state->termios) < 0)
107 return -1;
108
c2e247c4 109 return 0;
38dc5e12 110#endif
4e772f44 111
38dc5e12 112#ifdef HAVE_TERMIO
c2e247c4
JK
113 if (ioctl (scb->fd, TCGETA, &state->termio) < 0)
114 return -1;
dc34b11d 115 return 0;
38dc5e12 116#endif
4e772f44 117
38dc5e12 118#ifdef HAVE_SGTTY
c2e247c4
JK
119 if (ioctl (scb->fd, TIOCGETP, &state->sgttyb) < 0)
120 return -1;
121 if (ioctl (scb->fd, TIOCGETC, &state->tc) < 0)
122 return -1;
123 if (ioctl (scb->fd, TIOCGLTC, &state->ltc) < 0)
124 return -1;
125 if (ioctl (scb->fd, TIOCLGET, &state->lmode) < 0)
126 return -1;
127
a14a8fad 128 return 0;
38dc5e12
SG
129#endif
130}
4e772f44 131
38dc5e12
SG
132static int
133set_tty_state(scb, state)
134 serial_t scb;
135 struct hardwire_ttystate *state;
136{
38dc5e12 137#ifdef HAVE_TERMIOS
c2e247c4
JK
138 if (tcsetattr(scb->fd, TCSANOW, &state->termios) < 0)
139 return -1;
140
a14a8fad 141 return 0;
4e772f44
SG
142#endif
143
144#ifdef HAVE_TERMIO
c2e247c4
JK
145 if (ioctl (scb->fd, TCSETA, &state->termio) < 0)
146 return -1;
c2e247c4 147 return 0;
38dc5e12 148#endif
4e772f44 149
38dc5e12 150#ifdef HAVE_SGTTY
c2e247c4
JK
151 if (ioctl (scb->fd, TIOCSETN, &state->sgttyb) < 0)
152 return -1;
88cc9a42
RP
153 if (ioctl (scb->fd, TIOCSETC, &state->tc) < 0)
154 return -1;
155 if (ioctl (scb->fd, TIOCSLTC, &state->ltc) < 0)
156 return -1;
157 if (ioctl (scb->fd, TIOCLSET, &state->lmode) < 0)
158 return -1;
c2e247c4 159
a14a8fad 160 return 0;
38dc5e12
SG
161#endif
162}
4e772f44 163
38dc5e12
SG
164static serial_ttystate
165hardwire_get_tty_state(scb)
166 serial_t scb;
167{
168 struct hardwire_ttystate *state;
4e772f44 169
38dc5e12 170 state = (struct hardwire_ttystate *)xmalloc(sizeof *state);
4e772f44 171
38dc5e12
SG
172 if (get_tty_state(scb, state))
173 return NULL;
4e772f44 174
38dc5e12
SG
175 return (serial_ttystate)state;
176}
4e772f44 177
38dc5e12
SG
178static int
179hardwire_set_tty_state(scb, ttystate)
180 serial_t scb;
181 serial_ttystate ttystate;
182{
183 struct hardwire_ttystate *state;
4e772f44 184
38dc5e12
SG
185 state = (struct hardwire_ttystate *)ttystate;
186
187 return set_tty_state(scb, state);
188}
189
c2e247c4
JK
190static int
191hardwire_noflush_set_tty_state (scb, new_ttystate, old_ttystate)
192 serial_t scb;
193 serial_ttystate new_ttystate;
194 serial_ttystate old_ttystate;
195{
3fe11d47 196 struct hardwire_ttystate new_state;
c2e247c4
JK
197 struct hardwire_ttystate *state = (struct hardwire_ttystate *) old_ttystate;
198
3fe11d47
JK
199 new_state = *(struct hardwire_ttystate *)new_ttystate;
200
c2e247c4
JK
201#ifdef HAVE_TERMIOS
202 /* I'm not sure whether this is necessary; the manpage makes no mention
203 of discarding input when switching to/from ICANON. */
204 if (state->termios.c_lflag & ICANON)
205 new_state.termios.c_lflag |= ICANON;
206 else
207 new_state.termios.c_lflag &= ~ICANON;
208#endif
209
210#ifdef HAVE_TERMIO
211 /* I'm not sure whether this is necessary; the manpage makes no mention
212 of discarding input when switching to/from ICANON. */
213 if (state->termio.c_lflag & ICANON)
214 new_state.termio.c_lflag |= ICANON;
215 else
216 new_state.termio.c_lflag &= ~ICANON;
217#endif
218
219#ifdef HAVE_SGTTY
220 if (state->sgttyb.sg_flags & RAW)
221 new_state.sgttyb.sg_flags |= RAW;
222 else
223 new_state.sgttyb.sg_flags &= ~RAW;
224
225 /* I'm not sure whether this is necessary; the manpage just mentions
226 RAW not CBREAK. */
227 if (state->sgttyb.sg_flags & CBREAK)
228 new_state.sgttyb.sg_flags |= CBREAK;
229 else
230 new_state.sgttyb.sg_flags &= ~CBREAK;
231#endif
232
233 return set_tty_state (scb, &new_state);
234}
235
236static void
237hardwire_print_tty_state (scb, ttystate)
238 serial_t scb;
239 serial_ttystate ttystate;
240{
241 struct hardwire_ttystate *state = (struct hardwire_ttystate *) ttystate;
242 int i;
243
dc34b11d 244#ifdef HAVE_TERMIOS
c2e247c4
JK
245 printf_filtered ("c_iflag = 0x%x, c_oflag = 0x%x,\n",
246 state->termios.c_iflag, state->termios.c_oflag);
a77a5278
JK
247 printf_filtered ("c_cflag = 0x%x, c_lflag = 0x%x\n",
248 state->termios.c_cflag, state->termios.c_lflag);
249#if 0
250 /* This not in POSIX, and is not really documented by those systems
251 which have it (at least not Sun). */
252 printf_filtered ("c_line = 0x%x.\n", state->termios.c_line);
253#endif
c2e247c4
JK
254 printf_filtered ("c_cc: ");
255 for (i = 0; i < NCCS; i += 1)
256 printf_filtered ("0x%x ", state->termios.c_cc[i]);
257 printf_filtered ("\n");
258#endif
259
260#ifdef HAVE_TERMIO
261 printf_filtered ("c_iflag = 0x%x, c_oflag = 0x%x,\n",
262 state->termio.c_iflag, state->termio.c_oflag);
263 printf_filtered ("c_cflag = 0x%x, c_lflag = 0x%x, c_line = 0x%x.\n",
264 state->termio.c_cflag, state->termio.c_lflag,
265 state->termio.c_line);
266 printf_filtered ("c_cc: ");
267 for (i = 0; i < NCC; i += 1)
268 printf_filtered ("0x%x ", state->termio.c_cc[i]);
269 printf_filtered ("\n");
270#endif
271
272#ifdef HAVE_SGTTY
273 printf_filtered ("sgttyb.sg_flags = 0x%x.\n", state->sgttyb.sg_flags);
274
275 printf_filtered ("tchars: ");
276 for (i = 0; i < (int)sizeof (struct tchars); i++)
277 printf_filtered ("0x%x ", ((unsigned char *)&state->tc)[i]);
278 printf_filtered ("\n");
279
280 printf_filtered ("ltchars: ");
281 for (i = 0; i < (int)sizeof (struct ltchars); i++)
282 printf_filtered ("0x%x ", ((unsigned char *)&state->ltc)[i]);
283 printf_filtered ("\n");
284
285 printf_filtered ("lmode: 0x%x\n", state->lmode);
286#endif
287}
288
289static int
290hardwire_flush_output (scb)
291 serial_t scb;
292{
293#ifdef HAVE_TERMIOS
294 return tcflush (scb->fd, TCOFLUSH);
295#endif
296
297#ifdef HAVE_TERMIO
298 return ioctl (scb->fd, TCFLSH, 1);
299#endif
300
301#ifdef HAVE_SGTTY
302 /* This flushes both input and output, but we can't do better. */
303 return ioctl (scb->fd, TIOCFLUSH, 0);
304#endif
305}
306
704deef2
JK
307static int
308hardwire_flush_input (scb)
309 serial_t scb;
310{
311#ifdef HAVE_TERMIOS
312 return tcflush (scb->fd, TCIFLUSH);
313#endif
314
315#ifdef HAVE_TERMIO
316 return ioctl (scb->fd, TCFLSH, 0);
317#endif
318
319#ifdef HAVE_SGTTY
320 /* This flushes both input and output, but we can't do better. */
321 return ioctl (scb->fd, TIOCFLUSH, 0);
322#endif
323}
324
325static int
326hardwire_send_break (scb)
327 serial_t scb;
328{
704deef2
JK
329#ifdef HAVE_TERMIOS
330 return tcsendbreak (scb->fd, 0);
331#endif
332
333#ifdef HAVE_TERMIO
334 return ioctl (scb->fd, TCSBRK, 0);
335#endif
336
337#ifdef HAVE_SGTTY
95a98b5e 338 {
0ac0a9f6 339 int status;
95a98b5e
JK
340 struct timeval timeout;
341
342 status = ioctl (scb->fd, TIOCSBRK, 0);
343
344 /* Can't use usleep; it doesn't exist in BSD 4.2. */
345 /* Note that if this select() is interrupted by a signal it will not wait
346 the full length of time. I think that is OK. */
347 timeout.tv_sec = 0;
348 timeout.tv_usec = 250000;
349 select (0, 0, 0, 0, &timeout);
350 status = ioctl (scb->fd, TIOCCBRK, 0);
351 return status;
352 }
704deef2
JK
353#endif
354}
355
38dc5e12
SG
356static void
357hardwire_raw(scb)
358 serial_t scb;
359{
360 struct hardwire_ttystate state;
361
362 if (get_tty_state(scb, &state))
199b2450 363 fprintf_unfiltered(gdb_stderr, "get_tty_state failed: %s\n", safe_strerror(errno));
38dc5e12
SG
364
365#ifdef HAVE_TERMIOS
366 state.termios.c_iflag = 0;
367 state.termios.c_oflag = 0;
368 state.termios.c_lflag = 0;
369 state.termios.c_cflag &= ~(CSIZE|PARENB);
370 state.termios.c_cflag |= CS8;
371 state.termios.c_cc[VMIN] = 0;
372 state.termios.c_cc[VTIME] = 0;
373#endif
374
375#ifdef HAVE_TERMIO
376 state.termio.c_iflag = 0;
377 state.termio.c_oflag = 0;
378 state.termio.c_lflag = 0;
379 state.termio.c_cflag &= ~(CSIZE|PARENB);
380 state.termio.c_cflag |= CS8;
381 state.termio.c_cc[VMIN] = 0;
382 state.termio.c_cc[VTIME] = 0;
383#endif
384
385#ifdef HAVE_SGTTY
386 state.sgttyb.sg_flags |= RAW | ANYP;
387 state.sgttyb.sg_flags &= ~(CBREAK | ECHO);
4e772f44 388#endif
9e15da4a
SG
389
390 scb->current_timeout = 0;
38dc5e12
SG
391
392 if (set_tty_state (scb, &state))
199b2450 393 fprintf_unfiltered(gdb_stderr, "set_tty_state failed: %s\n", safe_strerror(errno));
4e772f44
SG
394}
395
9e15da4a
SG
396/* Wait for input on scb, with timeout seconds. Returns 0 on success,
397 otherwise SERIAL_TIMEOUT or SERIAL_ERROR.
398
399 For termio{s}, we actually just setup VTIME if necessary, and let the
400 timeout occur in the read() in hardwire_read().
401 */
4e772f44
SG
402
403static int
9775789d 404wait_for(scb, timeout)
4e772f44
SG
405 serial_t scb;
406 int timeout;
407{
9775789d
SG
408#ifdef HAVE_SGTTY
409 struct timeval tv;
410 fd_set readfds;
eca29634 411
9775789d 412 FD_ZERO (&readfds);
eca29634 413
9775789d
SG
414 tv.tv_sec = timeout;
415 tv.tv_usec = 0;
eca29634 416
9775789d 417 FD_SET(scb->fd, &readfds);
eca29634 418
a037b21e
SG
419 while (1)
420 {
0ac0a9f6
RP
421 int numfds;
422
a037b21e
SG
423 if (timeout >= 0)
424 numfds = select(scb->fd+1, &readfds, 0, 0, &tv);
425 else
426 numfds = select(scb->fd+1, &readfds, 0, 0, 0);
427
428 if (numfds <= 0)
429 if (numfds == 0)
430 return SERIAL_TIMEOUT;
431 else if (errno == EINTR)
432 continue;
433 else
434 return SERIAL_ERROR; /* Got an error from select or poll */
435
436 return 0;
437 }
9e15da4a 438
9775789d 439#endif /* HAVE_SGTTY */
4e772f44 440
9775789d 441#if defined HAVE_TERMIO || defined HAVE_TERMIOS
9e15da4a
SG
442 if (timeout == scb->current_timeout)
443 return 0;
4e772f44 444
9e15da4a 445 {
38dc5e12 446 struct hardwire_ttystate state;
eca29634 447
38dc5e12 448 if (get_tty_state(scb, &state))
199b2450 449 fprintf_unfiltered(gdb_stderr, "get_tty_state failed: %s\n", safe_strerror(errno));
eca29634 450
38dc5e12
SG
451#ifdef HAVE_TERMIOS
452 state.termios.c_cc[VTIME] = timeout * 10;
453#endif
9775789d 454
9e15da4a 455#ifdef HAVE_TERMIO
38dc5e12
SG
456 state.termio.c_cc[VTIME] = timeout * 10;
457#endif
9e15da4a 458
38dc5e12 459 scb->current_timeout = timeout;
9e15da4a 460
38dc5e12 461 if (set_tty_state (scb, &state))
199b2450 462 fprintf_unfiltered(gdb_stderr, "set_tty_state failed: %s\n", safe_strerror(errno));
9e15da4a 463
9e15da4a
SG
464 return 0;
465 }
466#endif /* HAVE_TERMIO || HAVE_TERMIOS */
9775789d
SG
467}
468
469/* Read a character with user-specified timeout. TIMEOUT is number of seconds
470 to wait, or -1 to wait forever. Use timeout of 0 to effect a poll. Returns
057c2f47
RP
471 char if successful. Returns SERIAL_TIMEOUT if timeout expired, EOF if line
472 dropped dead, or SERIAL_ERROR for any other error (see errno in that case). */
9775789d
SG
473
474static int
475hardwire_readchar(scb, timeout)
476 serial_t scb;
477 int timeout;
478{
479 int status;
480
481 if (scb->bufcnt-- > 0)
482 return *scb->bufp++;
483
484 status = wait_for(scb, timeout);
485
486 if (status < 0)
487 return status;
4e772f44 488
9775789d 489 scb->bufcnt = read(scb->fd, scb->buf, BUFSIZ);
4e772f44
SG
490
491 if (scb->bufcnt <= 0)
492 if (scb->bufcnt == 0)
9e15da4a
SG
493 return SERIAL_TIMEOUT; /* 0 chars means timeout [may need to
494 distinguish between EOF & timeouts
495 someday] */
4e772f44 496 else
4febd102 497 return SERIAL_ERROR; /* Got an error from read */
4e772f44
SG
498
499 scb->bufcnt--;
500 scb->bufp = scb->buf;
501 return *scb->bufp++;
502}
503
504#ifndef B19200
505#define B19200 EXTA
506#endif
507
508#ifndef B38400
509#define B38400 EXTB
510#endif
511
512/* Translate baud rates from integers to damn B_codes. Unix should
513 have outgrown this crap years ago, but even POSIX wouldn't buck it. */
514
515static struct
516{
517 int rate;
518 int code;
519}
520baudtab[] =
521{
522 {50, B50},
523 {75, B75},
524 {110, B110},
525 {134, B134},
526 {150, B150},
527 {200, B200},
528 {300, B300},
529 {600, B600},
530 {1200, B1200},
531 {1800, B1800},
532 {2400, B2400},
533 {4800, B4800},
534 {9600, B9600},
535 {19200, B19200},
536 {38400, B38400},
537 {-1, -1},
538};
539
540static int
541rate_to_code(rate)
542 int rate;
543{
544 int i;
545
546 for (i = 0; baudtab[i].rate != -1; i++)
547 if (rate == baudtab[i].rate)
548 return baudtab[i].code;
549
550 return -1;
551}
552
553static int
554hardwire_setbaudrate(scb, rate)
555 serial_t scb;
556 int rate;
557{
38dc5e12 558 struct hardwire_ttystate state;
4e772f44 559
38dc5e12 560 if (get_tty_state(scb, &state))
4febd102 561 return -1;
4e772f44 562
38dc5e12
SG
563#ifdef HAVE_TERMIOS
564 cfsetospeed (&state.termios, rate_to_code (rate));
565 cfsetispeed (&state.termios, rate_to_code (rate));
4e772f44
SG
566#endif
567
568#ifdef HAVE_TERMIO
4e772f44
SG
569#ifndef CIBAUD
570#define CIBAUD CBAUD
571#endif
572
38dc5e12
SG
573 state.termio.c_cflag &= ~(CBAUD | CIBAUD);
574 state.termio.c_cflag |= rate_to_code (rate);
4e772f44
SG
575#endif
576
577#ifdef HAVE_SGTTY
38dc5e12
SG
578 state.sgttyb.sg_ispeed = rate_to_code (rate);
579 state.sgttyb.sg_ospeed = rate_to_code (rate);
4e772f44 580#endif
38dc5e12
SG
581
582 return set_tty_state (scb, &state);
4e772f44
SG
583}
584
585static int
586hardwire_write(scb, str, len)
587 serial_t scb;
588 const char *str;
589 int len;
590{
591 int cc;
592
593 while (len > 0)
594 {
595 cc = write(scb->fd, str, len);
596
597 if (cc < 0)
598 return 1;
599 len -= cc;
600 str += cc;
601 }
602 return 0;
603}
604
4e772f44
SG
605static void
606hardwire_close(scb)
607 serial_t scb;
608{
609 if (scb->fd < 0)
610 return;
611
4e772f44
SG
612 close(scb->fd);
613 scb->fd = -1;
614}
615
616static struct serial_ops hardwire_ops =
617{
618 "hardwire",
619 0,
620 hardwire_open,
621 hardwire_close,
622 hardwire_readchar,
623 hardwire_write,
c2e247c4 624 hardwire_flush_output,
704deef2
JK
625 hardwire_flush_input,
626 hardwire_send_break,
4e772f44 627 hardwire_raw,
38dc5e12
SG
628 hardwire_get_tty_state,
629 hardwire_set_tty_state,
c2e247c4
JK
630 hardwire_print_tty_state,
631 hardwire_noflush_set_tty_state,
38dc5e12 632 hardwire_setbaudrate,
4e772f44
SG
633};
634
9775789d 635void
4e772f44
SG
636_initialize_ser_hardwire ()
637{
638 serial_add_interface (&hardwire_ops);
639}
This page took 0.112801 seconds and 4 git commands to generate.