Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Andrew Cagney <ac131313@cygnus.com>
To: Stan Shebs <shebs@cygnus.com>
Cc: jtc@redback.com, gdb-patches@sourceware.cygnus.com
Subject: Re: Patch to speed up remote protocol
Date: Wed, 07 Jul 1999 20:36:00 -0000	[thread overview]
Message-ID: <37841C56.A1A1525@cygnus.com> (raw)
In-Reply-To: <5md7y42ii0.fsf@jtc.redbacknetworks.com>

[Dropped ian, added stan; Policy question follows]

"J.T. Conklin" wrote:
> I'm not sure I like the idea of setting GDB's support of the P packet
> from the CLI.  If it can be autonegotiated successfully (which my
> experience has shown to be true), there doesn't seem to be a need.  I
> do agree that once a stub accepts 'P', it should be expected to always
> support it within that debugging session.
> 
> As for names, it probably should have "remote" in the name to tie it
> to the other remote protocol variables.  Perhaps:
> 
>         remote-stub-supports-P-packet
>         remote-protocol-supports-P-packet
>         remote-protocol-supports-register-set

Is there a policy on second level set/show commands?  vis:

	set remote P-packet ...

polluting the top level with obscure protocol control commands is
certainly a problem.  (Assuming this is possible of course :-).

	Andrew
From eliz@delorie.com Wed Jul 07 23:44:00 1999
From: Eli Zaretskii <eliz@delorie.com>
To: Stan Shebs <shebs@cygnus.com>
Cc: gdb-patches@sourceware.cygnus.com
Subject: Re: [eliz@is.elta.co.il: GDB: fine print in 387 info]
Date: Wed, 07 Jul 1999 23:44:00 -0000
Message-id: <199907080644.CAA08528@indy.delorie.com>
X-SW-Source: 1999-q3/msg00016.html
Content-length: 735

Date: Wed, 7 Jul 1999 18:17:06 -0700
From: Stan Shebs <shebs@cygnus.com>

> It's worth considering whether this ought to be done with macros or
> with the new architecture machinery

Can you give me a hint where to look for the "new architecture
machinery" in the sources?  Is it something that was introduced only
after 4.18 was released?

> Unless someone can work up a counterexample, let's define (and
> document) a single layout, and work from that.

Okay, I will try to come up with a suggestion, based on Bill
Metzenthen's code with minimal changes, and post it for review
and discussion.

By ``document'' you mean a description in the GDB manual, right, or is
there some other place where such things are/should be documented?
From ac131313@cygnus.com Thu Jul 08 00:10:00 1999
From: Andrew Cagney <ac131313@cygnus.com>
To: Eli Zaretskii <eliz@delorie.com>
Cc: Stan Shebs <shebs@cygnus.com>, gdb-patches@sourceware.cygnus.com
Subject: Re: [eliz@is.elta.co.il: GDB: fine print in 387 info]
Date: Thu, 08 Jul 1999 00:10:00 -0000
Message-id: <37844EB1.E59FDE9D@cygnus.com>
References: <199907080644.CAA08528@indy.delorie.com>
X-SW-Source: 1999-q3/msg00017.html
Content-length: 821

Eli Zaretskii wrote:
> 
> Date: Wed, 7 Jul 1999 18:17:06 -0700
> From: Stan Shebs <shebs@cygnus.com>
> 
> > It's worth considering whether this ought to be done with macros or
> > with the new architecture machinery
> 
> Can you give me a hint where to look for the "new architecture
> machinery" in the sources?  Is it something that was introduced only
> after 4.18 was released?

It was introduced after 4.18 was released.

I wouldn't be trying to change any i386 target to the new architecture
machinary :-)  I'd just be trying to approach the problem with a
mind-set that dictates that any compile time configury is to be avoided
- #if is bad; #define X {...;...;...} is also bad.

It should be possible to create a generic info_registers_387 function. 
That always asks the target for information.

Enjoy,

	Andrew
From eliz@delorie.com Thu Jul 08 00:23:00 1999
From: Eli Zaretskii <eliz@delorie.com>
To: Andrew Cagney <ac131313@cygnus.com>
Cc: gdb-patches@sourceware.cygnus.com
Subject: Re: [eliz@is.elta.co.il: GDB: fine print in 387 info]
Date: Thu, 08 Jul 1999 00:23:00 -0000
Message-id: <199907080723.DAA25670@indy.delorie.com>
X-SW-Source: 1999-q3/msg00018.html
Content-length: 485

Date: Thu, 08 Jul 1999 17:09:37 +1000
From: Andrew Cagney <ac131313@cygnus.com>

> It should be possible to create a generic info_registers_387 function.
> That always asks the target for information.

Given that several platforms that use x87 already define different
x87-related macros and enumerate the FP reghisters differently, your
suggestion would imply that all those macros and different definitions
should be removed and replaced with unified code.  Do I read you
correctly?
From ac131313@cygnus.com Thu Jul 08 01:30:00 1999
From: Andrew Cagney <ac131313@cygnus.com>
To: Eli Zaretskii <eliz@delorie.com>
Cc: gdb-patches@sourceware.cygnus.com
Subject: Re: [eliz@is.elta.co.il: GDB: fine print in 387 info]
Date: Thu, 08 Jul 1999 01:30:00 -0000
Message-id: <3784617C.5A93C40B@cygnus.com>
References: <199907080723.DAA25670@indy.delorie.com>
X-SW-Source: 1999-q3/msg00019.html
Content-length: 570

Eli Zaretskii wrote:
> 
> Date: Thu, 08 Jul 1999 17:09:37 +1000
> From: Andrew Cagney <ac131313@cygnus.com>
> 
> > It should be possible to create a generic info_registers_387 function.
> > That always asks the target for information.
> 
> Given that several platforms that use x87 already define different
> x87-related macros and enumerate the FP reghisters differently, your
> suggestion would imply that all those macros and different definitions
> should be removed and replaced with unified code.  Do I read you
> correctly?

Just don't make it worse :-)

	Andrew
From shebs@cygnus.com Thu Jul 08 13:07:00 1999
From: Stan Shebs <shebs@cygnus.com>
To: eliz@delorie.com
Cc: gdb-patches@sourceware.cygnus.com
Subject: Re: [eliz@is.elta.co.il: GDB: fine print in 387 info]
Date: Thu, 08 Jul 1999 13:07:00 -0000
Message-id: <199907082007.NAA18549@andros.cygnus.com>
References: <199907080644.CAA08528@indy.delorie.com>
X-SW-Source: 1999-q3/msg00020.html
Content-length: 653

   Date: Thu, 8 Jul 1999 02:44:11 -0400 (EDT)
   From: Eli Zaretskii <eliz@delorie.com>

   Okay, I will try to come up with a suggestion, based on Bill
   Metzenthen's code with minimal changes, and post it for review
   and discussion.

Cool.

   By ``document'' you mean a description in the GDB manual, right, or is
   there some other place where such things are/should be documented?

The GDB manual is plausible, although it's more of a user manual than
a formal specification, and doesn't normally get into layout details.
This would be ideal for the internals manual.  A long comment in the
code is OK too, though less desirable.

								Stan
From jimb@cygnus.com Thu Jul 08 17:56:00 1999
From: Jim Blandy <jimb@cygnus.com>
To: Eli Zaretskii <eliz@is.elta.co.il>, Mark Kettenis <kettenis@wins.uva.nl>, dj@delorie.com, billm@suburbia.net
Cc: gdb-patches@sourceware.cygnus.com
Subject: Unifying i387 support
Date: Thu, 08 Jul 1999 17:56:00 -0000
Message-id: <npoghmtzfj.fsf@zwingli.cygnus.com>
References: <Pine.SUN.3.91.990707154129.2851X-100000@is>
X-SW-Source: 1999-q3/msg00021.html
Content-length: 1625

We would like make it possible to write code that accesses the i387
registers which can be shared amongst all the i386-based targets.
However, at present, each target lays the registers out differently in
GDB's map, and #defines different symbols to say where things are.

There are two approaches to fix this.

1) We could choose a common set of symbols, assign them useful
   semantics, and make each target #define them appropriately.  Then,
   generic i387 code can just use them.  Each target will continue to
   lay out registers in GDB's map as it pleases.

2) We could choose a single register layout for all i387 targets to
   use, and require targets to reform the data they receive from the
   OS via ptrace or whatever to fit that layout.  Generic i387 code
   can be written to assume this layout.

Both options can be applied to targets as need and interest arises:
only targets which want to use our generic i387 code need conform to
the interface.

Option 1) is a little simpler: we only need to change the tm-*.h files
and the generic i387 code; no target-specific code needs to change.

Option 2) seems friendlier to multi-arch, since if you are using a
387, you know everything you need to know.  Under option 1), different
i387 targets have different layouts, so the multi-arch system needs to
carry more information to the generic code.

Linux already does an arbitrary reformatting between the u area and
GDB's register array; I think most targets do.  So that's not a
problem.

Option 2) also appeals to me because it's simpler: I don't see why we
should use multiple layouts for the same information.
From dj@delorie.com Thu Jul 08 18:05:00 1999
From: DJ Delorie <dj@delorie.com>
To: jimb@cygnus.com
Cc: eliz@is.elta.co.il, kettenis@wins.uva.nl, billm@suburbia.net, gdb-patches@sourceware.cygnus.com
Subject: Re: Unifying i387 support
Date: Thu, 08 Jul 1999 18:05:00 -0000
Message-id: <199907090104.VAA25054@indy.delorie.com>
References: <npoghmtzfj.fsf@zwingli.cygnus.com>
X-SW-Source: 1999-q3/msg00022.html
Content-length: 285

> 2) We could choose a single register layout for all i387 targets to

If one needs to be created, we should follow the layout that the
FNSAVE instruction stores the data in.  That may simplify some
targets, and it's the only really documented layout (it's in all the
Intel manuals :)
From ac131313@cygnus.com Thu Jul 08 18:34:00 1999
From: Andrew Cagney <ac131313@cygnus.com>
To: Jim Blandy <jimb@cygnus.com>
Cc: Eli Zaretskii <eliz@is.elta.co.il>, Mark Kettenis <kettenis@wins.uva.nl>, dj@delorie.com, billm@suburbia.net, gdb-patches@sourceware.cygnus.com
Subject: Re: Unifying i387 support
Date: Thu, 08 Jul 1999 18:34:00 -0000
Message-id: <37855111.9E78AF48@cygnus.com>
References: <Pine.SUN.3.91.990707154129.2851X-100000@is> <npoghmtzfj.fsf@zwingli.cygnus.com>
X-SW-Source: 1999-q3/msg00023.html
Content-length: 1380

Jim Blandy wrote:
> 
> We would like make it possible to write code that accesses the i387
> registers which can be shared amongst all the i386-based targets.
> However, at present, each target lays the registers out differently in
> GDB's map, and #defines different symbols to say where things are.
> 
> There are two approaches to fix this.
> 
> 1) We could choose a common set of symbols, assign them useful
>    semantics, and make each target #define them appropriately.  Then,
>    generic i387 code can just use them.  Each target will continue to
>    lay out registers in GDB's map as it pleases.
> 
> 2) We could choose a single register layout for all i387 targets to
>    use, and require targets to reform the data they receive from the
>    OS via ptrace or whatever to fit that layout.  Generic i387 code
>    can be written to assume this layout.

I also have a strong preference for two.

Another issue to keep in mind is remote.c.  It assumes that the order
registers appear in a G packet corresponds to their internal-to-gdb
register numbering.  It relies heavily on REGISTER_RAW_SIZE().

I'm not adverse to ideas such as there being a macro that maps a
target-G-packet register onto an internal register.  Kind of like the
RAW/VIRTUAL stuff but in the correct place :-).  The alternative would
be to parameterize the target with specific call backs.

	Andrew
From ac131313@cygnus.com Thu Jul 08 21:15:00 1999
From: Andrew Cagney <ac131313@cygnus.com>
To: gdb-patches@sourceware.cygnus.com
Subject: target extended-remote |program
Date: Thu, 08 Jul 1999 21:15:00 -0000
Message-id: <3785773C.7581A196@cygnus.com>
X-SW-Source: 1999-q3/msg00024.html
Content-length: 15646

FYI,

I've just checked in the attached.  If you're into developing a GDB stub
on a simulator then this is for you.  It allows GDB to communicate with
a sub process using the remote (or any other) protocol.

	Andrew

cagney@b1.cygnus.com$ ./gdb/gdb ~/tmp/hello.mn103 
This GDB was configured as "--host=i386-unknown-freebsdelf3.2
--target=mn10300-elf"...
(gdb) target extended-remote |./sim/mn10300/run ....
Remote debugging using |./sim/mn10300/run ....
0x40003387 in ?? ()
(gdb) load
Loading section .text, size 0xcb6 lma 0x40010000
Loading section .rodata, size 0x27 lma 0x40010cb6
Loading section .data, size 0x738 lma 0x40010de0
Start address 0x40010000 , load size 5141

Transfer rate: 6854 bits/sec.
(gdb) b main
Breakpoint 1 at 0x4001003d: file hello.c, line 3.
(gdb) run
The program being debugged has been started already.
Start it from the beginning? (y or n) y

Starting program: /home/people/cagney/tmp/hello.mn103 

Breakpoint 1, main () at hello.c:3
warning: Source file is more recent than executable.

3         char hello[] = "Hello World\n";
(gdb) quit
The program is running.  Exit anyway? (y or n) y


Thu Jul  8 16:48:40 1999  Andrew Cagney  <cagney@b1.cygnus.com>

        * ser-pipe.c (pipe_open): Bi-directional popen found on both
        NetBSD and OpenBSD.
        * ser-pipe.c: New file.  Implement popen() style serial
interface.
        * NEWS: Mention.
        * Makefile.in (ALLDEPFILES): Add ser-pipe.c.
        (ser-pipe.o): Add new target.  Specify dependencies.
        (SER_HARDWIRE): Add ser-pipe.o.
        * serial.c (serial_open): Recognize a serial pipe ``|''.
Index: Makefile.in
===================================================================
RCS file: /cvs/gdb/gdb/gdb/Makefile.in,v
retrieving revision 1.1.1.13
diff -p -r1.1.1.13 Makefile.in
*** Makefile.in	1999/07/07 17:20:04	1.1.1.13
--- Makefile.in	1999/07/09 03:59:50
*************** RUNTESTFLAGS=
*** 242,248 ****
  # part of libiberty) a POSIX interface.  But at least for now the
  # host-dependent makefile fragment might need to use something else
  # besides ser-unix.o
! SER_HARDWIRE = ser-unix.o
  
  # The `remote' debugging target is supported for most architectures,
  # but not all (e.g. 960)
--- 242,248 ----
  # part of libiberty) a POSIX interface.  But at least for now the
  # host-dependent makefile fragment might need to use something else
  # besides ser-unix.o
! SER_HARDWIRE = ser-unix.o ser-pipe.o
  
  # The `remote' debugging target is supported for most architectures,
  # but not all (e.g. 960)
*************** ALLDEPFILES = 29k-share/udi/udip2soc.c 2
*** 967,973 ****
  	remote-st.c remote-utils.c dcache.c \
  	remote-udi.c remote-vx.c remote-vx29k.c \
  	rs6000-nat.c rs6000-tdep.c \
! 	ser-go32.c ser-ocd.c ser-tcp.c sh-tdep.c solib.c sparc-nat.c \
  	sparc-tdep.c sparcl-tdep.c sun3-nat.c sun386-nat.c \
  	symm-tdep.c symm-nat.c \
  	tahoe-tdep.c ultra3-nat.c ultra3-xdep.c umax-xdep.c \
--- 967,974 ----
  	remote-st.c remote-utils.c dcache.c \
  	remote-udi.c remote-vx.c remote-vx29k.c \
  	rs6000-nat.c rs6000-tdep.c \
! 	ser-go32.c ser-ocd.c ser-pipe.c ser-tcp.c \
! 	sh-tdep.c solib.c sparc-nat.c \
  	sparc-tdep.c sparcl-tdep.c sun3-nat.c sun386-nat.c \
  	symm-tdep.c symm-nat.c \
  	tahoe-tdep.c ultra3-nat.c ultra3-xdep.c umax-xdep.c \
*************** ser-go32.o: ser-go32.c $(defs_h) serial.
*** 1491,1496 ****
--- 1492,1499 ----
  ser-mac.o: ser-mac.c $(defs_h) serial.h signals.h
  
  ser-ocd.o: ser-ocd.c $(defs_h) serial.h signals.h gdb_string.h
+ 
+ ser-pipe.o: ser-pipe.c $(defs_h) serial.h signals.h gdb_string.h
  
  ser-tcp.o: ser-tcp.c $(defs_h) serial.h signals.h gdb_string.h
  
Index: NEWS
===================================================================
RCS file: /cvs/gdb/gdb/gdb/NEWS,v
retrieving revision 1.1.1.4
diff -p -r1.1.1.4 NEWS
*** NEWS	1999/07/07 17:20:06	1.1.1.4
--- NEWS	1999/07/09 04:00:10
***************
*** 3,8 ****
--- 3,18 ----
  
  *** Changes since GDB-4.18:
  
+ * Remote targets can connect to a sub-program
+ 
+ A popen(3) style serial-device has been added.  This device starts a
+ sub-process (such as a stand-alone simulator) and then communicates
+ with that.  The sub-program to run is specified using the syntax
+ ``|<program> <args>'' vis:
+ 
+ 	(gdb) set remotedebug 1
+ 	(gdb) target extended-remote |mn10300-elf-sim program-args
+ 
  * New targets
  
  TI TMS320C80					tic80-*-*
Index: serial.c
===================================================================
RCS file: /cvs/gdb/gdb/gdb/serial.c,v
retrieving revision 1.1.1.3
diff -p -r1.1.1.3 serial.c
*** serial.c	1999/07/07 20:09:51	1.1.1.3
--- serial.c	1999/07/09 04:00:18
*************** serial_open (name)
*** 240,245 ****
--- 240,247 ----
      ops = serial_interface_lookup ("tcp");
    else if (strncmp (name, "lpt", 3) == 0)
      ops = serial_interface_lookup ("parallel");
+   else if (strncmp (name, "|", 1) == 0)
+     ops = serial_interface_lookup ("pipe");
    else
      ops = serial_interface_lookup ("hardwire");
  
*** /dev/null	Fri Jul  9 13:28:33 1999
--- ser-pipe.c	Fri Jul  9 13:51:27 1999
***************
*** 0 ****
--- 1,397 ----
+ /* Serial interface for a pipe to a separate program
+    Copyright 1999 Free Software Foundation, Inc.
+ 
+    Contributed by Cygnus Solutions.
+ 
+    This file is part of GDB.
+ 
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+ 
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+ 
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330,
+    Boston, MA 02111-1307, USA.  */
+ 
+ #include "defs.h"
+ #include "serial.h"
+ #include <sys/types.h>
+ #include <sys/wait.h>
+ #include <sys/socket.h>
+ #include <sys/time.h>
+ #include <fcntl.h>
+ #ifdef HAVE_UNISTD_H
+ #include <unistd.h>
+ #endif
+ 
+ #include "signals.h"
+ #include "gdb_string.h"
+ 
+ extern int (*ui_loop_hook) PARAMS ((int));
+ 
+ static int pipe_open PARAMS ((serial_t scb, const char *name));
+ static void pipe_raw PARAMS ((serial_t scb));
+ static int wait_for PARAMS ((serial_t scb, int timeout));
+ static int pipe_readchar PARAMS ((serial_t scb, int timeout));
+ static int pipe_setbaudrate PARAMS ((serial_t scb, int rate));
+ static int pipe_setstopbits PARAMS ((serial_t scb, int num));
+ static int pipe_write PARAMS ((serial_t scb, const char *str, int len));
+ /* FIXME: static void pipe_restore PARAMS ((serial_t scb)); */
+ static void pipe_close PARAMS ((serial_t scb));
+ static serial_ttystate pipe_get_tty_state PARAMS ((serial_t scb));
+ static int pipe_set_tty_state PARAMS ((serial_t scb, serial_ttystate state));
+ static int pipe_return_0 PARAMS ((serial_t));
+ static int pipe_noflush_set_tty_state PARAMS ((serial_t, serial_ttystate,
+ 					       serial_ttystate));
+ static void pipe_print_tty_state PARAMS ((serial_t, serial_ttystate));
+ 
+ extern void _initialize_ser_pipe PARAMS ((void));
+ 
+ /* Open up a raw pipe */
+ 
+ static int
+ pipe_open (scb, name)
+      serial_t scb;
+      const char *name;
+ {
+ #if !defined(O_NONBLOCK) || !defined(F_GETFL) || !defined(F_SETFL)
+   return -1;
+ #else
+ #if defined (__NetBSD__) || defined (__FreeBSD__)
+ 
+   /* check the BSD popen sources for where "r+" comes from :-) */
+   FILE *stream;
+   stream = popen (name + 1, "r+");
+   if (stream == NULL)
+     {
+       fprintf_unfiltered (gdb_stderr, "%s: popen failed\n", name + 1);
+       return -1;
+     }
+   scb->ttystate = stream;	/* borrow that space */
+   scb->fd = fileno (stream);
+ 
+ #else
+ 
+   /* This chunk: */
+ 
+   /* Copyright (c) 1988, 1993
+    *      The Regents of the University of California.  All rights reserved.
+    *
+    * This code is derived from software written by Ken Arnold and
+    * published in UNIX Review, Vol. 6, No. 8.
+    */
+   int pdes[2];
+   int pid;
+   if (socketpair (AF_UNIX, SOCK_STREAM, 0, pdes) < 0)
+     return -1;
+ 
+   switch (pid = vfork ())
+     {
+     case -1:			/* Error. */
+       close (pdes[0]);
+       close (pdes[1]);
+       return -1;
+     case 0:			/* Child. */
+ #if 0
+       /* POSIX.2 B.3.2.2 "popen() shall ensure that any streams
+          from previous popen() calls that remain open in the 
+          parent process are closed in the new child process. */
+       for (old = pidlist; old; old = old->next)
+ 	close (fileno (old->fp));	/* don't allow a flush */
+ #endif
+       close (pdes[0]);
+       if (pdes[1] != STDOUT_FILENO)
+ 	{
+ 	  dup2 (pdes[1], STDOUT_FILENO);
+ 	  close (pdes[1]);
+ 	}
+       dup2 (STDOUT_FILENO, STDIN_FILENO);
+       execl ("/bin/sh", "sh", "-c", name + 1, NULL);
+       _exit (127);
+     }
+ 
+   /* Parent; assume fdopen can't fail. */
+   close (pdes[1]);
+   scb->fd = pdes[0];
+   scb->ttystate = NULL;
+ #endif
+ 
+   /* Make it non-blocking */
+   {
+     int flags = fcntl (scb->fd, F_GETFL, 0);
+     if (fcntl (scb->fd, F_SETFL, flags | O_NONBLOCK) < 0)
+       {
+ 	perror ("ser-pipe");
+ 	pipe_close (scb);
+ 	return -1;
+       }
+   }
+ 
+   /* If we don't do this, GDB simply exits when the remote side dies.  */
+   signal (SIGPIPE, SIG_IGN);
+   return 0;
+ #endif
+ }
+ 
+ static serial_ttystate
+ pipe_get_tty_state (scb)
+      serial_t scb;
+ {
+   /* return garbage */
+   return xmalloc (sizeof (int));
+ }
+ 
+ static int
+ pipe_set_tty_state (scb, ttystate)
+      serial_t scb;
+      serial_ttystate ttystate;
+ {
+   return 0;
+ }
+ 
+ static int
+ pipe_return_0 (scb)
+      serial_t scb;
+ {
+   return 0;
+ }
+ 
+ static void
+ pipe_raw (scb)
+      serial_t scb;
+ {
+   return;			/* Always in raw mode */
+ }
+ 
+ /* Wait for input on scb, with timeout seconds.  Returns 0 on success,
+    otherwise SERIAL_TIMEOUT or SERIAL_ERROR.
+ 
+    For termio{s}, we actually just setup VTIME if necessary, and let the
+    timeout occur in the read() in pipe_read().
+  */
+ 
+ static int
+ wait_for (scb, timeout)
+      serial_t scb;
+      int timeout;
+ {
+   int numfds;
+   struct timeval tv;
+   fd_set readfds, exceptfds;
+ 
+   FD_ZERO (&readfds);
+   FD_ZERO (&exceptfds);
+ 
+   tv.tv_sec = timeout;
+   tv.tv_usec = 0;
+ 
+   FD_SET (scb->fd, &readfds);
+   FD_SET (scb->fd, &exceptfds);
+ 
+   while (1)
+     {
+       if (timeout >= 0)
+ 	numfds = select (scb->fd + 1, &readfds, 0, &exceptfds, &tv);
+       else
+ 	numfds = select (scb->fd + 1, &readfds, 0, &exceptfds, 0);
+ 
+       if (numfds <= 0)
+ 	{
+ 	  if (numfds == 0)
+ 	    return SERIAL_TIMEOUT;
+ 	  else if (errno == EINTR)
+ 	    continue;
+ 	  else
+ 	    return SERIAL_ERROR;	/* Got an error from select or poll */
+ 	}
+ 
+       return 0;
+     }
+ }
+ 
+ /* Read a character with user-specified timeout.  TIMEOUT is number of seconds
+    to wait, or -1 to wait forever.  Use timeout of 0 to effect a poll.  Returns
+    char if successful.  Returns -2 if timeout expired, EOF if line dropped
+    dead, or -3 for any other error (see errno in that case). */
+ 
+ static int
+ pipe_readchar (scb, timeout)
+      serial_t scb;
+      int timeout;
+ {
+   int status;
+   int delta;
+ 
+   if (scb->bufcnt-- > 0)
+     return *scb->bufp++;
+ 
+   /* We have to be able to keep the GUI alive here, so we break the original
+      timeout into steps of 1 second, running the "keep the GUI alive" hook 
+      each time through the loop.
+ 
+      Also, timeout = 0 means to poll, so we just set the delta to 0, so we
+      will only go through the loop once. */
+ 
+   delta = (timeout == 0 ? 0 : 1);
+   while (1)
+     {
+ 
+       /* N.B. The UI may destroy our world (for instance by calling
+          remote_stop,) in which case we want to get out of here as
+          quickly as possible.  It is not safe to touch scb, since
+          someone else might have freed it.  The ui_loop_hook signals that 
+          we should exit by returning 1. */
+ 
+       if (ui_loop_hook)
+ 	{
+ 	  if (ui_loop_hook (0))
+ 	    return SERIAL_TIMEOUT;
+ 	}
+ 
+       status = wait_for (scb, delta);
+       timeout -= delta;
+ 
+       /* If we got a character or an error back from wait_for, then we can 
+          break from the loop before the timeout is completed. */
+ 
+       if (status != SERIAL_TIMEOUT)
+ 	{
+ 	  break;
+ 	}
+ 
+       /* If we have exhausted the original timeout, then generate
+          a SERIAL_TIMEOUT, and pass it out of the loop. */
+ 
+       else if (timeout == 0)
+ 	{
+ 	  status == SERIAL_TIMEOUT;
+ 	  break;
+ 	}
+     }
+ 
+   if (status < 0)
+     return status;
+ 
+   while (1)
+     {
+       scb->bufcnt = read (scb->fd, scb->buf, BUFSIZ);
+       if (scb->bufcnt != -1 || errno != EINTR)
+ 	break;
+     }
+ 
+   if (scb->bufcnt <= 0)
+     {
+       if (scb->bufcnt == 0)
+ 	return SERIAL_TIMEOUT;	/* 0 chars means timeout [may need to
+ 				   distinguish between EOF & timeouts
+ 				   someday] */
+       else
+ 	return SERIAL_ERROR;	/* Got an error from read */
+     }
+ 
+   scb->bufcnt--;
+   scb->bufp = scb->buf;
+   return *scb->bufp++;
+ }
+ 
+ static int
+ pipe_noflush_set_tty_state (scb, new_ttystate, old_ttystate)
+      serial_t scb;
+      serial_ttystate new_ttystate;
+      serial_ttystate old_ttystate;
+ {
+   return 0;
+ }
+ 
+ static void
+ pipe_print_tty_state (scb, ttystate)
+      serial_t scb;
+      serial_ttystate ttystate;
+ {
+   /* Nothing to print.  */
+   return;
+ }
+ 
+ static int
+ pipe_setbaudrate (scb, rate)
+      serial_t scb;
+      int rate;
+ {
+   return 0;			/* Never fails! */
+ }
+ 
+ static int
+ pipe_setstopbits (scb, num)
+      serial_t scb;
+      int num;
+ {
+   return 0;			/* Never fails! */
+ }
+ 
+ static int
+ pipe_write (scb, str, len)
+      serial_t scb;
+      const char *str;
+      int len;
+ {
+   int cc;
+ 
+   while (len > 0)
+     {
+       cc = write (scb->fd, str, len);
+ 
+       if (cc < 0)
+ 	return 1;
+       len -= cc;
+       str += cc;
+     }
+   return 0;
+ }
+ 
+ static void
+ pipe_close (scb)
+      serial_t scb;
+ {
+   if (scb->fd < 0)
+     return;
+   if (scb->ttystate != NULL)
+     pclose ((FILE *) scb->ttystate);
+   else
+     close (scb->fd);
+   scb->ttystate = NULL;
+   scb->fd = -1;
+ }
+ 
+ static struct serial_ops pipe_ops =
+ {
+   "pipe",
+   0,
+   pipe_open,
+   pipe_close,
+   pipe_readchar,
+   pipe_write,
+   pipe_return_0,		/* flush output */
+   pipe_return_0,		/* flush input */
+   pipe_return_0,		/* send break */
+   pipe_raw,
+   pipe_get_tty_state,
+   pipe_set_tty_state,
+   pipe_print_tty_state,
+   pipe_noflush_set_tty_state,
+   pipe_setbaudrate,
+   pipe_setstopbits,
+   pipe_return_0,		/* wait for output to drain */
+ };
+ 
+ void
+ _initialize_ser_pipe ()
+ {
+   serial_add_interface (&pipe_ops);
+ }



      reply	other threads:[~1999-07-07 20:36 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <19990702201648.32062.qmail@daffy.airs.com>
     [not found] ` <378338EC.C709D54@cygnus.com>
1999-07-07 15:39   ` J.T. Conklin
1999-07-07 20:36     ` Andrew Cagney [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=37841C56.A1A1525@cygnus.com \
    --to=ac131313@cygnus.com \
    --cc=gdb-patches@sourceware.cygnus.com \
    --cc=jtc@redback.com \
    --cc=shebs@cygnus.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox