119370Spst/* Serial interface for local (hardwired) serial ports on Un*x like systems
219370Spst
3130809Smarcel   Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
4130809Smarcel   2003, 2004 Free Software Foundation, Inc.
5130809Smarcel
698948Sobrien   This file is part of GDB.
719370Spst
898948Sobrien   This program is free software; you can redistribute it and/or modify
998948Sobrien   it under the terms of the GNU General Public License as published by
1098948Sobrien   the Free Software Foundation; either version 2 of the License, or
1198948Sobrien   (at your option) any later version.
1219370Spst
1398948Sobrien   This program is distributed in the hope that it will be useful,
1498948Sobrien   but WITHOUT ANY WARRANTY; without even the implied warranty of
1598948Sobrien   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1698948Sobrien   GNU General Public License for more details.
1719370Spst
1898948Sobrien   You should have received a copy of the GNU General Public License
1998948Sobrien   along with this program; if not, write to the Free Software
2098948Sobrien   Foundation, Inc., 59 Temple Place - Suite 330,
2198948Sobrien   Boston, MA 02111-1307, USA.  */
2219370Spst
2319370Spst#include "defs.h"
2419370Spst#include "serial.h"
2598948Sobrien#include "ser-unix.h"
2698948Sobrien
2719370Spst#include <fcntl.h>
2819370Spst#include <sys/types.h>
2919370Spst#include "terminal.h"
3098948Sobrien#include <sys/socket.h>
3198948Sobrien#include <sys/time.h>
3219370Spst
3398948Sobrien#include "gdb_string.h"
3498948Sobrien#include "event-loop.h"
3598948Sobrien
3619370Spst#ifdef HAVE_TERMIOS
3719370Spst
3819370Spststruct hardwire_ttystate
3998948Sobrien  {
4098948Sobrien    struct termios termios;
4198948Sobrien  };
4219370Spst#endif /* termios */
4319370Spst
4419370Spst#ifdef HAVE_TERMIO
4519370Spst
4619370Spst/* It is believed that all systems which have added job control to SVR3
4719370Spst   (e.g. sco) have also added termios.  Even if not, trying to figure out
4819370Spst   all the variations (TIOCGPGRP vs. TCGETPGRP, etc.) would be pretty
4919370Spst   bewildering.  So we don't attempt it.  */
5019370Spst
5119370Spststruct hardwire_ttystate
5298948Sobrien  {
5398948Sobrien    struct termio termio;
5498948Sobrien  };
5519370Spst#endif /* termio */
5619370Spst
5719370Spst#ifdef HAVE_SGTTY
5819370Spststruct hardwire_ttystate
5998948Sobrien  {
6098948Sobrien    struct sgttyb sgttyb;
6198948Sobrien    struct tchars tc;
6298948Sobrien    struct ltchars ltc;
6398948Sobrien    /* Line discipline flags.  */
6498948Sobrien    int lmode;
6598948Sobrien  };
6619370Spst#endif /* sgtty */
6719370Spst
6898948Sobrienstatic int hardwire_open (struct serial *scb, const char *name);
6998948Sobrienstatic void hardwire_raw (struct serial *scb);
7098948Sobrienstatic int wait_for (struct serial *scb, int timeout);
7198948Sobrienstatic int hardwire_readchar (struct serial *scb, int timeout);
7298948Sobrienstatic int do_hardwire_readchar (struct serial *scb, int timeout);
7398948Sobrienstatic int generic_readchar (struct serial *scb, int timeout,
7498948Sobrien			     int (*do_readchar) (struct serial *scb,
7598948Sobrien						 int timeout));
7698948Sobrienstatic int rate_to_code (int rate);
7798948Sobrienstatic int hardwire_setbaudrate (struct serial *scb, int rate);
7898948Sobrienstatic void hardwire_close (struct serial *scb);
7998948Sobrienstatic int get_tty_state (struct serial *scb,
8098948Sobrien			  struct hardwire_ttystate * state);
8198948Sobrienstatic int set_tty_state (struct serial *scb,
8298948Sobrien			  struct hardwire_ttystate * state);
8398948Sobrienstatic serial_ttystate hardwire_get_tty_state (struct serial *scb);
8498948Sobrienstatic int hardwire_set_tty_state (struct serial *scb, serial_ttystate state);
8598948Sobrienstatic int hardwire_noflush_set_tty_state (struct serial *, serial_ttystate,
8698948Sobrien					   serial_ttystate);
8798948Sobrienstatic void hardwire_print_tty_state (struct serial *, serial_ttystate,
8898948Sobrien				      struct ui_file *);
8998948Sobrienstatic int hardwire_drain_output (struct serial *);
9098948Sobrienstatic int hardwire_flush_output (struct serial *);
9198948Sobrienstatic int hardwire_flush_input (struct serial *);
9298948Sobrienstatic int hardwire_send_break (struct serial *);
9398948Sobrienstatic int hardwire_setstopbits (struct serial *, int);
9419370Spst
9598948Sobrienstatic int do_unix_readchar (struct serial *scb, int timeout);
9698948Sobrienstatic timer_handler_func push_event;
9798948Sobrienstatic handler_func fd_event;
9898948Sobrienstatic void reschedule (struct serial *scb);
9946289Sdfr
10098948Sobrienvoid _initialize_ser_hardwire (void);
10146289Sdfr
10298948Sobrienextern int (*ui_loop_hook) (int);
10398948Sobrien
10419370Spst/* Open up a real live device for serial I/O */
10519370Spst
10619370Spststatic int
10798948Sobrienhardwire_open (struct serial *scb, const char *name)
10819370Spst{
10919370Spst  scb->fd = open (name, O_RDWR);
11019370Spst  if (scb->fd < 0)
11119370Spst    return -1;
11219370Spst
11319370Spst  return 0;
11419370Spst}
11519370Spst
11619370Spststatic int
11798948Sobrienget_tty_state (struct serial *scb, struct hardwire_ttystate *state)
11819370Spst{
11919370Spst#ifdef HAVE_TERMIOS
12098948Sobrien  if (tcgetattr (scb->fd, &state->termios) < 0)
12119370Spst    return -1;
12219370Spst
12319370Spst  return 0;
12419370Spst#endif
12519370Spst
12619370Spst#ifdef HAVE_TERMIO
12719370Spst  if (ioctl (scb->fd, TCGETA, &state->termio) < 0)
12819370Spst    return -1;
12919370Spst  return 0;
13019370Spst#endif
13119370Spst
13219370Spst#ifdef HAVE_SGTTY
13319370Spst  if (ioctl (scb->fd, TIOCGETP, &state->sgttyb) < 0)
13419370Spst    return -1;
13519370Spst  if (ioctl (scb->fd, TIOCGETC, &state->tc) < 0)
13619370Spst    return -1;
13719370Spst  if (ioctl (scb->fd, TIOCGLTC, &state->ltc) < 0)
13819370Spst    return -1;
13919370Spst  if (ioctl (scb->fd, TIOCLGET, &state->lmode) < 0)
14019370Spst    return -1;
14119370Spst
14219370Spst  return 0;
14319370Spst#endif
14419370Spst}
14519370Spst
14619370Spststatic int
14798948Sobrienset_tty_state (struct serial *scb, struct hardwire_ttystate *state)
14819370Spst{
14919370Spst#ifdef HAVE_TERMIOS
15098948Sobrien  if (tcsetattr (scb->fd, TCSANOW, &state->termios) < 0)
15119370Spst    return -1;
15219370Spst
15319370Spst  return 0;
15419370Spst#endif
15519370Spst
15619370Spst#ifdef HAVE_TERMIO
15719370Spst  if (ioctl (scb->fd, TCSETA, &state->termio) < 0)
15819370Spst    return -1;
15919370Spst  return 0;
16019370Spst#endif
16119370Spst
16219370Spst#ifdef HAVE_SGTTY
16319370Spst  if (ioctl (scb->fd, TIOCSETN, &state->sgttyb) < 0)
16419370Spst    return -1;
16519370Spst  if (ioctl (scb->fd, TIOCSETC, &state->tc) < 0)
16619370Spst    return -1;
16719370Spst  if (ioctl (scb->fd, TIOCSLTC, &state->ltc) < 0)
16819370Spst    return -1;
16919370Spst  if (ioctl (scb->fd, TIOCLSET, &state->lmode) < 0)
17019370Spst    return -1;
17119370Spst
17219370Spst  return 0;
17319370Spst#endif
17419370Spst}
17519370Spst
17619370Spststatic serial_ttystate
17798948Sobrienhardwire_get_tty_state (struct serial *scb)
17819370Spst{
17919370Spst  struct hardwire_ttystate *state;
18019370Spst
18198948Sobrien  state = (struct hardwire_ttystate *) xmalloc (sizeof *state);
18219370Spst
18398948Sobrien  if (get_tty_state (scb, state))
18419370Spst    return NULL;
18519370Spst
18698948Sobrien  return (serial_ttystate) state;
18719370Spst}
18819370Spst
18919370Spststatic int
19098948Sobrienhardwire_set_tty_state (struct serial *scb, serial_ttystate ttystate)
19119370Spst{
19219370Spst  struct hardwire_ttystate *state;
19319370Spst
19498948Sobrien  state = (struct hardwire_ttystate *) ttystate;
19519370Spst
19698948Sobrien  return set_tty_state (scb, state);
19719370Spst}
19819370Spst
19919370Spststatic int
20098948Sobrienhardwire_noflush_set_tty_state (struct serial *scb,
20198948Sobrien				serial_ttystate new_ttystate,
20298948Sobrien				serial_ttystate old_ttystate)
20319370Spst{
20419370Spst  struct hardwire_ttystate new_state;
20519370Spst#ifdef HAVE_SGTTY
20619370Spst  struct hardwire_ttystate *state = (struct hardwire_ttystate *) old_ttystate;
20719370Spst#endif
20819370Spst
20998948Sobrien  new_state = *(struct hardwire_ttystate *) new_ttystate;
21019370Spst
21119370Spst  /* Don't change in or out of raw mode; we don't want to flush input.
21219370Spst     termio and termios have no such restriction; for them flushing input
21319370Spst     is separate from setting the attributes.  */
21419370Spst
21519370Spst#ifdef HAVE_SGTTY
21619370Spst  if (state->sgttyb.sg_flags & RAW)
21719370Spst    new_state.sgttyb.sg_flags |= RAW;
21819370Spst  else
21919370Spst    new_state.sgttyb.sg_flags &= ~RAW;
22019370Spst
22119370Spst  /* I'm not sure whether this is necessary; the manpage just mentions
22219370Spst     RAW not CBREAK.  */
22319370Spst  if (state->sgttyb.sg_flags & CBREAK)
22419370Spst    new_state.sgttyb.sg_flags |= CBREAK;
22519370Spst  else
22619370Spst    new_state.sgttyb.sg_flags &= ~CBREAK;
22719370Spst#endif
22819370Spst
22919370Spst  return set_tty_state (scb, &new_state);
23019370Spst}
23119370Spst
23219370Spststatic void
23398948Sobrienhardwire_print_tty_state (struct serial *scb,
23498948Sobrien			  serial_ttystate ttystate,
23598948Sobrien			  struct ui_file *stream)
23619370Spst{
23719370Spst  struct hardwire_ttystate *state = (struct hardwire_ttystate *) ttystate;
23819370Spst  int i;
23919370Spst
24019370Spst#ifdef HAVE_TERMIOS
24198948Sobrien  fprintf_filtered (stream, "c_iflag = 0x%x, c_oflag = 0x%x,\n",
24298948Sobrien		    (int) state->termios.c_iflag,
24398948Sobrien		    (int) state->termios.c_oflag);
24498948Sobrien  fprintf_filtered (stream, "c_cflag = 0x%x, c_lflag = 0x%x\n",
24598948Sobrien		    (int) state->termios.c_cflag,
24698948Sobrien		    (int) state->termios.c_lflag);
24719370Spst#if 0
24819370Spst  /* This not in POSIX, and is not really documented by those systems
24919370Spst     which have it (at least not Sun).  */
25098948Sobrien  fprintf_filtered (stream, "c_line = 0x%x.\n", state->termios.c_line);
25119370Spst#endif
25298948Sobrien  fprintf_filtered (stream, "c_cc: ");
25319370Spst  for (i = 0; i < NCCS; i += 1)
25498948Sobrien    fprintf_filtered (stream, "0x%x ", state->termios.c_cc[i]);
25598948Sobrien  fprintf_filtered (stream, "\n");
25619370Spst#endif
25719370Spst
25819370Spst#ifdef HAVE_TERMIO
25998948Sobrien  fprintf_filtered (stream, "c_iflag = 0x%x, c_oflag = 0x%x,\n",
26098948Sobrien		    state->termio.c_iflag, state->termio.c_oflag);
26198948Sobrien  fprintf_filtered (stream, "c_cflag = 0x%x, c_lflag = 0x%x, c_line = 0x%x.\n",
26298948Sobrien		    state->termio.c_cflag, state->termio.c_lflag,
26398948Sobrien		    state->termio.c_line);
26498948Sobrien  fprintf_filtered (stream, "c_cc: ");
26519370Spst  for (i = 0; i < NCC; i += 1)
26698948Sobrien    fprintf_filtered (stream, "0x%x ", state->termio.c_cc[i]);
26798948Sobrien  fprintf_filtered (stream, "\n");
26819370Spst#endif
26919370Spst
27019370Spst#ifdef HAVE_SGTTY
27198948Sobrien  fprintf_filtered (stream, "sgttyb.sg_flags = 0x%x.\n",
27298948Sobrien		    state->sgttyb.sg_flags);
27319370Spst
27498948Sobrien  fprintf_filtered (stream, "tchars: ");
27598948Sobrien  for (i = 0; i < (int) sizeof (struct tchars); i++)
27698948Sobrien    fprintf_filtered (stream, "0x%x ", ((unsigned char *) &state->tc)[i]);
27798948Sobrien  fprintf_filtered (stream, "\n");
27819370Spst
27998948Sobrien  fprintf_filtered (stream, "ltchars: ");
28098948Sobrien  for (i = 0; i < (int) sizeof (struct ltchars); i++)
28198948Sobrien    fprintf_filtered (stream, "0x%x ", ((unsigned char *) &state->ltc)[i]);
28298948Sobrien  fprintf_filtered (stream, "\n");
28319370Spst
28498948Sobrien  fprintf_filtered (stream, "lmode:  0x%x\n", state->lmode);
28519370Spst#endif
28619370Spst}
28719370Spst
28846289Sdfr/* Wait for the output to drain away, as opposed to flushing (discarding) it */
28946289Sdfr
29019370Spststatic int
29198948Sobrienhardwire_drain_output (struct serial *scb)
29246289Sdfr{
29346289Sdfr#ifdef HAVE_TERMIOS
29446289Sdfr  return tcdrain (scb->fd);
29546289Sdfr#endif
29646289Sdfr
29746289Sdfr#ifdef HAVE_TERMIO
29846289Sdfr  return ioctl (scb->fd, TCSBRK, 1);
29946289Sdfr#endif
30046289Sdfr
30146289Sdfr#ifdef HAVE_SGTTY
30246289Sdfr  /* Get the current state and then restore it using TIOCSETP,
30346289Sdfr     which should cause the output to drain and pending input
30446289Sdfr     to be discarded. */
30546289Sdfr  {
30646289Sdfr    struct hardwire_ttystate state;
30746289Sdfr    if (get_tty_state (scb, &state))
30846289Sdfr      {
30946289Sdfr	return (-1);
31046289Sdfr      }
31146289Sdfr    else
31246289Sdfr      {
31346289Sdfr	return (ioctl (scb->fd, TIOCSETP, &state.sgttyb));
31446289Sdfr      }
31546289Sdfr  }
31698948Sobrien#endif
31746289Sdfr}
31846289Sdfr
31946289Sdfrstatic int
32098948Sobrienhardwire_flush_output (struct serial *scb)
32119370Spst{
32219370Spst#ifdef HAVE_TERMIOS
32319370Spst  return tcflush (scb->fd, TCOFLUSH);
32419370Spst#endif
32519370Spst
32619370Spst#ifdef HAVE_TERMIO
32719370Spst  return ioctl (scb->fd, TCFLSH, 1);
32819370Spst#endif
32919370Spst
33019370Spst#ifdef HAVE_SGTTY
33119370Spst  /* This flushes both input and output, but we can't do better.  */
33219370Spst  return ioctl (scb->fd, TIOCFLUSH, 0);
33398948Sobrien#endif
33419370Spst}
33519370Spst
33619370Spststatic int
33798948Sobrienhardwire_flush_input (struct serial *scb)
33819370Spst{
33998948Sobrien  ser_unix_flush_input (scb);
34019370Spst
34119370Spst#ifdef HAVE_TERMIOS
34219370Spst  return tcflush (scb->fd, TCIFLUSH);
34319370Spst#endif
34419370Spst
34519370Spst#ifdef HAVE_TERMIO
34619370Spst  return ioctl (scb->fd, TCFLSH, 0);
34719370Spst#endif
34819370Spst
34919370Spst#ifdef HAVE_SGTTY
35019370Spst  /* This flushes both input and output, but we can't do better.  */
35119370Spst  return ioctl (scb->fd, TIOCFLUSH, 0);
35298948Sobrien#endif
35319370Spst}
35419370Spst
35519370Spststatic int
35698948Sobrienhardwire_send_break (struct serial *scb)
35719370Spst{
35819370Spst#ifdef HAVE_TERMIOS
35919370Spst  return tcsendbreak (scb->fd, 0);
36019370Spst#endif
36119370Spst
36219370Spst#ifdef HAVE_TERMIO
36319370Spst  return ioctl (scb->fd, TCSBRK, 0);
36419370Spst#endif
36519370Spst
36619370Spst#ifdef HAVE_SGTTY
36719370Spst  {
36819370Spst    int status;
36919370Spst    struct timeval timeout;
37019370Spst
37119370Spst    status = ioctl (scb->fd, TIOCSBRK, 0);
37219370Spst
37319370Spst    /* Can't use usleep; it doesn't exist in BSD 4.2.  */
37419370Spst    /* Note that if this select() is interrupted by a signal it will not wait
37519370Spst       the full length of time.  I think that is OK.  */
37619370Spst    timeout.tv_sec = 0;
37719370Spst    timeout.tv_usec = 250000;
37819370Spst    select (0, 0, 0, 0, &timeout);
37919370Spst    status = ioctl (scb->fd, TIOCCBRK, 0);
38019370Spst    return status;
38119370Spst  }
38298948Sobrien#endif
38319370Spst}
38419370Spst
38519370Spststatic void
38698948Sobrienhardwire_raw (struct serial *scb)
38719370Spst{
38819370Spst  struct hardwire_ttystate state;
38919370Spst
39098948Sobrien  if (get_tty_state (scb, &state))
39198948Sobrien    fprintf_unfiltered (gdb_stderr, "get_tty_state failed: %s\n", safe_strerror (errno));
39219370Spst
39319370Spst#ifdef HAVE_TERMIOS
39419370Spst  state.termios.c_iflag = 0;
39519370Spst  state.termios.c_oflag = 0;
39619370Spst  state.termios.c_lflag = 0;
39798948Sobrien  state.termios.c_cflag &= ~(CSIZE | PARENB);
39819370Spst  state.termios.c_cflag |= CLOCAL | CS8;
39919370Spst  state.termios.c_cc[VMIN] = 0;
40019370Spst  state.termios.c_cc[VTIME] = 0;
40119370Spst#endif
40219370Spst
40319370Spst#ifdef HAVE_TERMIO
40419370Spst  state.termio.c_iflag = 0;
40519370Spst  state.termio.c_oflag = 0;
40619370Spst  state.termio.c_lflag = 0;
40798948Sobrien  state.termio.c_cflag &= ~(CSIZE | PARENB);
40819370Spst  state.termio.c_cflag |= CLOCAL | CS8;
40919370Spst  state.termio.c_cc[VMIN] = 0;
41019370Spst  state.termio.c_cc[VTIME] = 0;
41119370Spst#endif
41219370Spst
41319370Spst#ifdef HAVE_SGTTY
41419370Spst  state.sgttyb.sg_flags |= RAW | ANYP;
41519370Spst  state.sgttyb.sg_flags &= ~(CBREAK | ECHO);
41619370Spst#endif
41719370Spst
41819370Spst  scb->current_timeout = 0;
41919370Spst
42019370Spst  if (set_tty_state (scb, &state))
42198948Sobrien    fprintf_unfiltered (gdb_stderr, "set_tty_state failed: %s\n", safe_strerror (errno));
42219370Spst}
42319370Spst
42419370Spst/* Wait for input on scb, with timeout seconds.  Returns 0 on success,
42519370Spst   otherwise SERIAL_TIMEOUT or SERIAL_ERROR.
42619370Spst
42719370Spst   For termio{s}, we actually just setup VTIME if necessary, and let the
42819370Spst   timeout occur in the read() in hardwire_read().
42919370Spst */
43019370Spst
43198948Sobrien/* FIXME: cagney/1999-09-16: Don't replace this with the equivalent
43298948Sobrien   ser_unix*() until the old TERMIOS/SGTTY/... timer code has been
43398948Sobrien   flushed. . */
43498948Sobrien
43598948Sobrien/* NOTE: cagney/1999-09-30: Much of the code below is dead.  The only
43698948Sobrien   possible values of the TIMEOUT parameter are ONE and ZERO.
43798948Sobrien   Consequently all the code that tries to handle the possability of
43898948Sobrien   an overflowed timer is unnecessary. */
43998948Sobrien
44019370Spststatic int
44198948Sobrienwait_for (struct serial *scb, int timeout)
44219370Spst{
44319370Spst#ifdef HAVE_SGTTY
44498948Sobrien  while (1)
44598948Sobrien    {
44698948Sobrien      struct timeval tv;
44798948Sobrien      fd_set readfds;
44898948Sobrien      int numfds;
44919370Spst
45098948Sobrien      /* NOTE: Some OS's can scramble the READFDS when the select()
45198948Sobrien         call fails (ex the kernel with Red Hat 5.2).  Initialize all
45298948Sobrien         arguments before each call. */
45319370Spst
45498948Sobrien      tv.tv_sec = timeout;
45598948Sobrien      tv.tv_usec = 0;
45619370Spst
45798948Sobrien      FD_ZERO (&readfds);
45898948Sobrien      FD_SET (scb->fd, &readfds);
45919370Spst
46098948Sobrien      if (timeout >= 0)
46198948Sobrien	numfds = select (scb->fd + 1, &readfds, 0, 0, &tv);
46298948Sobrien      else
46398948Sobrien	numfds = select (scb->fd + 1, &readfds, 0, 0, 0);
46419370Spst
46598948Sobrien      if (numfds <= 0)
46698948Sobrien	if (numfds == 0)
46798948Sobrien	  return SERIAL_TIMEOUT;
46898948Sobrien	else if (errno == EINTR)
46998948Sobrien	  continue;
47019370Spst	else
47198948Sobrien	  return SERIAL_ERROR;	/* Got an error from select or poll */
47219370Spst
47398948Sobrien      return 0;
47498948Sobrien    }
47598948Sobrien#endif /* HAVE_SGTTY */
47619370Spst
47719370Spst#if defined HAVE_TERMIO || defined HAVE_TERMIOS
47819370Spst  if (timeout == scb->current_timeout)
47919370Spst    return 0;
48019370Spst
48119370Spst  scb->current_timeout = timeout;
48219370Spst
48319370Spst  {
48419370Spst    struct hardwire_ttystate state;
48519370Spst
48698948Sobrien    if (get_tty_state (scb, &state))
48798948Sobrien      fprintf_unfiltered (gdb_stderr, "get_tty_state failed: %s\n", safe_strerror (errno));
48819370Spst
48919370Spst#ifdef HAVE_TERMIOS
49019370Spst    if (timeout < 0)
49119370Spst      {
49219370Spst	/* No timeout.  */
49319370Spst	state.termios.c_cc[VTIME] = 0;
49419370Spst	state.termios.c_cc[VMIN] = 1;
49519370Spst      }
49619370Spst    else
49719370Spst      {
49819370Spst	state.termios.c_cc[VMIN] = 0;
49919370Spst	state.termios.c_cc[VTIME] = timeout * 10;
50019370Spst	if (state.termios.c_cc[VTIME] != timeout * 10)
50119370Spst	  {
50219370Spst
50319370Spst	    /* If c_cc is an 8-bit signed character, we can't go
50419370Spst	       bigger than this.  If it is always unsigned, we could use
50519370Spst	       25.  */
50619370Spst
50719370Spst	    scb->current_timeout = 12;
50819370Spst	    state.termios.c_cc[VTIME] = scb->current_timeout * 10;
50919370Spst	    scb->timeout_remaining = timeout - scb->current_timeout;
51019370Spst	  }
51119370Spst      }
51219370Spst#endif
51319370Spst
51419370Spst#ifdef HAVE_TERMIO
51519370Spst    if (timeout < 0)
51619370Spst      {
51719370Spst	/* No timeout.  */
51819370Spst	state.termio.c_cc[VTIME] = 0;
51919370Spst	state.termio.c_cc[VMIN] = 1;
52019370Spst      }
52119370Spst    else
52219370Spst      {
52319370Spst	state.termio.c_cc[VMIN] = 0;
52419370Spst	state.termio.c_cc[VTIME] = timeout * 10;
52519370Spst	if (state.termio.c_cc[VTIME] != timeout * 10)
52619370Spst	  {
52719370Spst	    /* If c_cc is an 8-bit signed character, we can't go
52819370Spst	       bigger than this.  If it is always unsigned, we could use
52919370Spst	       25.  */
53019370Spst
53119370Spst	    scb->current_timeout = 12;
53219370Spst	    state.termio.c_cc[VTIME] = scb->current_timeout * 10;
53319370Spst	    scb->timeout_remaining = timeout - scb->current_timeout;
53419370Spst	  }
53519370Spst      }
53619370Spst#endif
53719370Spst
53819370Spst    if (set_tty_state (scb, &state))
53998948Sobrien      fprintf_unfiltered (gdb_stderr, "set_tty_state failed: %s\n", safe_strerror (errno));
54019370Spst
54119370Spst    return 0;
54219370Spst  }
54398948Sobrien#endif /* HAVE_TERMIO || HAVE_TERMIOS */
54419370Spst}
54519370Spst
54619370Spst/* Read a character with user-specified timeout.  TIMEOUT is number of seconds
54719370Spst   to wait, or -1 to wait forever.  Use timeout of 0 to effect a poll.  Returns
54819370Spst   char if successful.  Returns SERIAL_TIMEOUT if timeout expired, EOF if line
54919370Spst   dropped dead, or SERIAL_ERROR for any other error (see errno in that case).  */
55098948Sobrien
55198948Sobrien/* FIXME: cagney/1999-09-16: Don't replace this with the equivalent
55298948Sobrien   ser_unix*() until the old TERMIOS/SGTTY/... timer code has been
55398948Sobrien   flushed. */
55498948Sobrien
55598948Sobrien/* NOTE: cagney/1999-09-16: This function is not identical to
55698948Sobrien   ser_unix_readchar() as part of replacing it with ser_unix*()
55798948Sobrien   merging will be required - this code handles the case where read()
55898948Sobrien   times out due to no data while ser_unix_readchar() doesn't expect
55998948Sobrien   that. */
56098948Sobrien
56119370Spststatic int
56298948Sobriendo_hardwire_readchar (struct serial *scb, int timeout)
56319370Spst{
56498948Sobrien  int status, delta;
56598948Sobrien  int detach = 0;
56619370Spst
56746289Sdfr  if (timeout > 0)
56846289Sdfr    timeout++;
56946289Sdfr
57098948Sobrien  /* We have to be able to keep the GUI alive here, so we break the original
57198948Sobrien     timeout into steps of 1 second, running the "keep the GUI alive" hook
57298948Sobrien     each time through the loop.
57398948Sobrien     Also, timeout = 0 means to poll, so we just set the delta to 0, so we
57498948Sobrien     will only go through the loop once. */
57598948Sobrien
57698948Sobrien  delta = (timeout == 0 ? 0 : 1);
57719370Spst  while (1)
57819370Spst    {
57946289Sdfr
58098948Sobrien      /* N.B. The UI may destroy our world (for instance by calling
58198948Sobrien         remote_stop,) in which case we want to get out of here as
58298948Sobrien         quickly as possible.  It is not safe to touch scb, since
58398948Sobrien         someone else might have freed it.  The ui_loop_hook signals that
58498948Sobrien         we should exit by returning 1. */
58598948Sobrien
58646289Sdfr      if (ui_loop_hook)
58798948Sobrien	detach = ui_loop_hook (0);
58898948Sobrien
58998948Sobrien      if (detach)
59098948Sobrien	return SERIAL_TIMEOUT;
59198948Sobrien
59298948Sobrien      scb->timeout_remaining = (timeout < 0 ? timeout : timeout - delta);
59398948Sobrien      status = wait_for (scb, delta);
59498948Sobrien
59519370Spst      if (status < 0)
59619370Spst	return status;
59719370Spst
59898948Sobrien      status = read (scb->fd, scb->buf, BUFSIZ);
59919370Spst
60098948Sobrien      if (status <= 0)
60119370Spst	{
60298948Sobrien	  if (status == 0)
60319370Spst	    {
60419370Spst	      /* Zero characters means timeout (it could also be EOF, but
60598948Sobrien	         we don't (yet at least) distinguish).  */
60619370Spst	      if (scb->timeout_remaining > 0)
60719370Spst		{
60819370Spst		  timeout = scb->timeout_remaining;
60919370Spst		  continue;
61019370Spst		}
61198948Sobrien	      else if (scb->timeout_remaining < 0)
61298948Sobrien		continue;
61319370Spst	      else
61419370Spst		return SERIAL_TIMEOUT;
61519370Spst	    }
61619370Spst	  else if (errno == EINTR)
61719370Spst	    continue;
61819370Spst	  else
61919370Spst	    return SERIAL_ERROR;	/* Got an error from read */
62019370Spst	}
62119370Spst
62298948Sobrien      scb->bufcnt = status;
62319370Spst      scb->bufcnt--;
62419370Spst      scb->bufp = scb->buf;
62519370Spst      return *scb->bufp++;
62619370Spst    }
62719370Spst}
62819370Spst
62998948Sobrienstatic int
63098948Sobrienhardwire_readchar (struct serial *scb, int timeout)
63198948Sobrien{
63298948Sobrien  return generic_readchar (scb, timeout, do_hardwire_readchar);
63398948Sobrien}
63498948Sobrien
63598948Sobrien
63619370Spst#ifndef B19200
63719370Spst#define B19200 EXTA
63819370Spst#endif
63919370Spst
64019370Spst#ifndef B38400
64119370Spst#define B38400 EXTB
64219370Spst#endif
64319370Spst
64419370Spst/* Translate baud rates from integers to damn B_codes.  Unix should
64519370Spst   have outgrown this crap years ago, but even POSIX wouldn't buck it.  */
64619370Spst
64719370Spststatic struct
64819370Spst{
64919370Spst  int rate;
65019370Spst  int code;
65119370Spst}
65219370Spstbaudtab[] =
65319370Spst{
65498948Sobrien  {
65598948Sobrien    50, B50
65698948Sobrien  }
65798948Sobrien  ,
65898948Sobrien  {
65998948Sobrien    75, B75
66098948Sobrien  }
66198948Sobrien  ,
66298948Sobrien  {
66398948Sobrien    110, B110
66498948Sobrien  }
66598948Sobrien  ,
66698948Sobrien  {
66798948Sobrien    134, B134
66898948Sobrien  }
66998948Sobrien  ,
67098948Sobrien  {
67198948Sobrien    150, B150
67298948Sobrien  }
67398948Sobrien  ,
67498948Sobrien  {
67598948Sobrien    200, B200
67698948Sobrien  }
67798948Sobrien  ,
67898948Sobrien  {
67998948Sobrien    300, B300
68098948Sobrien  }
68198948Sobrien  ,
68298948Sobrien  {
68398948Sobrien    600, B600
68498948Sobrien  }
68598948Sobrien  ,
68698948Sobrien  {
68798948Sobrien    1200, B1200
68898948Sobrien  }
68998948Sobrien  ,
69098948Sobrien  {
69198948Sobrien    1800, B1800
69298948Sobrien  }
69398948Sobrien  ,
69498948Sobrien  {
69598948Sobrien    2400, B2400
69698948Sobrien  }
69798948Sobrien  ,
69898948Sobrien  {
69998948Sobrien    4800, B4800
70098948Sobrien  }
70198948Sobrien  ,
70298948Sobrien  {
70398948Sobrien    9600, B9600
70498948Sobrien  }
70598948Sobrien  ,
70698948Sobrien  {
70798948Sobrien    19200, B19200
70898948Sobrien  }
70998948Sobrien  ,
71098948Sobrien  {
71198948Sobrien    38400, B38400
71298948Sobrien  }
71398948Sobrien  ,
71436629Sdfr#ifdef B57600
71598948Sobrien  {
71698948Sobrien    57600, B57600
71798948Sobrien  }
71898948Sobrien  ,
71936629Sdfr#endif
72036629Sdfr#ifdef B115200
72198948Sobrien  {
72298948Sobrien    115200, B115200
72398948Sobrien  }
72498948Sobrien  ,
72536629Sdfr#endif
72636629Sdfr#ifdef B230400
72798948Sobrien  {
72898948Sobrien    230400, B230400
72998948Sobrien  }
73098948Sobrien  ,
73136629Sdfr#endif
73246289Sdfr#ifdef B460800
73398948Sobrien  {
73498948Sobrien    460800, B460800
73598948Sobrien  }
73698948Sobrien  ,
73746289Sdfr#endif
73898948Sobrien  {
73998948Sobrien    -1, -1
74098948Sobrien  }
74198948Sobrien  ,
74219370Spst};
74319370Spst
74498948Sobrienstatic int
74598948Sobrienrate_to_code (int rate)
74619370Spst{
74719370Spst  int i;
74819370Spst
74919370Spst  for (i = 0; baudtab[i].rate != -1; i++)
75098948Sobrien    {
75198948Sobrien      /* test for perfect macth. */
75298948Sobrien      if (rate == baudtab[i].rate)
75398948Sobrien        return baudtab[i].code;
75498948Sobrien      else
75598948Sobrien        {
75698948Sobrien	  /* check if it is in between valid values. */
75798948Sobrien          if (rate < baudtab[i].rate)
75898948Sobrien	    {
75998948Sobrien	      if (i)
76098948Sobrien	        {
76198948Sobrien	          warning ("Invalid baud rate %d.  Closest values are %d and %d.",
76298948Sobrien	                    rate, baudtab[i - 1].rate, baudtab[i].rate);
76398948Sobrien		}
76498948Sobrien	      else
76598948Sobrien	        {
76698948Sobrien	          warning ("Invalid baud rate %d.  Minimum value is %d.",
76798948Sobrien	                    rate, baudtab[0].rate);
76898948Sobrien		}
76998948Sobrien	      return -1;
77098948Sobrien	    }
77198948Sobrien        }
77298948Sobrien    }
77398948Sobrien
77498948Sobrien  /* The requested speed was too large. */
77598948Sobrien  warning ("Invalid baud rate %d.  Maximum value is %d.",
77698948Sobrien            rate, baudtab[i - 1].rate);
77719370Spst  return -1;
77819370Spst}
77919370Spst
78019370Spststatic int
78198948Sobrienhardwire_setbaudrate (struct serial *scb, int rate)
78219370Spst{
78319370Spst  struct hardwire_ttystate state;
78498948Sobrien  int baud_code = rate_to_code (rate);
78598948Sobrien
78698948Sobrien  if (baud_code < 0)
78798948Sobrien    {
78898948Sobrien      /* The baud rate was not valid.
78998948Sobrien         A warning has already been issued. */
79098948Sobrien      errno = EINVAL;
79198948Sobrien      return -1;
79298948Sobrien    }
79319370Spst
79498948Sobrien  if (get_tty_state (scb, &state))
79519370Spst    return -1;
79619370Spst
79719370Spst#ifdef HAVE_TERMIOS
79898948Sobrien  cfsetospeed (&state.termios, baud_code);
79998948Sobrien  cfsetispeed (&state.termios, baud_code);
80019370Spst#endif
80119370Spst
80219370Spst#ifdef HAVE_TERMIO
80319370Spst#ifndef CIBAUD
80419370Spst#define CIBAUD CBAUD
80519370Spst#endif
80619370Spst
80719370Spst  state.termio.c_cflag &= ~(CBAUD | CIBAUD);
80898948Sobrien  state.termio.c_cflag |= baud_code;
80919370Spst#endif
81019370Spst
81119370Spst#ifdef HAVE_SGTTY
81298948Sobrien  state.sgttyb.sg_ispeed = baud_code;
81398948Sobrien  state.sgttyb.sg_ospeed = baud_code;
81419370Spst#endif
81519370Spst
81619370Spst  return set_tty_state (scb, &state);
81719370Spst}
81819370Spst
81919370Spststatic int
82098948Sobrienhardwire_setstopbits (struct serial *scb, int num)
82119370Spst{
82219370Spst  struct hardwire_ttystate state;
82319370Spst  int newbit;
82419370Spst
82598948Sobrien  if (get_tty_state (scb, &state))
82619370Spst    return -1;
82719370Spst
82819370Spst  switch (num)
82919370Spst    {
83019370Spst    case SERIAL_1_STOPBITS:
83119370Spst      newbit = 0;
83219370Spst      break;
83319370Spst    case SERIAL_1_AND_A_HALF_STOPBITS:
83419370Spst    case SERIAL_2_STOPBITS:
83519370Spst      newbit = 1;
83619370Spst      break;
83719370Spst    default:
83819370Spst      return 1;
83919370Spst    }
84019370Spst
84119370Spst#ifdef HAVE_TERMIOS
84219370Spst  if (!newbit)
84319370Spst    state.termios.c_cflag &= ~CSTOPB;
84419370Spst  else
84598948Sobrien    state.termios.c_cflag |= CSTOPB;	/* two bits */
84619370Spst#endif
84719370Spst
84819370Spst#ifdef HAVE_TERMIO
84919370Spst  if (!newbit)
85019370Spst    state.termio.c_cflag &= ~CSTOPB;
85119370Spst  else
85298948Sobrien    state.termio.c_cflag |= CSTOPB;	/* two bits */
85319370Spst#endif
85419370Spst
85519370Spst#ifdef HAVE_SGTTY
85619370Spst  return 0;			/* sgtty doesn't support this */
85719370Spst#endif
85819370Spst
85919370Spst  return set_tty_state (scb, &state);
86019370Spst}
86119370Spst
86298948Sobrienstatic void
86398948Sobrienhardwire_close (struct serial *scb)
86498948Sobrien{
86598948Sobrien  if (scb->fd < 0)
86698948Sobrien    return;
86798948Sobrien
86898948Sobrien  close (scb->fd);
86998948Sobrien  scb->fd = -1;
87098948Sobrien}
87198948Sobrien
87298948Sobrien
87398948Sobrien/* Generic operations used by all UNIX/FD based serial interfaces. */
87498948Sobrien
87598948Sobrienserial_ttystate
87698948Sobrienser_unix_nop_get_tty_state (struct serial *scb)
87798948Sobrien{
87898948Sobrien  /* allocate a dummy */
87998948Sobrien  return (serial_ttystate) XMALLOC (int);
88098948Sobrien}
88198948Sobrien
88298948Sobrienint
88398948Sobrienser_unix_nop_set_tty_state (struct serial *scb, serial_ttystate ttystate)
88498948Sobrien{
88598948Sobrien  return 0;
88698948Sobrien}
88798948Sobrien
88898948Sobrienvoid
88998948Sobrienser_unix_nop_raw (struct serial *scb)
89098948Sobrien{
89198948Sobrien  return;			/* Always in raw mode */
89298948Sobrien}
89398948Sobrien
89498948Sobrien/* Wait for input on scb, with timeout seconds.  Returns 0 on success,
89598948Sobrien   otherwise SERIAL_TIMEOUT or SERIAL_ERROR. */
89698948Sobrien
89798948Sobrienint
89898948Sobrienser_unix_wait_for (struct serial *scb, int timeout)
89998948Sobrien{
90098948Sobrien  while (1)
90198948Sobrien    {
90298948Sobrien      int numfds;
90398948Sobrien      struct timeval tv;
90498948Sobrien      fd_set readfds, exceptfds;
90598948Sobrien
90698948Sobrien      /* NOTE: Some OS's can scramble the READFDS when the select()
90798948Sobrien         call fails (ex the kernel with Red Hat 5.2).  Initialize all
90898948Sobrien         arguments before each call. */
90998948Sobrien
91098948Sobrien      tv.tv_sec = timeout;
91198948Sobrien      tv.tv_usec = 0;
91298948Sobrien
91398948Sobrien      FD_ZERO (&readfds);
91498948Sobrien      FD_ZERO (&exceptfds);
91598948Sobrien      FD_SET (scb->fd, &readfds);
91698948Sobrien      FD_SET (scb->fd, &exceptfds);
91798948Sobrien
91898948Sobrien      if (timeout >= 0)
91998948Sobrien	numfds = select (scb->fd + 1, &readfds, 0, &exceptfds, &tv);
92098948Sobrien      else
92198948Sobrien	numfds = select (scb->fd + 1, &readfds, 0, &exceptfds, 0);
92298948Sobrien
92398948Sobrien      if (numfds <= 0)
92498948Sobrien	{
92598948Sobrien	  if (numfds == 0)
92698948Sobrien	    return SERIAL_TIMEOUT;
92798948Sobrien	  else if (errno == EINTR)
92898948Sobrien	    continue;
92998948Sobrien	  else
93098948Sobrien	    return SERIAL_ERROR;	/* Got an error from select or poll */
93198948Sobrien	}
93298948Sobrien
93398948Sobrien      return 0;
93498948Sobrien    }
93598948Sobrien}
93698948Sobrien
93798948Sobrien/* Read a character with user-specified timeout.  TIMEOUT is number of seconds
93898948Sobrien   to wait, or -1 to wait forever.  Use timeout of 0 to effect a poll.  Returns
93998948Sobrien   char if successful.  Returns -2 if timeout expired, EOF if line dropped
94098948Sobrien   dead, or -3 for any other error (see errno in that case). */
94198948Sobrien
94219370Spststatic int
94398948Sobriendo_unix_readchar (struct serial *scb, int timeout)
94419370Spst{
94598948Sobrien  int status;
94698948Sobrien  int delta;
94798948Sobrien
94898948Sobrien  /* We have to be able to keep the GUI alive here, so we break the original
94998948Sobrien     timeout into steps of 1 second, running the "keep the GUI alive" hook
95098948Sobrien     each time through the loop.
95198948Sobrien
95298948Sobrien     Also, timeout = 0 means to poll, so we just set the delta to 0, so we
95398948Sobrien     will only go through the loop once. */
95498948Sobrien
95598948Sobrien  delta = (timeout == 0 ? 0 : 1);
95698948Sobrien  while (1)
95798948Sobrien    {
95898948Sobrien
95998948Sobrien      /* N.B. The UI may destroy our world (for instance by calling
96098948Sobrien         remote_stop,) in which case we want to get out of here as
96198948Sobrien         quickly as possible.  It is not safe to touch scb, since
96298948Sobrien         someone else might have freed it.  The ui_loop_hook signals that
96398948Sobrien         we should exit by returning 1. */
96498948Sobrien
96598948Sobrien      if (ui_loop_hook)
96698948Sobrien	{
96798948Sobrien	  if (ui_loop_hook (0))
96898948Sobrien	    return SERIAL_TIMEOUT;
96998948Sobrien	}
97098948Sobrien
97198948Sobrien      status = ser_unix_wait_for (scb, delta);
97298948Sobrien      if (timeout > 0)
97398948Sobrien        timeout -= delta;
97498948Sobrien
97598948Sobrien      /* If we got a character or an error back from wait_for, then we can
97698948Sobrien         break from the loop before the timeout is completed. */
97798948Sobrien
97898948Sobrien      if (status != SERIAL_TIMEOUT)
97998948Sobrien	{
98098948Sobrien	  break;
98198948Sobrien	}
98298948Sobrien
98398948Sobrien      /* If we have exhausted the original timeout, then generate
98498948Sobrien         a SERIAL_TIMEOUT, and pass it out of the loop. */
98598948Sobrien
98698948Sobrien      else if (timeout == 0)
98798948Sobrien	{
98898948Sobrien	  status = SERIAL_TIMEOUT;
98998948Sobrien	  break;
99098948Sobrien	}
99198948Sobrien    }
99298948Sobrien
99398948Sobrien  if (status < 0)
99498948Sobrien    return status;
99598948Sobrien
99698948Sobrien  while (1)
99798948Sobrien    {
99898948Sobrien      status = read (scb->fd, scb->buf, BUFSIZ);
99998948Sobrien      if (status != -1 || errno != EINTR)
100098948Sobrien	break;
100198948Sobrien    }
100298948Sobrien
100398948Sobrien  if (status <= 0)
100498948Sobrien    {
100598948Sobrien      if (status == 0)
100698948Sobrien	return SERIAL_TIMEOUT;	/* 0 chars means timeout [may need to
100798948Sobrien				   distinguish between EOF & timeouts
100898948Sobrien				   someday] */
100998948Sobrien      else
101098948Sobrien	return SERIAL_ERROR;	/* Got an error from read */
101198948Sobrien    }
101298948Sobrien
101398948Sobrien  scb->bufcnt = status;
101498948Sobrien  scb->bufcnt--;
101598948Sobrien  scb->bufp = scb->buf;
101698948Sobrien  return *scb->bufp++;
101798948Sobrien}
101898948Sobrien
101998948Sobrien/* Perform operations common to both old and new readchar. */
102098948Sobrien
102198948Sobrien/* Return the next character from the input FIFO.  If the FIFO is
102298948Sobrien   empty, call the SERIAL specific routine to try and read in more
102398948Sobrien   characters.
102498948Sobrien
102598948Sobrien   Initially data from the input FIFO is returned (fd_event()
102698948Sobrien   pre-reads the input into that FIFO.  Once that has been emptied,
102798948Sobrien   further data is obtained by polling the input FD using the device
102898948Sobrien   specific readchar() function.  Note: reschedule() is called after
102998948Sobrien   every read.  This is because there is no guarentee that the lower
103098948Sobrien   level fd_event() poll_event() code (which also calls reschedule())
103198948Sobrien   will be called. */
103298948Sobrien
103398948Sobrienstatic int
103498948Sobriengeneric_readchar (struct serial *scb, int timeout,
103598948Sobrien		  int (do_readchar) (struct serial *scb, int timeout))
103698948Sobrien{
103798948Sobrien  int ch;
103898948Sobrien  if (scb->bufcnt > 0)
103998948Sobrien    {
104098948Sobrien      ch = *scb->bufp;
104198948Sobrien      scb->bufcnt--;
104298948Sobrien      scb->bufp++;
104398948Sobrien    }
104498948Sobrien  else if (scb->bufcnt < 0)
104598948Sobrien    {
104698948Sobrien      /* Some errors/eof are are sticky. */
104798948Sobrien      ch = scb->bufcnt;
104898948Sobrien    }
104998948Sobrien  else
105098948Sobrien    {
105198948Sobrien      ch = do_readchar (scb, timeout);
105298948Sobrien      if (ch < 0)
105398948Sobrien	{
105498948Sobrien	  switch ((enum serial_rc) ch)
105598948Sobrien	    {
105698948Sobrien	    case SERIAL_EOF:
105798948Sobrien	    case SERIAL_ERROR:
105898948Sobrien	      /* Make the error/eof stick. */
105998948Sobrien	      scb->bufcnt = ch;
106098948Sobrien	      break;
106198948Sobrien	    case SERIAL_TIMEOUT:
106298948Sobrien	      scb->bufcnt = 0;
106398948Sobrien	      break;
106498948Sobrien	    }
106598948Sobrien	}
106698948Sobrien    }
106798948Sobrien  reschedule (scb);
106898948Sobrien  return ch;
106998948Sobrien}
107098948Sobrien
107198948Sobrienint
107298948Sobrienser_unix_readchar (struct serial *scb, int timeout)
107398948Sobrien{
107498948Sobrien  return generic_readchar (scb, timeout, do_unix_readchar);
107598948Sobrien}
107698948Sobrien
107798948Sobrienint
107898948Sobrienser_unix_nop_noflush_set_tty_state (struct serial *scb,
107998948Sobrien				    serial_ttystate new_ttystate,
108098948Sobrien				    serial_ttystate old_ttystate)
108198948Sobrien{
108298948Sobrien  return 0;
108398948Sobrien}
108498948Sobrien
108598948Sobrienvoid
108698948Sobrienser_unix_nop_print_tty_state (struct serial *scb,
108798948Sobrien			      serial_ttystate ttystate,
108898948Sobrien			      struct ui_file *stream)
108998948Sobrien{
109098948Sobrien  /* Nothing to print.  */
109198948Sobrien  return;
109298948Sobrien}
109398948Sobrien
109498948Sobrienint
109598948Sobrienser_unix_nop_setbaudrate (struct serial *scb, int rate)
109698948Sobrien{
109798948Sobrien  return 0;			/* Never fails! */
109898948Sobrien}
109998948Sobrien
110098948Sobrienint
110198948Sobrienser_unix_nop_setstopbits (struct serial *scb, int num)
110298948Sobrien{
110398948Sobrien  return 0;			/* Never fails! */
110498948Sobrien}
110598948Sobrien
110698948Sobrienint
110798948Sobrienser_unix_write (struct serial *scb, const char *str, int len)
110898948Sobrien{
110919370Spst  int cc;
111019370Spst
111119370Spst  while (len > 0)
111219370Spst    {
111398948Sobrien      cc = write (scb->fd, str, len);
111419370Spst
111519370Spst      if (cc < 0)
111619370Spst	return 1;
111719370Spst      len -= cc;
111819370Spst      str += cc;
111919370Spst    }
112019370Spst  return 0;
112119370Spst}
112219370Spst
112398948Sobrienint
112498948Sobrienser_unix_nop_flush_output (struct serial *scb)
112519370Spst{
112698948Sobrien  return 0;
112798948Sobrien}
112819370Spst
112998948Sobrienint
113098948Sobrienser_unix_flush_input (struct serial *scb)
113198948Sobrien{
113298948Sobrien  if (scb->bufcnt >= 0)
113398948Sobrien    {
113498948Sobrien      scb->bufcnt = 0;
113598948Sobrien      scb->bufp = scb->buf;
113698948Sobrien      return 0;
113798948Sobrien    }
113898948Sobrien  else
113998948Sobrien    return SERIAL_ERROR;
114019370Spst}
114119370Spst
114298948Sobrienint
114398948Sobrienser_unix_nop_send_break (struct serial *scb)
114419370Spst{
114598948Sobrien  return 0;
114698948Sobrien}
114798948Sobrien
114898948Sobrienint
114998948Sobrienser_unix_nop_drain_output (struct serial *scb)
115098948Sobrien{
115198948Sobrien  return 0;
115298948Sobrien}
115398948Sobrien
115498948Sobrien
115598948Sobrien
115698948Sobrien/* Event handling for ASYNC serial code.
115798948Sobrien
115898948Sobrien   At any time the SERIAL device either: has an empty FIFO and is
115998948Sobrien   waiting on a FD event; or has a non-empty FIFO/error condition and
116098948Sobrien   is constantly scheduling timer events.
116198948Sobrien
116298948Sobrien   ASYNC only stops pestering its client when it is de-async'ed or it
116398948Sobrien   is told to go away. */
116498948Sobrien
116598948Sobrien/* Value of scb->async_state: */
116698948Sobrienenum {
116798948Sobrien  /* >= 0 (TIMER_SCHEDULED) */
116898948Sobrien  /* The ID of the currently scheduled timer event. This state is
116998948Sobrien     rarely encountered.  Timer events are one-off so as soon as the
117098948Sobrien     event is delivered the state is shanged to NOTHING_SCHEDULED. */
117198948Sobrien  FD_SCHEDULED = -1,
117298948Sobrien  /* The fd_event() handler is scheduled.  It is called when ever the
117398948Sobrien     file descriptor becomes ready. */
117498948Sobrien  NOTHING_SCHEDULED = -2
117598948Sobrien  /* Either no task is scheduled (just going into ASYNC mode) or a
117698948Sobrien     timer event has just gone off and the current state has been
117798948Sobrien     forced into nothing scheduled. */
117819370Spst};
117919370Spst
118098948Sobrien/* Identify and schedule the next ASYNC task based on scb->async_state
118198948Sobrien   and scb->buf* (the input FIFO).  A state machine is used to avoid
118298948Sobrien   the need to make redundant calls into the event-loop - the next
118398948Sobrien   scheduled task is only changed when needed. */
118498948Sobrien
118598948Sobrienstatic void
118698948Sobrienreschedule (struct serial *scb)
118798948Sobrien{
118898948Sobrien  if (serial_is_async_p (scb))
118998948Sobrien    {
119098948Sobrien      int next_state;
119198948Sobrien      switch (scb->async_state)
119298948Sobrien	{
119398948Sobrien	case FD_SCHEDULED:
119498948Sobrien	  if (scb->bufcnt == 0)
119598948Sobrien	    next_state = FD_SCHEDULED;
119698948Sobrien	  else
119798948Sobrien	    {
119898948Sobrien	      delete_file_handler (scb->fd);
119998948Sobrien	      next_state = create_timer (0, push_event, scb);
120098948Sobrien	    }
120198948Sobrien	  break;
120298948Sobrien	case NOTHING_SCHEDULED:
120398948Sobrien	  if (scb->bufcnt == 0)
120498948Sobrien	    {
120598948Sobrien	      add_file_handler (scb->fd, fd_event, scb);
120698948Sobrien	      next_state = FD_SCHEDULED;
120798948Sobrien	    }
120898948Sobrien	  else
120998948Sobrien	    {
121098948Sobrien	      next_state = create_timer (0, push_event, scb);
121198948Sobrien	    }
121298948Sobrien	  break;
121398948Sobrien	default: /* TIMER SCHEDULED */
121498948Sobrien	  if (scb->bufcnt == 0)
121598948Sobrien	    {
121698948Sobrien	      delete_timer (scb->async_state);
121798948Sobrien	      add_file_handler (scb->fd, fd_event, scb);
121898948Sobrien	      next_state = FD_SCHEDULED;
121998948Sobrien	    }
122098948Sobrien	  else
122198948Sobrien	    next_state = scb->async_state;
122298948Sobrien	  break;
122398948Sobrien	}
122498948Sobrien      if (serial_debug_p (scb))
122598948Sobrien	{
122698948Sobrien	  switch (next_state)
122798948Sobrien	    {
122898948Sobrien	    case FD_SCHEDULED:
122998948Sobrien	      if (scb->async_state != FD_SCHEDULED)
123098948Sobrien		fprintf_unfiltered (gdb_stdlog, "[fd%d->fd-scheduled]\n",
123198948Sobrien				    scb->fd);
123298948Sobrien	      break;
123398948Sobrien	    default: /* TIMER SCHEDULED */
123498948Sobrien	      if (scb->async_state == FD_SCHEDULED)
123598948Sobrien		fprintf_unfiltered (gdb_stdlog, "[fd%d->timer-scheduled]\n",
123698948Sobrien				    scb->fd);
123798948Sobrien	      break;
123898948Sobrien	    }
123998948Sobrien	}
124098948Sobrien      scb->async_state = next_state;
124198948Sobrien    }
124298948Sobrien}
124398948Sobrien
124498948Sobrien/* FD_EVENT: This is scheduled when the input FIFO is empty (and there
124598948Sobrien   is no pending error).  As soon as data arrives, it is read into the
124698948Sobrien   input FIFO and the client notified.  The client should then drain
124798948Sobrien   the FIFO using readchar().  If the FIFO isn't immediatly emptied,
124898948Sobrien   push_event() is used to nag the client until it is. */
124998948Sobrien
125098948Sobrienstatic void
125198948Sobrienfd_event (int error, void *context)
125298948Sobrien{
125398948Sobrien  struct serial *scb = context;
125498948Sobrien  if (error != 0)
125598948Sobrien    {
125698948Sobrien      scb->bufcnt = SERIAL_ERROR;
125798948Sobrien    }
125898948Sobrien  else if (scb->bufcnt == 0)
125998948Sobrien    {
126098948Sobrien      /* Prime the input FIFO.  The readchar() function is used to
126198948Sobrien         pull characters out of the buffer.  See also
126298948Sobrien         generic_readchar(). */
126398948Sobrien      int nr;
126498948Sobrien      do
126598948Sobrien	{
126698948Sobrien	  nr = read (scb->fd, scb->buf, BUFSIZ);
126798948Sobrien	}
126898948Sobrien      while (nr == -1 && errno == EINTR);
126998948Sobrien      if (nr == 0)
127098948Sobrien	{
127198948Sobrien	  scb->bufcnt = SERIAL_EOF;
127298948Sobrien	}
127398948Sobrien      else if (nr > 0)
127498948Sobrien	{
127598948Sobrien	  scb->bufcnt = nr;
127698948Sobrien	  scb->bufp = scb->buf;
127798948Sobrien	}
127898948Sobrien      else
127998948Sobrien	{
128098948Sobrien	  scb->bufcnt = SERIAL_ERROR;
128198948Sobrien	}
128298948Sobrien    }
128398948Sobrien  scb->async_handler (scb, scb->async_context);
128498948Sobrien  reschedule (scb);
128598948Sobrien}
128698948Sobrien
128798948Sobrien/* PUSH_EVENT: The input FIFO is non-empty (or there is a pending
128898948Sobrien   error).  Nag the client until all the data has been read.  In the
128998948Sobrien   case of errors, the client will need to close or de-async the
129098948Sobrien   device before naging stops. */
129198948Sobrien
129298948Sobrienstatic void
129398948Sobrienpush_event (void *context)
129498948Sobrien{
129598948Sobrien  struct serial *scb = context;
129698948Sobrien  scb->async_state = NOTHING_SCHEDULED; /* Timers are one-off */
129798948Sobrien  scb->async_handler (scb, scb->async_context);
129898948Sobrien  /* re-schedule */
129998948Sobrien  reschedule (scb);
130098948Sobrien}
130198948Sobrien
130298948Sobrien/* Put the SERIAL device into/out-of ASYNC mode.  */
130398948Sobrien
130419370Spstvoid
130598948Sobrienser_unix_async (struct serial *scb,
130698948Sobrien		int async_p)
130719370Spst{
130898948Sobrien  if (async_p)
130998948Sobrien    {
131098948Sobrien      /* Force a re-schedule. */
131198948Sobrien      scb->async_state = NOTHING_SCHEDULED;
131298948Sobrien      if (serial_debug_p (scb))
131398948Sobrien	fprintf_unfiltered (gdb_stdlog, "[fd%d->asynchronous]\n",
131498948Sobrien			    scb->fd);
131598948Sobrien      reschedule (scb);
131698948Sobrien    }
131798948Sobrien  else
131898948Sobrien    {
131998948Sobrien      if (serial_debug_p (scb))
132098948Sobrien	fprintf_unfiltered (gdb_stdlog, "[fd%d->synchronous]\n",
132198948Sobrien			    scb->fd);
132298948Sobrien      /* De-schedule whatever tasks are currently scheduled. */
132398948Sobrien      switch (scb->async_state)
132498948Sobrien	{
132598948Sobrien	case FD_SCHEDULED:
132698948Sobrien	  delete_file_handler (scb->fd);
132798948Sobrien	  break;
1328130809Smarcel	case NOTHING_SCHEDULED:
132998948Sobrien	  break;
133098948Sobrien	default: /* TIMER SCHEDULED */
133198948Sobrien	  delete_timer (scb->async_state);
133298948Sobrien	  break;
133398948Sobrien	}
133498948Sobrien    }
133519370Spst}
133698948Sobrien
133798948Sobrienvoid
133898948Sobrien_initialize_ser_hardwire (void)
133998948Sobrien{
134098948Sobrien  struct serial_ops *ops = XMALLOC (struct serial_ops);
1341130809Smarcel  memset (ops, 0, sizeof (struct serial_ops));
134298948Sobrien  ops->name = "hardwire";
134398948Sobrien  ops->next = 0;
134498948Sobrien  ops->open = hardwire_open;
134598948Sobrien  ops->close = hardwire_close;
134698948Sobrien  /* FIXME: Don't replace this with the equivalent ser_unix*() until
134798948Sobrien     the old TERMIOS/SGTTY/... timer code has been flushed. cagney
134898948Sobrien     1999-09-16. */
134998948Sobrien  ops->readchar = hardwire_readchar;
135098948Sobrien  ops->write = ser_unix_write;
135198948Sobrien  ops->flush_output = hardwire_flush_output;
135298948Sobrien  ops->flush_input = hardwire_flush_input;
135398948Sobrien  ops->send_break = hardwire_send_break;
135498948Sobrien  ops->go_raw = hardwire_raw;
135598948Sobrien  ops->get_tty_state = hardwire_get_tty_state;
135698948Sobrien  ops->set_tty_state = hardwire_set_tty_state;
135798948Sobrien  ops->print_tty_state = hardwire_print_tty_state;
135898948Sobrien  ops->noflush_set_tty_state = hardwire_noflush_set_tty_state;
135998948Sobrien  ops->setbaudrate = hardwire_setbaudrate;
136098948Sobrien  ops->setstopbits = hardwire_setstopbits;
136198948Sobrien  ops->drain_output = hardwire_drain_output;
136298948Sobrien  ops->async = ser_unix_async;
136398948Sobrien  serial_add_interface (ops);
136498948Sobrien}
1365