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