From mboxrd@z Thu Jan 1 00:00:00 1970 From: Andrew Cagney To: gdb-patches AT sourceware.cygnus.com Subject: ser*.[hc] cleanup Date: Tue, 14 Sep 1999 23:15:00 -0000 Message-id: <37DF373E.F05A3406@cygnus.com> X-SW-Source: 1999-q3/msg00255.html Hello, The attached patch: o creates the two files ser-fd.[hc] that contains generic UNIX/FD serial code. Q. File name? Is ser-fdgen better? ser-gen? o updates ser-pipe.c and ser-tcp.c so that they use that common code o updates ser-unix.c but only a little (there wasn't as much in common). In going through this I noticed that ser-unix.c implements non-blocking reads using either select() or TERMIO/TERMIOS calls (?). I'm wondering if the TERMIO/TERMIOS code that causes timeouts is now redundant. It would appear that we're assuming select() anyway (c.f. event-loop.c). That would allow me to be even more ruthless :-) Andrew Index: Makefile.in =================================================================== RCS file: /cvs/cvsfiles/devo/gdb/Makefile.in,v retrieving revision 1.703 diff -p -r1.703 Makefile.in *** Makefile.in 1999/09/13 15:36:28 1.703 --- Makefile.in 1999/09/15 05:49:22 *************** RUNTESTFLAGS= *** 301,307 **** # 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) --- 301,307 ---- # 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 ser-fd.o # The `remote' debugging target is supported for most architectures, # but not all (e.g. 960) *************** ALLDEPFILES = 29k-share/udi/udip2soc.c 2 *** 1071,1077 **** 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-pipe.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 \ --- 1071,1077 ---- 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-pipe.c ser-ocd.c ser-tcp.c ser-fd.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 \ *************** scm-lang.o: $(defs_h) $(value_h) parser- *** 1680,1696 **** scm-valprint.o: $(defs_h) $(value_h) parser-defs.h language.h \ scm-lang.h valprint.h $(gdbcore_h) ser-go32.o: ser-go32.c $(defs_h) serial.h 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 ! ser-unix.o: ser-unix.c $(defs_h) serial.h serial.o: serial.c $(defs_h) serial.h gdb_string.h --- 1680,1698 ---- scm-valprint.o: $(defs_h) $(value_h) parser-defs.h language.h \ scm-lang.h valprint.h $(gdbcore_h) + ser-fd.o: ser-fd.c $(defs_h) serial.h ser-fd.h + ser-go32.o: ser-go32.c $(defs_h) serial.h 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-fd.h ! ser-tcp.o: ser-tcp.c $(defs_h) serial.h signals.h gdb_string.h ser-fd.h ! ser-unix.o: ser-unix.c $(defs_h) serial.h ser-fd.h serial.o: serial.c $(defs_h) serial.h gdb_string.h Index: ser-pipe.c =================================================================== RCS file: /cvs/cvsfiles/devo/gdb/ser-pipe.c,v retrieving revision 2.10 diff -p -r2.10 ser-pipe.c *** ser-pipe.c 1999/09/14 03:43:27 2.10 --- ser-pipe.c 1999/09/15 05:49:38 *************** *** 22,27 **** --- 22,29 ---- #include "defs.h" #include "serial.h" + #include "ser-fd.h" + #include #ifdef HAVE_SYS_WAIT_H #include *************** *** 33,62 **** #include "signals.h" #include "gdb_string.h" - extern int (*ui_loop_hook) (int); - static int pipe_open (serial_t scb, const char *name); - static void pipe_raw (serial_t scb); - static int wait_for (serial_t scb, int timeout); - static int pipe_readchar (serial_t scb, int timeout); - static int pipe_setbaudrate (serial_t scb, int rate); - static int pipe_setstopbits (serial_t scb, int num); - static int pipe_write (serial_t scb, const char *str, int len); - /* FIXME: static void pipe_restore (serial_t scb); */ static void pipe_close (serial_t scb); - static serial_ttystate pipe_get_tty_state (serial_t scb); - static int pipe_set_tty_state (serial_t scb, serial_ttystate state); - static int pipe_return_0 (serial_t); - static int pipe_noflush_set_tty_state (serial_t, serial_ttystate, - serial_ttystate); - static void pipe_print_tty_state (serial_t, serial_ttystate, struct gdb_file *); extern void _initialize_ser_pipe (void); - #undef XMALLOC - #define XMALLOC(T) ((T*) xmalloc (sizeof (T))) - - struct pipe_state { int pid; --- 35,45 ---- *************** pipe_open (serial_t scb, const char *nam *** 141,344 **** #endif } - static serial_ttystate - pipe_get_tty_state (serial_t scb) - { - /* return garbage */ - return xmalloc (sizeof (int)); - } - - static int - pipe_set_tty_state (serial_t scb, serial_ttystate ttystate) - { - return 0; - } - - static int - pipe_return_0 (serial_t scb) - { - return 0; - } - - static void - pipe_raw (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 (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 (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 (serial_t scb, - serial_ttystate new_ttystate, - serial_ttystate old_ttystate) - { - return 0; - } - - static void - pipe_print_tty_state (serial_t scb, - serial_ttystate ttystate, - struct gdb_file *stream) - { - /* Nothing to print. */ - return; - } - - static int - pipe_setbaudrate (serial_t scb, int rate) - { - return 0; /* Never fails! */ - } - - static int - pipe_setstopbits (serial_t scb, int num) - { - return 0; /* Never fails! */ - } - - static int - pipe_write (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 (serial_t scb) { --- 124,129 ---- *************** pipe_close (serial_t scb) *** 355,383 **** } } ! 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 (void) { serial_add_interface (&pipe_ops); } --- 140,166 ---- } } ! static struct serial_ops pipe_ops; void _initialize_ser_pipe (void) { + pipe_ops.name = "pipe"; + pipe_ops.next = 0; + pipe_ops.open = pipe_open; + pipe_ops.close = pipe_close; + pipe_ops.readchar = serial_fd_readchar; + pipe_ops.write = serial_fd_write; + pipe_ops.flush_output = serial_fd_nop_flush_output; + pipe_ops.flush_input = serial_fd_nop_flush_input; + pipe_ops.send_break = serial_fd_nop_send_break; + pipe_ops.go_raw = serial_fd_nop_raw; + pipe_ops.get_tty_state = serial_fd_nop_get_tty_state; + pipe_ops.set_tty_state = serial_fd_nop_set_tty_state; + pipe_ops.print_tty_state = serial_fd_nop_print_tty_state; + pipe_ops.noflush_set_tty_state = serial_fd_nop_noflush_set_tty_state; + pipe_ops.setbaudrate = serial_fd_nop_setbaudrate; + pipe_ops.setstopbits = serial_fd_nop_setstopbits; + pipe_ops.drain_output = serial_fd_nop_drain_output; serial_add_interface (&pipe_ops); } Index: ser-tcp.c =================================================================== RCS file: /cvs/cvsfiles/devo/gdb/ser-tcp.c,v retrieving revision 2.32 diff -p -r2.32 ser-tcp.c *** ser-tcp.c 1999/09/14 04:18:05 2.32 --- ser-tcp.c 1999/09/15 05:49:38 *************** *** 20,32 **** #include "defs.h" #include "serial.h" #include #include #include #include #include #include - #ifndef __CYGWIN32__ #include #endif --- 20,33 ---- #include "defs.h" #include "serial.h" + #include "ser-fd.h" + #include #include #include #include #include #include #ifndef __CYGWIN32__ #include #endif *************** *** 34,66 **** #include "signals.h" #include "gdb_string.h" - /* start-sanitize-churchill */ - #ifdef UI_OUT - #define BUFSIZ 1 - #endif - /* end-sanitize-churchill */ - extern int (*ui_loop_hook) (int); - - struct tcp_ttystate - { - int bogus; - }; - static int tcp_open (serial_t scb, const char *name); - static void tcp_raw (serial_t scb); - static int wait_for (serial_t scb, int timeout); - static int tcp_readchar (serial_t scb, int timeout); - static int tcp_setbaudrate (serial_t scb, int rate); - static int tcp_setstopbits (serial_t scb, int num); - static int tcp_write (serial_t scb, const char *str, int len); - /* FIXME: static void tcp_restore (serial_t scb); */ static void tcp_close (serial_t scb); - static serial_ttystate tcp_get_tty_state (serial_t scb); - static int tcp_set_tty_state (serial_t scb, serial_ttystate state); - static int tcp_return_0 (serial_t); - static int tcp_noflush_set_tty_state (serial_t, serial_ttystate, - serial_ttystate); - static void tcp_print_tty_state (serial_t, serial_ttystate, struct gdb_file *); void _initialize_ser_tcp (void); --- 35,42 ---- *************** tcp_open (serial_t scb, const char *name *** 146,357 **** return 0; } - static serial_ttystate - tcp_get_tty_state (serial_t scb) - { - struct tcp_ttystate *state; - - state = (struct tcp_ttystate *) xmalloc (sizeof *state); - - return (serial_ttystate) state; - } - - static int - tcp_set_tty_state (serial_t scb, serial_ttystate ttystate) - { - struct tcp_ttystate *state; - - state = (struct tcp_ttystate *) ttystate; - - return 0; - } - - static int - tcp_return_0 (serial_t scb) - { - return 0; - } - static void - tcp_raw (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 tcp_read(). - */ - - static int - wait_for (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 - tcp_readchar (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 - tcp_noflush_set_tty_state (serial_t scb, - serial_ttystate new_ttystate, - serial_ttystate old_ttystate) - { - return 0; - } - - static void - tcp_print_tty_state (serial_t scb, - serial_ttystate ttystate, - struct gdb_file *stream) - { - /* Nothing to print. */ - return; - } - - static int - tcp_setbaudrate (serial_t scb, int rate) - { - return 0; /* Never fails! */ - } - - static int - tcp_setstopbits (serial_t scb, int num) - { - return 0; /* Never fails! */ - } - - static int - tcp_write (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 tcp_close (serial_t scb) { if (scb->fd < 0) --- 122,128 ---- *************** tcp_close (serial_t scb) *** 361,389 **** scb->fd = -1; } ! static struct serial_ops tcp_ops = ! { ! "tcp", ! 0, ! tcp_open, ! tcp_close, ! tcp_readchar, ! tcp_write, ! tcp_return_0, /* flush output */ ! tcp_return_0, /* flush input */ ! tcp_return_0, /* send break */ ! tcp_raw, ! tcp_get_tty_state, ! tcp_set_tty_state, ! tcp_print_tty_state, ! tcp_noflush_set_tty_state, ! tcp_setbaudrate, ! tcp_setstopbits, ! tcp_return_0, /* wait for output to drain */ ! }; void _initialize_ser_tcp (void) { serial_add_interface (&tcp_ops); } --- 132,158 ---- scb->fd = -1; } ! static struct serial_ops tcp_ops; void _initialize_ser_tcp (void) { + tcp_ops.name = "tcp"; + tcp_ops.next = 0; + tcp_ops.open = tcp_open; + tcp_ops.close = tcp_close; + tcp_ops.readchar = serial_fd_readchar; + tcp_ops.write = serial_fd_write; + tcp_ops.flush_output = serial_fd_nop_flush_output; + tcp_ops.flush_input = serial_fd_nop_flush_input; + tcp_ops.send_break = serial_fd_nop_send_break; + tcp_ops.go_raw = serial_fd_nop_raw; + tcp_ops.get_tty_state = serial_fd_nop_get_tty_state; + tcp_ops.set_tty_state = serial_fd_nop_set_tty_state; + tcp_ops.print_tty_state = serial_fd_nop_print_tty_state; + tcp_ops.noflush_set_tty_state = serial_fd_nop_noflush_set_tty_state; + tcp_ops.setbaudrate = serial_fd_nop_setbaudrate; + tcp_ops.setstopbits = serial_fd_nop_setstopbits; + tcp_ops.drain_output = serial_fd_nop_drain_output; serial_add_interface (&tcp_ops); } Index: ser-unix.c =================================================================== RCS file: /cvs/cvsfiles/devo/gdb/ser-unix.c,v retrieving revision 2.48 diff -p -r2.48 ser-unix.c *** ser-unix.c 1999/09/14 04:18:05 2.48 --- ser-unix.c 1999/09/15 05:49:38 *************** *** 20,25 **** --- 20,27 ---- #include "defs.h" #include "serial.h" + #include "ser-fd.h" + #include #include #include "terminal.h" *************** static int *** 415,451 **** wait_for (serial_t scb, int timeout) { #ifdef HAVE_SGTTY ! { ! struct timeval tv; ! fd_set readfds; ! ! FD_ZERO (&readfds); ! ! tv.tv_sec = timeout; ! tv.tv_usec = 0; ! ! FD_SET (scb->fd, &readfds); ! ! while (1) ! { ! int numfds; ! ! if (timeout >= 0) ! numfds = select (scb->fd + 1, &readfds, 0, 0, &tv); ! else ! numfds = select (scb->fd + 1, &readfds, 0, 0, 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; ! } ! } #endif /* HAVE_SGTTY */ #if defined HAVE_TERMIO || defined HAVE_TERMIOS --- 417,423 ---- wait_for (serial_t scb, int timeout) { #ifdef HAVE_SGTTY ! return serial_fd_wait_for (scb, timeout); #endif /* HAVE_SGTTY */ #if defined HAVE_TERMIO || defined HAVE_TERMIOS *************** hardwire_setstopbits (scb, num) *** 786,808 **** return set_tty_state (scb, &state); } - static int - hardwire_write (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 hardwire_close (serial_t scb) { --- 758,763 ---- *************** hardwire_close (serial_t scb) *** 813,841 **** scb->fd = -1; } ! static struct serial_ops hardwire_ops = ! { ! "hardwire", ! 0, ! hardwire_open, ! hardwire_close, ! hardwire_readchar, ! hardwire_write, ! hardwire_flush_output, ! hardwire_flush_input, ! hardwire_send_break, ! hardwire_raw, ! hardwire_get_tty_state, ! hardwire_set_tty_state, ! hardwire_print_tty_state, ! hardwire_noflush_set_tty_state, ! hardwire_setbaudrate, ! hardwire_setstopbits, ! hardwire_drain_output, /* wait for output to drain */ ! }; void _initialize_ser_hardwire (void) { serial_add_interface (&hardwire_ops); } --- 768,794 ---- scb->fd = -1; } ! static struct serial_ops hardwire_ops; void _initialize_ser_hardwire (void) { + hardwire_ops.name = "hardwire"; + hardwire_ops.next = 0; + hardwire_ops.open = hardwire_open; + hardwire_ops.close = hardwire_close; + hardwire_ops.readchar = hardwire_readchar; + hardwire_ops.write = serial_fd_write; + hardwire_ops.flush_output = hardwire_flush_output; + hardwire_ops.flush_input = hardwire_flush_input; + hardwire_ops.send_break = hardwire_send_break; + hardwire_ops.go_raw = hardwire_raw; + hardwire_ops.get_tty_state = hardwire_get_tty_state; + hardwire_ops.set_tty_state = hardwire_set_tty_state; + hardwire_ops.print_tty_state = hardwire_print_tty_state; + hardwire_ops.noflush_set_tty_state = hardwire_noflush_set_tty_state; + hardwire_ops.setbaudrate = hardwire_setbaudrate; + hardwire_ops.setstopbits = hardwire_setstopbits; + hardwire_ops.drain_output = hardwire_drain_output; serial_add_interface (&hardwire_ops); } *** /dev/null Wed Sep 15 15:50:04 1999 --- ser-fd.h Wed Sep 15 15:23:05 1999 *************** *** 0 **** --- 1,50 ---- + /* Serial interface for UN*X file-descriptor based connection. + Copyright 1999 Free Software Foundation, Inc. + + 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. */ + + #ifndef SER_FD_H + #define SER_FD_H + + #undef XMALLOC + #define XMALLOC(TYPE) (TYPE*) xmalloc (sizeof (TYPE)) + + /* Generic FD functions */ + + extern int serial_fd_nop_flush_output (serial_t scb); + extern int serial_fd_nop_flush_input (serial_t scb); + extern int serial_fd_nop_send_break (serial_t scb); + extern void serial_fd_nop_raw (serial_t scb); + extern serial_ttystate serial_fd_nop_get_tty_state (serial_t scb); + extern int serial_fd_nop_set_tty_state (serial_t scb, serial_ttystate ttystate); + extern void serial_fd_nop_print_tty_state (serial_t scb, + serial_ttystate ttystate, + struct gdb_file *stream); + extern int serial_fd_nop_noflush_set_tty_state (serial_t scb, + serial_ttystate new_ttystate, + serial_ttystate old_ttystate); + extern int serial_fd_nop_setbaudrate (serial_t scb, int rate); + extern int serial_fd_nop_setstopbits (serial_t scb, int rate); + extern int serial_fd_nop_drain_output (serial_t scb); + + int serial_fd_wait_for (serial_t scb, int timeout); + int serial_fd_readchar (serial_t scb, int timeout); + + int serial_fd_write (serial_t scb, const char *str, int len); + + #endif *** /dev/null Wed Sep 15 15:50:04 1999 --- ser-fd.c Wed Sep 15 15:29:51 1999 *************** *** 0 **** --- 1,270 ---- + /* Serial interface for UN*X file-descriptor based connection. + Copyright 1992, 1993, 1998-1999 Free Software Foundation, Inc. + + 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 "ser-fd.h" + + #include + #ifdef HAVE_SYS_WAIT_H + #include + #endif + #include + #include + #include + + #include "signals.h" + #include "gdb_string.h" + + /* start-sanitize-churchill */ + #ifdef UI_OUT + #define BUFSIZ 1 + #endif + /* end-sanitize-churchill */ + extern int (*ui_loop_hook) (int); + + #if 0 + int + serial_fd_fatal_open (serial_t scb, const char *name) + { + internal_error ("ser-fd: no open method"); + return -1; + } + #endif + + #if 0 + void + serial_fd_fatal_close (serial_t scb) + { + internal_error ("ser-fd: no close method"); + } + #endif + + serial_ttystate + serial_fd_nop_get_tty_state (serial_t scb) + { + /* allocate a dummy */ + return (serial_ttystate) XMALLOC (int); + } + + int + serial_fd_nop_set_tty_state (serial_t scb, serial_ttystate ttystate) + { + return 0; + } + + void + serial_fd_nop_raw (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. */ + + int + serial_fd_wait_for (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). */ + + int + serial_fd_readchar (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 = serial_fd_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++; + } + + int + serial_fd_nop_noflush_set_tty_state (serial_t scb, + serial_ttystate new_ttystate, + serial_ttystate old_ttystate) + { + return 0; + } + + void + serial_fd_nop_print_tty_state (serial_t scb, + serial_ttystate ttystate, + struct gdb_file *stream) + { + /* Nothing to print. */ + return; + } + + int + serial_fd_nop_setbaudrate (serial_t scb, int rate) + { + return 0; /* Never fails! */ + } + + int + serial_fd_nop_setstopbits (serial_t scb, int num) + { + return 0; /* Never fails! */ + } + + int + serial_fd_write (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; + } + + int + serial_fd_nop_flush_output (serial_t scb) + { + return 0; + } + + int + serial_fd_nop_flush_input (serial_t scb) + { + return 0; + } + + int + serial_fd_nop_send_break (serial_t scb) + { + return 0; + } + + int + serial_fd_nop_drain_output (serial_t scb) + { + return 0; + } From mboxrd@z Thu Jan 1 00:00:00 1970 From: Andrew Cagney To: gdb-patches@sourceware.cygnus.com Subject: ser*.[hc] cleanup Date: Sat, 27 Nov 1999 18:50:00 -0000 Message-ID: <37DF373E.F05A3406@cygnus.com> X-SW-Source: 1999-q4/msg00331.html Message-ID: <19991127185000.b9bM1InbAfNxvxoXL_4MDdjH-qTQ6wLtGjg-ZWsokKo@z> Hello, The attached patch: o creates the two files ser-fd.[hc] that contains generic UNIX/FD serial code. Q. File name? Is ser-fdgen better? ser-gen? o updates ser-pipe.c and ser-tcp.c so that they use that common code o updates ser-unix.c but only a little (there wasn't as much in common). In going through this I noticed that ser-unix.c implements non-blocking reads using either select() or TERMIO/TERMIOS calls (?). I'm wondering if the TERMIO/TERMIOS code that causes timeouts is now redundant. It would appear that we're assuming select() anyway (c.f. event-loop.c). That would allow me to be even more ruthless :-) Andrew Index: Makefile.in =================================================================== RCS file: /cvs/cvsfiles/devo/gdb/Makefile.in,v retrieving revision 1.703 diff -p -r1.703 Makefile.in *** Makefile.in 1999/09/13 15:36:28 1.703 --- Makefile.in 1999/09/15 05:49:22 *************** RUNTESTFLAGS= *** 301,307 **** # 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) --- 301,307 ---- # 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 ser-fd.o # The `remote' debugging target is supported for most architectures, # but not all (e.g. 960) *************** ALLDEPFILES = 29k-share/udi/udip2soc.c 2 *** 1071,1077 **** 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-pipe.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 \ --- 1071,1077 ---- 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-pipe.c ser-ocd.c ser-tcp.c ser-fd.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 \ *************** scm-lang.o: $(defs_h) $(value_h) parser- *** 1680,1696 **** scm-valprint.o: $(defs_h) $(value_h) parser-defs.h language.h \ scm-lang.h valprint.h $(gdbcore_h) ser-go32.o: ser-go32.c $(defs_h) serial.h 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 ! ser-unix.o: ser-unix.c $(defs_h) serial.h serial.o: serial.c $(defs_h) serial.h gdb_string.h --- 1680,1698 ---- scm-valprint.o: $(defs_h) $(value_h) parser-defs.h language.h \ scm-lang.h valprint.h $(gdbcore_h) + ser-fd.o: ser-fd.c $(defs_h) serial.h ser-fd.h + ser-go32.o: ser-go32.c $(defs_h) serial.h 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-fd.h ! ser-tcp.o: ser-tcp.c $(defs_h) serial.h signals.h gdb_string.h ser-fd.h ! ser-unix.o: ser-unix.c $(defs_h) serial.h ser-fd.h serial.o: serial.c $(defs_h) serial.h gdb_string.h Index: ser-pipe.c =================================================================== RCS file: /cvs/cvsfiles/devo/gdb/ser-pipe.c,v retrieving revision 2.10 diff -p -r2.10 ser-pipe.c *** ser-pipe.c 1999/09/14 03:43:27 2.10 --- ser-pipe.c 1999/09/15 05:49:38 *************** *** 22,27 **** --- 22,29 ---- #include "defs.h" #include "serial.h" + #include "ser-fd.h" + #include #ifdef HAVE_SYS_WAIT_H #include *************** *** 33,62 **** #include "signals.h" #include "gdb_string.h" - extern int (*ui_loop_hook) (int); - static int pipe_open (serial_t scb, const char *name); - static void pipe_raw (serial_t scb); - static int wait_for (serial_t scb, int timeout); - static int pipe_readchar (serial_t scb, int timeout); - static int pipe_setbaudrate (serial_t scb, int rate); - static int pipe_setstopbits (serial_t scb, int num); - static int pipe_write (serial_t scb, const char *str, int len); - /* FIXME: static void pipe_restore (serial_t scb); */ static void pipe_close (serial_t scb); - static serial_ttystate pipe_get_tty_state (serial_t scb); - static int pipe_set_tty_state (serial_t scb, serial_ttystate state); - static int pipe_return_0 (serial_t); - static int pipe_noflush_set_tty_state (serial_t, serial_ttystate, - serial_ttystate); - static void pipe_print_tty_state (serial_t, serial_ttystate, struct gdb_file *); extern void _initialize_ser_pipe (void); - #undef XMALLOC - #define XMALLOC(T) ((T*) xmalloc (sizeof (T))) - - struct pipe_state { int pid; --- 35,45 ---- *************** pipe_open (serial_t scb, const char *nam *** 141,344 **** #endif } - static serial_ttystate - pipe_get_tty_state (serial_t scb) - { - /* return garbage */ - return xmalloc (sizeof (int)); - } - - static int - pipe_set_tty_state (serial_t scb, serial_ttystate ttystate) - { - return 0; - } - - static int - pipe_return_0 (serial_t scb) - { - return 0; - } - - static void - pipe_raw (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 (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 (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 (serial_t scb, - serial_ttystate new_ttystate, - serial_ttystate old_ttystate) - { - return 0; - } - - static void - pipe_print_tty_state (serial_t scb, - serial_ttystate ttystate, - struct gdb_file *stream) - { - /* Nothing to print. */ - return; - } - - static int - pipe_setbaudrate (serial_t scb, int rate) - { - return 0; /* Never fails! */ - } - - static int - pipe_setstopbits (serial_t scb, int num) - { - return 0; /* Never fails! */ - } - - static int - pipe_write (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 (serial_t scb) { --- 124,129 ---- *************** pipe_close (serial_t scb) *** 355,383 **** } } ! 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 (void) { serial_add_interface (&pipe_ops); } --- 140,166 ---- } } ! static struct serial_ops pipe_ops; void _initialize_ser_pipe (void) { + pipe_ops.name = "pipe"; + pipe_ops.next = 0; + pipe_ops.open = pipe_open; + pipe_ops.close = pipe_close; + pipe_ops.readchar = serial_fd_readchar; + pipe_ops.write = serial_fd_write; + pipe_ops.flush_output = serial_fd_nop_flush_output; + pipe_ops.flush_input = serial_fd_nop_flush_input; + pipe_ops.send_break = serial_fd_nop_send_break; + pipe_ops.go_raw = serial_fd_nop_raw; + pipe_ops.get_tty_state = serial_fd_nop_get_tty_state; + pipe_ops.set_tty_state = serial_fd_nop_set_tty_state; + pipe_ops.print_tty_state = serial_fd_nop_print_tty_state; + pipe_ops.noflush_set_tty_state = serial_fd_nop_noflush_set_tty_state; + pipe_ops.setbaudrate = serial_fd_nop_setbaudrate; + pipe_ops.setstopbits = serial_fd_nop_setstopbits; + pipe_ops.drain_output = serial_fd_nop_drain_output; serial_add_interface (&pipe_ops); } Index: ser-tcp.c =================================================================== RCS file: /cvs/cvsfiles/devo/gdb/ser-tcp.c,v retrieving revision 2.32 diff -p -r2.32 ser-tcp.c *** ser-tcp.c 1999/09/14 04:18:05 2.32 --- ser-tcp.c 1999/09/15 05:49:38 *************** *** 20,32 **** #include "defs.h" #include "serial.h" #include #include #include #include #include #include - #ifndef __CYGWIN32__ #include #endif --- 20,33 ---- #include "defs.h" #include "serial.h" + #include "ser-fd.h" + #include #include #include #include #include #include #ifndef __CYGWIN32__ #include #endif *************** *** 34,66 **** #include "signals.h" #include "gdb_string.h" - /* start-sanitize-churchill */ - #ifdef UI_OUT - #define BUFSIZ 1 - #endif - /* end-sanitize-churchill */ - extern int (*ui_loop_hook) (int); - - struct tcp_ttystate - { - int bogus; - }; - static int tcp_open (serial_t scb, const char *name); - static void tcp_raw (serial_t scb); - static int wait_for (serial_t scb, int timeout); - static int tcp_readchar (serial_t scb, int timeout); - static int tcp_setbaudrate (serial_t scb, int rate); - static int tcp_setstopbits (serial_t scb, int num); - static int tcp_write (serial_t scb, const char *str, int len); - /* FIXME: static void tcp_restore (serial_t scb); */ static void tcp_close (serial_t scb); - static serial_ttystate tcp_get_tty_state (serial_t scb); - static int tcp_set_tty_state (serial_t scb, serial_ttystate state); - static int tcp_return_0 (serial_t); - static int tcp_noflush_set_tty_state (serial_t, serial_ttystate, - serial_ttystate); - static void tcp_print_tty_state (serial_t, serial_ttystate, struct gdb_file *); void _initialize_ser_tcp (void); --- 35,42 ---- *************** tcp_open (serial_t scb, const char *name *** 146,357 **** return 0; } - static serial_ttystate - tcp_get_tty_state (serial_t scb) - { - struct tcp_ttystate *state; - - state = (struct tcp_ttystate *) xmalloc (sizeof *state); - - return (serial_ttystate) state; - } - - static int - tcp_set_tty_state (serial_t scb, serial_ttystate ttystate) - { - struct tcp_ttystate *state; - - state = (struct tcp_ttystate *) ttystate; - - return 0; - } - - static int - tcp_return_0 (serial_t scb) - { - return 0; - } - static void - tcp_raw (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 tcp_read(). - */ - - static int - wait_for (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 - tcp_readchar (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 - tcp_noflush_set_tty_state (serial_t scb, - serial_ttystate new_ttystate, - serial_ttystate old_ttystate) - { - return 0; - } - - static void - tcp_print_tty_state (serial_t scb, - serial_ttystate ttystate, - struct gdb_file *stream) - { - /* Nothing to print. */ - return; - } - - static int - tcp_setbaudrate (serial_t scb, int rate) - { - return 0; /* Never fails! */ - } - - static int - tcp_setstopbits (serial_t scb, int num) - { - return 0; /* Never fails! */ - } - - static int - tcp_write (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 tcp_close (serial_t scb) { if (scb->fd < 0) --- 122,128 ---- *************** tcp_close (serial_t scb) *** 361,389 **** scb->fd = -1; } ! static struct serial_ops tcp_ops = ! { ! "tcp", ! 0, ! tcp_open, ! tcp_close, ! tcp_readchar, ! tcp_write, ! tcp_return_0, /* flush output */ ! tcp_return_0, /* flush input */ ! tcp_return_0, /* send break */ ! tcp_raw, ! tcp_get_tty_state, ! tcp_set_tty_state, ! tcp_print_tty_state, ! tcp_noflush_set_tty_state, ! tcp_setbaudrate, ! tcp_setstopbits, ! tcp_return_0, /* wait for output to drain */ ! }; void _initialize_ser_tcp (void) { serial_add_interface (&tcp_ops); } --- 132,158 ---- scb->fd = -1; } ! static struct serial_ops tcp_ops; void _initialize_ser_tcp (void) { + tcp_ops.name = "tcp"; + tcp_ops.next = 0; + tcp_ops.open = tcp_open; + tcp_ops.close = tcp_close; + tcp_ops.readchar = serial_fd_readchar; + tcp_ops.write = serial_fd_write; + tcp_ops.flush_output = serial_fd_nop_flush_output; + tcp_ops.flush_input = serial_fd_nop_flush_input; + tcp_ops.send_break = serial_fd_nop_send_break; + tcp_ops.go_raw = serial_fd_nop_raw; + tcp_ops.get_tty_state = serial_fd_nop_get_tty_state; + tcp_ops.set_tty_state = serial_fd_nop_set_tty_state; + tcp_ops.print_tty_state = serial_fd_nop_print_tty_state; + tcp_ops.noflush_set_tty_state = serial_fd_nop_noflush_set_tty_state; + tcp_ops.setbaudrate = serial_fd_nop_setbaudrate; + tcp_ops.setstopbits = serial_fd_nop_setstopbits; + tcp_ops.drain_output = serial_fd_nop_drain_output; serial_add_interface (&tcp_ops); } Index: ser-unix.c =================================================================== RCS file: /cvs/cvsfiles/devo/gdb/ser-unix.c,v retrieving revision 2.48 diff -p -r2.48 ser-unix.c *** ser-unix.c 1999/09/14 04:18:05 2.48 --- ser-unix.c 1999/09/15 05:49:38 *************** *** 20,25 **** --- 20,27 ---- #include "defs.h" #include "serial.h" + #include "ser-fd.h" + #include #include #include "terminal.h" *************** static int *** 415,451 **** wait_for (serial_t scb, int timeout) { #ifdef HAVE_SGTTY ! { ! struct timeval tv; ! fd_set readfds; ! ! FD_ZERO (&readfds); ! ! tv.tv_sec = timeout; ! tv.tv_usec = 0; ! ! FD_SET (scb->fd, &readfds); ! ! while (1) ! { ! int numfds; ! ! if (timeout >= 0) ! numfds = select (scb->fd + 1, &readfds, 0, 0, &tv); ! else ! numfds = select (scb->fd + 1, &readfds, 0, 0, 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; ! } ! } #endif /* HAVE_SGTTY */ #if defined HAVE_TERMIO || defined HAVE_TERMIOS --- 417,423 ---- wait_for (serial_t scb, int timeout) { #ifdef HAVE_SGTTY ! return serial_fd_wait_for (scb, timeout); #endif /* HAVE_SGTTY */ #if defined HAVE_TERMIO || defined HAVE_TERMIOS *************** hardwire_setstopbits (scb, num) *** 786,808 **** return set_tty_state (scb, &state); } - static int - hardwire_write (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 hardwire_close (serial_t scb) { --- 758,763 ---- *************** hardwire_close (serial_t scb) *** 813,841 **** scb->fd = -1; } ! static struct serial_ops hardwire_ops = ! { ! "hardwire", ! 0, ! hardwire_open, ! hardwire_close, ! hardwire_readchar, ! hardwire_write, ! hardwire_flush_output, ! hardwire_flush_input, ! hardwire_send_break, ! hardwire_raw, ! hardwire_get_tty_state, ! hardwire_set_tty_state, ! hardwire_print_tty_state, ! hardwire_noflush_set_tty_state, ! hardwire_setbaudrate, ! hardwire_setstopbits, ! hardwire_drain_output, /* wait for output to drain */ ! }; void _initialize_ser_hardwire (void) { serial_add_interface (&hardwire_ops); } --- 768,794 ---- scb->fd = -1; } ! static struct serial_ops hardwire_ops; void _initialize_ser_hardwire (void) { + hardwire_ops.name = "hardwire"; + hardwire_ops.next = 0; + hardwire_ops.open = hardwire_open; + hardwire_ops.close = hardwire_close; + hardwire_ops.readchar = hardwire_readchar; + hardwire_ops.write = serial_fd_write; + hardwire_ops.flush_output = hardwire_flush_output; + hardwire_ops.flush_input = hardwire_flush_input; + hardwire_ops.send_break = hardwire_send_break; + hardwire_ops.go_raw = hardwire_raw; + hardwire_ops.get_tty_state = hardwire_get_tty_state; + hardwire_ops.set_tty_state = hardwire_set_tty_state; + hardwire_ops.print_tty_state = hardwire_print_tty_state; + hardwire_ops.noflush_set_tty_state = hardwire_noflush_set_tty_state; + hardwire_ops.setbaudrate = hardwire_setbaudrate; + hardwire_ops.setstopbits = hardwire_setstopbits; + hardwire_ops.drain_output = hardwire_drain_output; serial_add_interface (&hardwire_ops); } *** /dev/null Wed Sep 15 15:50:04 1999 --- ser-fd.h Wed Sep 15 15:23:05 1999 *************** *** 0 **** --- 1,50 ---- + /* Serial interface for UN*X file-descriptor based connection. + Copyright 1999 Free Software Foundation, Inc. + + 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. */ + + #ifndef SER_FD_H + #define SER_FD_H + + #undef XMALLOC + #define XMALLOC(TYPE) (TYPE*) xmalloc (sizeof (TYPE)) + + /* Generic FD functions */ + + extern int serial_fd_nop_flush_output (serial_t scb); + extern int serial_fd_nop_flush_input (serial_t scb); + extern int serial_fd_nop_send_break (serial_t scb); + extern void serial_fd_nop_raw (serial_t scb); + extern serial_ttystate serial_fd_nop_get_tty_state (serial_t scb); + extern int serial_fd_nop_set_tty_state (serial_t scb, serial_ttystate ttystate); + extern void serial_fd_nop_print_tty_state (serial_t scb, + serial_ttystate ttystate, + struct gdb_file *stream); + extern int serial_fd_nop_noflush_set_tty_state (serial_t scb, + serial_ttystate new_ttystate, + serial_ttystate old_ttystate); + extern int serial_fd_nop_setbaudrate (serial_t scb, int rate); + extern int serial_fd_nop_setstopbits (serial_t scb, int rate); + extern int serial_fd_nop_drain_output (serial_t scb); + + int serial_fd_wait_for (serial_t scb, int timeout); + int serial_fd_readchar (serial_t scb, int timeout); + + int serial_fd_write (serial_t scb, const char *str, int len); + + #endif *** /dev/null Wed Sep 15 15:50:04 1999 --- ser-fd.c Wed Sep 15 15:29:51 1999 *************** *** 0 **** --- 1,270 ---- + /* Serial interface for UN*X file-descriptor based connection. + Copyright 1992, 1993, 1998-1999 Free Software Foundation, Inc. + + 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 "ser-fd.h" + + #include + #ifdef HAVE_SYS_WAIT_H + #include + #endif + #include + #include + #include + + #include "signals.h" + #include "gdb_string.h" + + /* start-sanitize-churchill */ + #ifdef UI_OUT + #define BUFSIZ 1 + #endif + /* end-sanitize-churchill */ + extern int (*ui_loop_hook) (int); + + #if 0 + int + serial_fd_fatal_open (serial_t scb, const char *name) + { + internal_error ("ser-fd: no open method"); + return -1; + } + #endif + + #if 0 + void + serial_fd_fatal_close (serial_t scb) + { + internal_error ("ser-fd: no close method"); + } + #endif + + serial_ttystate + serial_fd_nop_get_tty_state (serial_t scb) + { + /* allocate a dummy */ + return (serial_ttystate) XMALLOC (int); + } + + int + serial_fd_nop_set_tty_state (serial_t scb, serial_ttystate ttystate) + { + return 0; + } + + void + serial_fd_nop_raw (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. */ + + int + serial_fd_wait_for (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). */ + + int + serial_fd_readchar (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 = serial_fd_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++; + } + + int + serial_fd_nop_noflush_set_tty_state (serial_t scb, + serial_ttystate new_ttystate, + serial_ttystate old_ttystate) + { + return 0; + } + + void + serial_fd_nop_print_tty_state (serial_t scb, + serial_ttystate ttystate, + struct gdb_file *stream) + { + /* Nothing to print. */ + return; + } + + int + serial_fd_nop_setbaudrate (serial_t scb, int rate) + { + return 0; /* Never fails! */ + } + + int + serial_fd_nop_setstopbits (serial_t scb, int num) + { + return 0; /* Never fails! */ + } + + int + serial_fd_write (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; + } + + int + serial_fd_nop_flush_output (serial_t scb) + { + return 0; + } + + int + serial_fd_nop_flush_input (serial_t scb) + { + return 0; + } + + int + serial_fd_nop_send_break (serial_t scb) + { + return 0; + } + + int + serial_fd_nop_drain_output (serial_t scb) + { + return 0; + }