From 3ffbdf15324b373b8a941dc58e421d1420b80ffc Mon Sep 17 00:00:00 2001
From: Fred Fish <fnf@specifix.com>
Date: Fri, 6 Mar 1998 20:38:45 +0000
Subject: PR 15068 	* utils.c (quit): Call SERIAL_DRAIN_OUTPUT rather than
  	SERIAL_FLUSH_OUTPUT. 	* serial.h (struct serial_ops): Add
 drain_output, pointer to  	function that waits for output to drain. 
 (SERIAL_DRAIN_OUTPUT): Macro to wait for output to drain. 	* ser-unix.c
 (hardwire_drain_output): New function and prototype.

	* ser-unix.c (hardwire_ops): Add entry for drain_output function.
	* ser-tcp.c (tcp_ops): Ditto.
	* ser-ocd.c (ocd_ops): Ditto.
	* ser-mac.c (mac_ops): Ditto.
	* ser-go32.c (dos_ops): Ditto.
	* ser-e7kpc.c (e7000pc_ops): Ditto.
---
 gdb/ChangeLog   | 16 ++++++++++++++++
 gdb/ser-e7kpc.c |  1 +
 gdb/ser-go32.c  |  1 +
 gdb/ser-mac.c   |  1 +
 gdb/ser-ocd.c   |  1 +
 gdb/ser-tcp.c   |  1 +
 gdb/ser-unix.c  | 34 ++++++++++++++++++++++++++++++++++
 gdb/serial.h    | 11 ++++++++++-
 8 files changed, 65 insertions(+), 1 deletion(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index b356ec5..59eb4dd 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,19 @@
+Fri Mar  6 13:10:27 1998  Fred Fish  <fnf@cygnus.com>
+
+	* utils.c (quit): Call SERIAL_DRAIN_OUTPUT rather than
+ 	SERIAL_FLUSH_OUTPUT.
+	* serial.h (struct serial_ops): Add drain_output, pointer to
+ 	function that waits for output to drain.
+	(SERIAL_DRAIN_OUTPUT): Macro to wait for output to drain.
+	* ser-unix.c (hardwire_drain_output): New function and prototype.
+
+	* ser-unix.c (hardwire_ops): Add entry for drain_output function.
+	* ser-tcp.c (tcp_ops): Ditto.
+	* ser-ocd.c (ocd_ops): Ditto.
+	* ser-mac.c (mac_ops): Ditto.
+	* ser-go32.c (dos_ops): Ditto.
+	* ser-e7kpc.c (e7000pc_ops): Ditto.
+
 Thu Mar  5 16:07:41 1998  Michael Snyder  (msnyder@cleaver.cygnus.com)
 
 	* sparcl-tdep.c: fix #endif comments
diff --git a/gdb/ser-e7kpc.c b/gdb/ser-e7kpc.c
index 8cf6ec6..4997ba2 100644
--- a/gdb/ser-e7kpc.c
+++ b/gdb/ser-e7kpc.c
@@ -453,6 +453,7 @@ static struct serial_ops e7000pc_ops =
   e7000pc_print_tty_state,
   e7000pc_noflush_set_tty_state,
   e7000pc_setbaudrate,
+  e7000pc_noop,			/* wait for output to drain */
 };
 
 void
diff --git a/gdb/ser-go32.c b/gdb/ser-go32.c
index 4af25f1..f776161 100644
--- a/gdb/ser-go32.c
+++ b/gdb/ser-go32.c
@@ -848,6 +848,7 @@ static struct serial_ops dos_ops =
   dos_noflush_set_tty_state,
   dos_setbaudrate,
   dos_setstopbits,
+  dos_noop,			/* wait for output to drain */
 };
 
 
diff --git a/gdb/ser-mac.c b/gdb/ser-mac.c
index 3540002..df0040e 100644
--- a/gdb/ser-mac.c
+++ b/gdb/ser-mac.c
@@ -352,6 +352,7 @@ static struct serial_ops mac_ops =
   mac_noflush_set_tty_state,
   mac_set_baud_rate,
   mac_set_stop_bits,
+  mac_noop,			/* wait for output to drain */
 };
 
 void
diff --git a/gdb/ser-ocd.c b/gdb/ser-ocd.c
index 08239bb..7ef1796 100644
--- a/gdb/ser-ocd.c
+++ b/gdb/ser-ocd.c
@@ -197,6 +197,7 @@ static struct serial_ops ocd_ops =
   ocd_print_tty_state,
   ocd_noflush_set_tty_state,
   ocd_setbaudrate,
+  ocd_noop,		/* wait for output to drain */
 };
 
 void
diff --git a/gdb/ser-tcp.c b/gdb/ser-tcp.c
index 23153a9..279cbd0 100644
--- a/gdb/ser-tcp.c
+++ b/gdb/ser-tcp.c
@@ -342,6 +342,7 @@ static struct serial_ops tcp_ops =
   tcp_noflush_set_tty_state,
   tcp_setbaudrate,
   tcp_setstopbits,
+  tcp_return_0,	/* wait for output to drain */
 };
 
 void
diff --git a/gdb/ser-unix.c b/gdb/ser-unix.c
index a77da59..b1ffca0 100644
--- a/gdb/ser-unix.c
+++ b/gdb/ser-unix.c
@@ -77,6 +77,7 @@ static int hardwire_set_tty_state PARAMS ((serial_t scb, serial_ttystate state))
 static int hardwire_noflush_set_tty_state PARAMS ((serial_t, serial_ttystate,
 						   serial_ttystate));
 static void hardwire_print_tty_state PARAMS ((serial_t, serial_ttystate));
+static int hardwire_drain_output PARAMS ((serial_t));
 static int hardwire_flush_output PARAMS ((serial_t));
 static int hardwire_flush_input PARAMS ((serial_t));
 static int hardwire_send_break PARAMS ((serial_t));
@@ -275,6 +276,38 @@ hardwire_print_tty_state (scb, ttystate)
 #endif
 }
 
+/* Wait for the output to drain away, as opposed to flushing (discarding) it */
+
+static int
+hardwire_drain_output (scb)
+     serial_t scb;
+{
+#ifdef HAVE_TERMIOS
+  return tcdrain (scb->fd);
+#endif
+
+#ifdef HAVE_TERMIO
+  return ioctl (scb->fd, TCSBRK, 1);
+#endif
+
+#ifdef HAVE_SGTTY
+  /* Get the current state and then restore it using TIOCSETP,
+     which should cause the output to drain and pending input
+     to be discarded. */
+  {
+    struct hardwire_ttystate state;
+    if (get_tty_state (scb, &state))
+      {
+	return (-1);
+      }
+    else
+      {
+	return (ioctl (scb->fd, TIOCSETP, &state.sgttyb));
+      }
+  }
+#endif  
+}
+
 static int
 hardwire_flush_output (scb)
      serial_t scb;
@@ -727,6 +760,7 @@ static struct serial_ops hardwire_ops =
   hardwire_noflush_set_tty_state,
   hardwire_setbaudrate,
   hardwire_setstopbits,
+  hardwire_drain_output,	/* wait for output to drain */
 };
 
 void
diff --git a/gdb/serial.h b/gdb/serial.h
index f1963d0..04332bc 100644
--- a/gdb/serial.h
+++ b/gdb/serial.h
@@ -50,7 +50,9 @@ struct serial_ops {
   void (*close) PARAMS ((serial_t));
   int (*readchar) PARAMS ((serial_t, int timeout));
   int (*write) PARAMS ((serial_t, const char *str, int len));
+  /* Discard pending output */
   int (*flush_output) PARAMS ((serial_t));
+  /* Discard pending input */
   int (*flush_input) PARAMS ((serial_t));
   int (*send_break) PARAMS ((serial_t));
   void (*go_raw) PARAMS ((serial_t));
@@ -61,6 +63,8 @@ struct serial_ops {
     PARAMS ((serial_t, serial_ttystate, serial_ttystate));
   int (*setbaudrate) PARAMS ((serial_t, int rate));
   int (*setstopbits) PARAMS ((serial_t, int num));
+  /* Wait for output to drain */
+  int (*drain_output) PARAMS ((serial_t));
 };
 
 /* Add a new serial interface to the interface list */
@@ -83,7 +87,12 @@ serial_t serial_fdopen PARAMS ((const int fd));
 
 #define SERIAL_FDOPEN(FD) serial_fdopen(FD)
 
-/* Flush pending output.  Might also flush input (if this system can't flush
+/* Allow pending output to drain. */
+
+#define SERIAL_DRAIN_OUTPUT(SERIAL_T) \
+  ((SERIAL_T)->ops->drain_output((SERIAL_T)))
+  
+/* Flush (discard) pending output.  Might also flush input (if this system can't flush
    only output).  */
 
 #define SERIAL_FLUSH_OUTPUT(SERIAL_T) \
-- 
cgit v1.1