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