Update FSF address.
[platform/upstream/binutils.git] / gdb / ser-unix.c
1 /* Serial interface for local (hardwired) serial ports on Un*x like systems
2    Copyright 1992, 1993, 1994 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., 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
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 #ifdef HAVE_SGTTY
198   struct hardwire_ttystate *state = (struct hardwire_ttystate *) old_ttystate;
199 #endif
200
201   new_state = *(struct hardwire_ttystate *)new_ttystate;
202
203   /* Don't change in or out of raw mode; we don't want to flush input.
204      termio and termios have no such restriction; for them flushing input
205      is separate from setting the attributes.  */
206
207 #ifdef HAVE_SGTTY
208   if (state->sgttyb.sg_flags & RAW)
209     new_state.sgttyb.sg_flags |= RAW;
210   else
211     new_state.sgttyb.sg_flags &= ~RAW;
212
213   /* I'm not sure whether this is necessary; the manpage just mentions
214      RAW not CBREAK.  */
215   if (state->sgttyb.sg_flags & CBREAK)
216     new_state.sgttyb.sg_flags |= CBREAK;
217   else
218     new_state.sgttyb.sg_flags &= ~CBREAK;
219 #endif
220
221   return set_tty_state (scb, &new_state);
222 }
223
224 static void
225 hardwire_print_tty_state (scb, ttystate)
226      serial_t scb;
227      serial_ttystate ttystate;
228 {
229   struct hardwire_ttystate *state = (struct hardwire_ttystate *) ttystate;
230   int i;
231
232 #ifdef HAVE_TERMIOS
233   printf_filtered ("c_iflag = 0x%x, c_oflag = 0x%x,\n",
234                    state->termios.c_iflag, state->termios.c_oflag);
235   printf_filtered ("c_cflag = 0x%x, c_lflag = 0x%x\n",
236                    state->termios.c_cflag, state->termios.c_lflag);
237 #if 0
238   /* This not in POSIX, and is not really documented by those systems
239      which have it (at least not Sun).  */
240   printf_filtered ("c_line = 0x%x.\n", state->termios.c_line);
241 #endif
242   printf_filtered ("c_cc: ");
243   for (i = 0; i < NCCS; i += 1)
244     printf_filtered ("0x%x ", state->termios.c_cc[i]);
245   printf_filtered ("\n");
246 #endif
247
248 #ifdef HAVE_TERMIO
249   printf_filtered ("c_iflag = 0x%x, c_oflag = 0x%x,\n",
250                    state->termio.c_iflag, state->termio.c_oflag);
251   printf_filtered ("c_cflag = 0x%x, c_lflag = 0x%x, c_line = 0x%x.\n",
252                    state->termio.c_cflag, state->termio.c_lflag,
253                    state->termio.c_line);
254   printf_filtered ("c_cc: ");
255   for (i = 0; i < NCC; i += 1)
256     printf_filtered ("0x%x ", state->termio.c_cc[i]);
257   printf_filtered ("\n");
258 #endif
259
260 #ifdef HAVE_SGTTY
261   printf_filtered ("sgttyb.sg_flags = 0x%x.\n", state->sgttyb.sg_flags);
262
263   printf_filtered ("tchars: ");
264   for (i = 0; i < (int)sizeof (struct tchars); i++)
265     printf_filtered ("0x%x ", ((unsigned char *)&state->tc)[i]);
266   printf_filtered ("\n");
267
268   printf_filtered ("ltchars: ");
269   for (i = 0; i < (int)sizeof (struct ltchars); i++)
270     printf_filtered ("0x%x ", ((unsigned char *)&state->ltc)[i]);
271   printf_filtered ("\n");
272
273   printf_filtered ("lmode:  0x%x\n", state->lmode);
274 #endif
275 }
276
277 static int
278 hardwire_flush_output (scb)
279      serial_t scb;
280 {
281 #ifdef HAVE_TERMIOS
282   return tcflush (scb->fd, TCOFLUSH);
283 #endif
284
285 #ifdef HAVE_TERMIO
286   return ioctl (scb->fd, TCFLSH, 1);
287 #endif
288
289 #ifdef HAVE_SGTTY
290   /* This flushes both input and output, but we can't do better.  */
291   return ioctl (scb->fd, TIOCFLUSH, 0);
292 #endif  
293 }
294
295 static int
296 hardwire_flush_input (scb)
297      serial_t scb;
298 {
299 #ifdef HAVE_TERMIOS
300   return tcflush (scb->fd, TCIFLUSH);
301 #endif
302
303 #ifdef HAVE_TERMIO
304   return ioctl (scb->fd, TCFLSH, 0);
305 #endif
306
307 #ifdef HAVE_SGTTY
308   /* This flushes both input and output, but we can't do better.  */
309   return ioctl (scb->fd, TIOCFLUSH, 0);
310 #endif  
311 }
312
313 static int
314 hardwire_send_break (scb)
315      serial_t scb;
316 {
317 #ifdef HAVE_TERMIOS
318   return tcsendbreak (scb->fd, 0);
319 #endif
320
321 #ifdef HAVE_TERMIO
322   return ioctl (scb->fd, TCSBRK, 0);
323 #endif
324
325 #ifdef HAVE_SGTTY
326   {
327     int status;
328     struct timeval timeout;
329
330     status = ioctl (scb->fd, TIOCSBRK, 0);
331
332     /* Can't use usleep; it doesn't exist in BSD 4.2.  */
333     /* Note that if this select() is interrupted by a signal it will not wait
334        the full length of time.  I think that is OK.  */
335     timeout.tv_sec = 0;
336     timeout.tv_usec = 250000;
337     select (0, 0, 0, 0, &timeout);
338     status = ioctl (scb->fd, TIOCCBRK, 0);
339     return status;
340   }
341 #endif  
342 }
343
344 static void
345 hardwire_raw(scb)
346      serial_t scb;
347 {
348   struct hardwire_ttystate state;
349
350   if (get_tty_state(scb, &state))
351     fprintf_unfiltered(gdb_stderr, "get_tty_state failed: %s\n", safe_strerror(errno));
352
353 #ifdef HAVE_TERMIOS
354   state.termios.c_iflag = 0;
355   state.termios.c_oflag = 0;
356   state.termios.c_lflag = 0;
357   state.termios.c_cflag &= ~(CSIZE|PARENB);
358   state.termios.c_cflag |= CLOCAL | CS8;
359   state.termios.c_cc[VMIN] = 0;
360   state.termios.c_cc[VTIME] = 0;
361 #endif
362
363 #ifdef HAVE_TERMIO
364   state.termio.c_iflag = 0;
365   state.termio.c_oflag = 0;
366   state.termio.c_lflag = 0;
367   state.termio.c_cflag &= ~(CSIZE|PARENB);
368   state.termio.c_cflag |= CLOCAL | CS8;
369   state.termio.c_cc[VMIN] = 0;
370   state.termio.c_cc[VTIME] = 0;
371 #endif
372
373 #ifdef HAVE_SGTTY
374   state.sgttyb.sg_flags |= RAW | ANYP;
375   state.sgttyb.sg_flags &= ~(CBREAK | ECHO);
376 #endif
377
378   scb->current_timeout = 0;
379
380   if (set_tty_state (scb, &state))
381     fprintf_unfiltered(gdb_stderr, "set_tty_state failed: %s\n", safe_strerror(errno));
382 }
383
384 /* Wait for input on scb, with timeout seconds.  Returns 0 on success,
385    otherwise SERIAL_TIMEOUT or SERIAL_ERROR.
386
387    For termio{s}, we actually just setup VTIME if necessary, and let the
388    timeout occur in the read() in hardwire_read().
389  */
390
391 static int
392 wait_for(scb, timeout)
393      serial_t scb;
394      int timeout;
395 {
396   scb->timeout_remaining = 0;
397
398 #ifdef HAVE_SGTTY
399   {
400     struct timeval tv;
401     fd_set readfds;
402
403     FD_ZERO (&readfds);
404
405     tv.tv_sec = timeout;
406     tv.tv_usec = 0;
407
408     FD_SET(scb->fd, &readfds);
409
410     while (1)
411       {
412         int numfds;
413
414         if (timeout >= 0)
415           numfds = select(scb->fd+1, &readfds, 0, 0, &tv);
416         else
417           numfds = select(scb->fd+1, &readfds, 0, 0, 0);
418
419         if (numfds <= 0)
420           if (numfds == 0)
421             return SERIAL_TIMEOUT;
422           else if (errno == EINTR)
423             continue;
424           else
425             return SERIAL_ERROR;        /* Got an error from select or poll */
426
427         return 0;
428       }
429   }
430 #endif  /* HAVE_SGTTY */
431
432 #if defined HAVE_TERMIO || defined HAVE_TERMIOS
433   if (timeout == scb->current_timeout)
434     return 0;
435
436   scb->current_timeout = timeout;
437
438   {
439     struct hardwire_ttystate state;
440
441     if (get_tty_state(scb, &state))
442       fprintf_unfiltered(gdb_stderr, "get_tty_state failed: %s\n", safe_strerror(errno));
443
444 #ifdef HAVE_TERMIOS
445     if (timeout < 0)
446       {
447         /* No timeout.  */
448         state.termios.c_cc[VTIME] = 0;
449         state.termios.c_cc[VMIN] = 1;
450       }
451     else
452       {
453         state.termios.c_cc[VMIN] = 0;
454         state.termios.c_cc[VTIME] = timeout * 10;
455         if (state.termios.c_cc[VTIME] != timeout * 10)
456           {
457
458             /* If c_cc is an 8-bit signed character, we can't go 
459                bigger than this.  If it is always unsigned, we could use
460                25.  */
461
462             scb->current_timeout = 12;
463             state.termios.c_cc[VTIME] = scb->current_timeout * 10;
464             scb->timeout_remaining = timeout - scb->current_timeout;
465           }
466       }
467 #endif
468
469 #ifdef HAVE_TERMIO
470     if (timeout < 0)
471       {
472         /* No timeout.  */
473         state.termio.c_cc[VTIME] = 0;
474         state.termio.c_cc[VMIN] = 1;
475       }
476     else
477       {
478         state.termio.c_cc[VMIN] = 0;
479         state.termio.c_cc[VTIME] = timeout * 10;
480         if (state.termio.c_cc[VTIME] != timeout * 10)
481           {
482             /* If c_cc is an 8-bit signed character, we can't go 
483                bigger than this.  If it is always unsigned, we could use
484                25.  */
485
486             scb->current_timeout = 12;
487             state.termio.c_cc[VTIME] = scb->current_timeout * 10;
488             scb->timeout_remaining = timeout - scb->current_timeout;
489           }
490       }
491 #endif
492
493     if (set_tty_state (scb, &state))
494       fprintf_unfiltered(gdb_stderr, "set_tty_state failed: %s\n", safe_strerror(errno));
495
496     return 0;
497   }
498 #endif  /* HAVE_TERMIO || HAVE_TERMIOS */
499 }
500
501 /* Read a character with user-specified timeout.  TIMEOUT is number of seconds
502    to wait, or -1 to wait forever.  Use timeout of 0 to effect a poll.  Returns
503    char if successful.  Returns SERIAL_TIMEOUT if timeout expired, EOF if line
504    dropped dead, or SERIAL_ERROR for any other error (see errno in that case).  */
505
506 static int
507 hardwire_readchar(scb, timeout)
508      serial_t scb;
509      int timeout;
510 {
511   int status;
512
513   if (scb->bufcnt-- > 0)
514     return *scb->bufp++;
515
516   while (1)
517     {
518       status = wait_for (scb, timeout);
519
520       if (status < 0)
521         return status;
522
523       scb->bufcnt = read (scb->fd, scb->buf, BUFSIZ);
524
525       if (scb->bufcnt <= 0)
526         {
527           if (scb->bufcnt == 0)
528             {
529               /* Zero characters means timeout (it could also be EOF, but
530                  we don't (yet at least) distinguish).  */
531               if (scb->timeout_remaining > 0)
532                 {
533                   timeout = scb->timeout_remaining;
534                   continue;
535                 }
536               else
537                 return SERIAL_TIMEOUT;
538             }
539           else if (errno == EINTR)
540             continue;
541           else
542             return SERIAL_ERROR;        /* Got an error from read */
543         }
544
545       scb->bufcnt--;
546       scb->bufp = scb->buf;
547       return *scb->bufp++;
548     }
549 }
550
551 #ifndef B19200
552 #define B19200 EXTA
553 #endif
554
555 #ifndef B38400
556 #define B38400 EXTB
557 #endif
558
559 /* Translate baud rates from integers to damn B_codes.  Unix should
560    have outgrown this crap years ago, but even POSIX wouldn't buck it.  */
561
562 static struct
563 {
564   int rate;
565   int code;
566 }
567 baudtab[] =
568 {
569   {50, B50},
570   {75, B75},
571   {110, B110},
572   {134, B134},
573   {150, B150},
574   {200, B200},
575   {300, B300},
576   {600, B600},
577   {1200, B1200},
578   {1800, B1800},
579   {2400, B2400},
580   {4800, B4800},
581   {9600, B9600},
582   {19200, B19200},
583   {38400, B38400},
584   {-1, -1},
585 };
586
587 static int 
588 rate_to_code(rate)
589      int rate;
590 {
591   int i;
592
593   for (i = 0; baudtab[i].rate != -1; i++)
594     if (rate == baudtab[i].rate)  
595       return baudtab[i].code;
596
597   return -1;
598 }
599
600 static int
601 hardwire_setbaudrate(scb, rate)
602      serial_t scb;
603      int rate;
604 {
605   struct hardwire_ttystate state;
606
607   if (get_tty_state(scb, &state))
608     return -1;
609
610 #ifdef HAVE_TERMIOS
611   cfsetospeed (&state.termios, rate_to_code (rate));
612   cfsetispeed (&state.termios, rate_to_code (rate));
613 #endif
614
615 #ifdef HAVE_TERMIO
616 #ifndef CIBAUD
617 #define CIBAUD CBAUD
618 #endif
619
620   state.termio.c_cflag &= ~(CBAUD | CIBAUD);
621   state.termio.c_cflag |= rate_to_code (rate);
622 #endif
623
624 #ifdef HAVE_SGTTY
625   state.sgttyb.sg_ispeed = rate_to_code (rate);
626   state.sgttyb.sg_ospeed = rate_to_code (rate);
627 #endif
628
629   return set_tty_state (scb, &state);
630 }
631
632 static int
633 hardwire_setstopbits(scb, num)
634      serial_t scb;
635      int num;
636 {
637   struct hardwire_ttystate state;
638   int newbit;
639
640   if (get_tty_state(scb, &state))
641     return -1;
642
643   switch (num)
644     {
645     case SERIAL_1_STOPBITS:
646       newbit = 0;
647       break;
648     case SERIAL_1_AND_A_HALF_STOPBITS:
649     case SERIAL_2_STOPBITS:
650       newbit = 1;
651       break;
652     default:
653       return 1;
654     }
655
656 #ifdef HAVE_TERMIOS
657   if (!newbit)
658     state.termios.c_cflag &= ~CSTOPB;
659   else
660     state.termios.c_cflag |= CSTOPB; /* two bits */
661 #endif
662
663 #ifdef HAVE_TERMIO
664   if (!newbit)
665     state.termio.c_cflag &= ~CSTOPB;
666   else
667     state.termio.c_cflag |= CSTOPB; /* two bits */
668 #endif
669
670 #ifdef HAVE_SGTTY
671   return 0;                     /* sgtty doesn't support this */
672 #endif
673
674   return set_tty_state (scb, &state);
675 }
676
677 static int
678 hardwire_write(scb, str, len)
679      serial_t scb;
680      const char *str;
681      int len;
682 {
683   int cc;
684
685   while (len > 0)
686     {
687       cc = write(scb->fd, str, len);
688
689       if (cc < 0)
690         return 1;
691       len -= cc;
692       str += cc;
693     }
694   return 0;
695 }
696
697 static void
698 hardwire_close(scb)
699      serial_t scb;
700 {
701   if (scb->fd < 0)
702     return;
703
704   close(scb->fd);
705   scb->fd = -1;
706 }
707
708 static struct serial_ops hardwire_ops =
709 {
710   "hardwire",
711   0,
712   hardwire_open,
713   hardwire_close,
714   hardwire_readchar,
715   hardwire_write,
716   hardwire_flush_output,
717   hardwire_flush_input,
718   hardwire_send_break,
719   hardwire_raw,
720   hardwire_get_tty_state,
721   hardwire_set_tty_state,
722   hardwire_print_tty_state,
723   hardwire_noflush_set_tty_state,
724   hardwire_setbaudrate,
725   hardwire_setstopbits,
726 };
727
728 void
729 _initialize_ser_hardwire ()
730 {
731   serial_add_interface (&hardwire_ops);
732 }