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