set the other three terminal state pieces for systems that HAVE_SGTTY
[deliverable/binutils-gdb.git] / gdb / ser-unix.c
1 /* Serial interface for local (hardwired) serial ports on Un*x like systems
2 Copyright 1992, 1993 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., 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>
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>
32
33 struct hardwire_ttystate
34 {
35 struct termios termios;
36 };
37 #endif /* termios */
38
39 #ifdef HAVE_TERMIO
40 #include <termio.h>
41
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
47 struct hardwire_ttystate
48 {
49 struct termio termio;
50 };
51 #endif /* termio */
52
53 #ifdef HAVE_SGTTY
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
58 #include <sgtty.h>
59
60 struct hardwire_ttystate
61 {
62 struct sgttyb sgttyb;
63 struct tchars tc;
64 struct ltchars ltc;
65 /* Line discipline flags. */
66 int lmode;
67 };
68 #endif /* sgtty */
69
70 static int hardwire_open PARAMS ((serial_t scb, const char *name));
71 static void hardwire_raw PARAMS ((serial_t scb));
72 static int wait_for PARAMS ((serial_t scb, int timeout));
73 static int hardwire_readchar PARAMS ((serial_t scb, int timeout));
74 static int rate_to_code PARAMS ((int rate));
75 static int hardwire_setbaudrate PARAMS ((serial_t scb, int rate));
76 static int hardwire_write PARAMS ((serial_t scb, const char *str, int len));
77 /* FIXME: static void hardwire_restore PARAMS ((serial_t scb)); */
78 static void hardwire_close PARAMS ((serial_t scb));
79 static int get_tty_state PARAMS ((serial_t scb, struct hardwire_ttystate *state));
80 static int set_tty_state PARAMS ((serial_t scb, struct hardwire_ttystate *state));
81 static serial_ttystate hardwire_get_tty_state PARAMS ((serial_t scb));
82 static int hardwire_set_tty_state PARAMS ((serial_t scb, serial_ttystate state));
83
84 /* Open up a real live device for serial I/O */
85
86 static int
87 hardwire_open(scb, name)
88 serial_t scb;
89 const char *name;
90 {
91 scb->fd = open (name, O_RDWR);
92 if (scb->fd < 0)
93 return -1;
94
95 return 0;
96 }
97
98 static int
99 get_tty_state(scb, state)
100 serial_t scb;
101 struct hardwire_ttystate *state;
102 {
103 #ifdef HAVE_TERMIOS
104 extern int errno;
105
106 if (tcgetattr(scb->fd, &state->termios) < 0)
107 return -1;
108
109 return 0;
110 #endif
111
112 #ifdef HAVE_TERMIO
113 if (ioctl (scb->fd, TCGETA, &state->termio) < 0)
114 return -1;
115 return 0;
116 #endif
117
118 #ifdef HAVE_SGTTY
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
128 return 0;
129 #endif
130 }
131
132 static int
133 set_tty_state(scb, state)
134 serial_t scb;
135 struct hardwire_ttystate *state;
136 {
137 #ifdef HAVE_TERMIOS
138 if (tcsetattr(scb->fd, TCSANOW, &state->termios) < 0)
139 return -1;
140
141 return 0;
142 #endif
143
144 #ifdef HAVE_TERMIO
145 if (ioctl (scb->fd, TCSETA, &state->termio) < 0)
146 return -1;
147 return 0;
148 #endif
149
150 #ifdef HAVE_SGTTY
151 if (ioctl (scb->fd, TIOCSETN, &state->sgttyb) < 0)
152 return -1;
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;
159
160 return 0;
161 #endif
162 }
163
164 static serial_ttystate
165 hardwire_get_tty_state(scb)
166 serial_t scb;
167 {
168 struct hardwire_ttystate *state;
169
170 state = (struct hardwire_ttystate *)xmalloc(sizeof *state);
171
172 if (get_tty_state(scb, state))
173 return NULL;
174
175 return (serial_ttystate)state;
176 }
177
178 static int
179 hardwire_set_tty_state(scb, ttystate)
180 serial_t scb;
181 serial_ttystate ttystate;
182 {
183 struct hardwire_ttystate *state;
184
185 state = (struct hardwire_ttystate *)ttystate;
186
187 return set_tty_state(scb, state);
188 }
189
190 static int
191 hardwire_noflush_set_tty_state (scb, new_ttystate, old_ttystate)
192 serial_t scb;
193 serial_ttystate new_ttystate;
194 serial_ttystate old_ttystate;
195 {
196 struct hardwire_ttystate new_state;
197 struct hardwire_ttystate *state = (struct hardwire_ttystate *) old_ttystate;
198
199 new_state = *(struct hardwire_ttystate *)new_ttystate;
200
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
236 static void
237 hardwire_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
244 #ifdef HAVE_TERMIOS
245 printf_filtered ("c_iflag = 0x%x, c_oflag = 0x%x,\n",
246 state->termios.c_iflag, state->termios.c_oflag);
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
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
289 static int
290 hardwire_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
307 static int
308 hardwire_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
325 static int
326 hardwire_send_break (scb)
327 serial_t scb;
328 {
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
338 {
339 int status;
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 }
353 #endif
354 }
355
356 static void
357 hardwire_raw(scb)
358 serial_t scb;
359 {
360 struct hardwire_ttystate state;
361
362 if (get_tty_state(scb, &state))
363 fprintf_unfiltered(gdb_stderr, "get_tty_state failed: %s\n", safe_strerror(errno));
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);
388 #endif
389
390 scb->current_timeout = 0;
391
392 if (set_tty_state (scb, &state))
393 fprintf_unfiltered(gdb_stderr, "set_tty_state failed: %s\n", safe_strerror(errno));
394 }
395
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 */
402
403 static int
404 wait_for(scb, timeout)
405 serial_t scb;
406 int timeout;
407 {
408 #ifdef HAVE_SGTTY
409 struct timeval tv;
410 fd_set readfds;
411
412 FD_ZERO (&readfds);
413
414 tv.tv_sec = timeout;
415 tv.tv_usec = 0;
416
417 FD_SET(scb->fd, &readfds);
418
419 while (1)
420 {
421 int numfds;
422
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 }
438
439 #endif /* HAVE_SGTTY */
440
441 #if defined HAVE_TERMIO || defined HAVE_TERMIOS
442 if (timeout == scb->current_timeout)
443 return 0;
444
445 {
446 struct hardwire_ttystate state;
447
448 if (get_tty_state(scb, &state))
449 fprintf_unfiltered(gdb_stderr, "get_tty_state failed: %s\n", safe_strerror(errno));
450
451 #ifdef HAVE_TERMIOS
452 state.termios.c_cc[VTIME] = timeout * 10;
453 #endif
454
455 #ifdef HAVE_TERMIO
456 state.termio.c_cc[VTIME] = timeout * 10;
457 #endif
458
459 scb->current_timeout = timeout;
460
461 if (set_tty_state (scb, &state))
462 fprintf_unfiltered(gdb_stderr, "set_tty_state failed: %s\n", safe_strerror(errno));
463
464 return 0;
465 }
466 #endif /* HAVE_TERMIO || HAVE_TERMIOS */
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
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). */
473
474 static int
475 hardwire_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;
488
489 scb->bufcnt = read(scb->fd, scb->buf, BUFSIZ);
490
491 if (scb->bufcnt <= 0)
492 if (scb->bufcnt == 0)
493 return SERIAL_TIMEOUT; /* 0 chars means timeout [may need to
494 distinguish between EOF & timeouts
495 someday] */
496 else
497 return SERIAL_ERROR; /* Got an error from read */
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
515 static struct
516 {
517 int rate;
518 int code;
519 }
520 baudtab[] =
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
540 static int
541 rate_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
553 static int
554 hardwire_setbaudrate(scb, rate)
555 serial_t scb;
556 int rate;
557 {
558 struct hardwire_ttystate state;
559
560 if (get_tty_state(scb, &state))
561 return -1;
562
563 #ifdef HAVE_TERMIOS
564 cfsetospeed (&state.termios, rate_to_code (rate));
565 cfsetispeed (&state.termios, rate_to_code (rate));
566 #endif
567
568 #ifdef HAVE_TERMIO
569 #ifndef CIBAUD
570 #define CIBAUD CBAUD
571 #endif
572
573 state.termio.c_cflag &= ~(CBAUD | CIBAUD);
574 state.termio.c_cflag |= rate_to_code (rate);
575 #endif
576
577 #ifdef HAVE_SGTTY
578 state.sgttyb.sg_ispeed = rate_to_code (rate);
579 state.sgttyb.sg_ospeed = rate_to_code (rate);
580 #endif
581
582 return set_tty_state (scb, &state);
583 }
584
585 static int
586 hardwire_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
605 static void
606 hardwire_close(scb)
607 serial_t scb;
608 {
609 if (scb->fd < 0)
610 return;
611
612 close(scb->fd);
613 scb->fd = -1;
614 }
615
616 static struct serial_ops hardwire_ops =
617 {
618 "hardwire",
619 0,
620 hardwire_open,
621 hardwire_close,
622 hardwire_readchar,
623 hardwire_write,
624 hardwire_flush_output,
625 hardwire_flush_input,
626 hardwire_send_break,
627 hardwire_raw,
628 hardwire_get_tty_state,
629 hardwire_set_tty_state,
630 hardwire_print_tty_state,
631 hardwire_noflush_set_tty_state,
632 hardwire_setbaudrate,
633 };
634
635 void
636 _initialize_ser_hardwire ()
637 {
638 serial_add_interface (&hardwire_ops);
639 }
This page took 0.078034 seconds and 5 git commands to generate.