From 4e772f4426b2e004da8aaa4cccc7ea483eadf794 Mon Sep 17 00:00:00 2001 From: Stu Grossman Date: Tue, 6 Apr 1993 05:50:54 +0000 Subject: [PATCH] * Makefile.in (SFILES OBS): Add serial.[co] & ser-hardwire.[co]. These implement a new serial line interface for talking to remote targets. * configure.in: Link ser-hardwire.c to ser-unix.c for all hosts, EXCEPT go32, which gets ser-go32.c. * remote.c: Use new serial interface. More remote-xxx's to be converted later. * ser-bsd.c, ser-termios.c: Removed. * serial.c: New. Implements common operations for all serial types. * ser-unix.c: New. Unix specific serial operations for various flavors of Unix (Posix, SysV, BSD). * serial.h: Generic serial interface defs. * config/i386/go32.mh, config/i386/i386bsd.h, config/m68k/apollo68b.mh, config/sparc/sun4os4.mh: Remove ser-bsd.o from XDEPFILES. All the magic is now handled in configure.in. --- gdb/ChangeLog | 20 +++ gdb/Makefile.in | 11 +- gdb/config/i386/go32.mh | 3 + gdb/config/i386/i386bsd.mh | 2 +- gdb/config/m68k/apollo68b.mh | 2 +- gdb/config/sparc/sun4os4.mh | 2 +- gdb/configure.in | 9 +- gdb/ser-bsd.c | 226 ------------------------ gdb/ser-termios.c | 223 ------------------------ gdb/ser-unix.c | 324 +++++++++++++++++++++++++++++++++++ gdb/serial.c | 181 +++++++++++++++++++ gdb/serial.h | 79 ++++----- 12 files changed, 582 insertions(+), 500 deletions(-) create mode 100644 gdb/config/i386/go32.mh create mode 100644 gdb/ser-unix.c create mode 100644 gdb/serial.c diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 44af16b3f10..e8594d1ca9f 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,23 @@ +Mon Apr 5 22:29:43 1993 Stu Grossman (grossman@cygnus.com) + + * Makefile.in (SFILES OBS): Add serial.[co] & ser-hardwire.[co]. + These implement a new serial line interface for talking to remote + targets. + * configure.in: Link ser-hardwire.c to ser-unix.c for all hosts, + EXCEPT go32, which gets ser-go32.c. + * remote.c: Use new serial interface. More remote-xxx's to be + converted later. + * ser-bsd.c, ser-termios.c: Removed. + * serial.c: New. Implements common operations for all serial + types. + * ser-unix.c: New. Unix specific serial operations for various + flavors of Unix (Posix, SysV, BSD). + * serial.h: Generic serial interface defs. + * config/i386/go32.mh, config/i386/i386bsd.h, + config/m68k/apollo68b.mh, config/sparc/sun4os4.mh: Remove + ser-bsd.o from XDEPFILES. All the magic is now handled in + configure.in. + Mon Apr 5 20:48:54 1993 Stu Grossman (grossman@cygnus.com) * config/h8500/tm-h8500.h: Clean up brain damage found by GCC. diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 0ee72964310..76ed9cf68dc 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -281,7 +281,7 @@ SFILES = blockframe.c breakpoint.c buildsym.c c-exp.y c-lang.c c-typeprint.c \ m2-valprint.c main.c maint.c mem-break.c minsyms.c mipsread.c \ objfiles.c parse.c printcmd.c remote.c source.c stabsread.c stack.c \ symfile.c symmisc.c symtab.c target.c typeprint.c utils.c valarith.c \ - valops.c valprint.c values.c + valops.c valprint.c values.c serial.c ser-hardwire.c # Files that are not source code, but need to go into gdb-$(VERSION).tar.Z. NONSRC = Makefile.in depend alldeps.mak createtags munch configure.in \ @@ -354,7 +354,8 @@ OBS = version.o main.o blockframe.o breakpoint.o findvar.o stack.o source.o \ dbxread.o coffread.o elfread.o dwarfread.o mipsread.o \ stabsread.o core.o c-lang.o ch-lang.o m2-lang.o complaints.o \ typeprint.o c-typeprint.o ch-typeprint.o m2-typeprint.o \ - c-valprint.o cp-valprint.o ch-valprint.o m2-valprint.o + c-valprint.o cp-valprint.o ch-valprint.o m2-valprint.o \ + serial.o ser-hardwire.o RAPP_OBS = rgdb.o rudp.o rserial.o serial.o udp.o $(XDEPFILES) @@ -658,23 +659,23 @@ make-proto-gdb-1: ${TARFILES} ${TARDIRS} gdb.info chmod og=u `find . -print` clean: + @$(MAKE) $(FLAGS_TO_PASS) DO=clean "DODIRS=$(SUBDIRS)" subdir_do rm -f *.o ${ADD_FILES} *~ rm -f init.c version.c rm -f gdb core make.log rm -f gdb[0-9] - @$(MAKE) $(FLAGS_TO_PASS) DO=clean "DODIRS=$(SUBDIRS)" subdir_do distclean: clean c-exp.tab.c m2-exp.tab.c ch-exp.tab.c TAGS + @$(MAKE) $(FLAGS_TO_PASS) DO=distclean "DODIRS=$(SUBDIRS)" subdir_do rm -f tm.h xm.h config.status rm -f y.output yacc.acts yacc.tmp rm -f ${TESTS} Makefile depend - @$(MAKE) $(FLAGS_TO_PASS) DO=distclean "DODIRS=$(SUBDIRS)" subdir_do realclean: clean + @$(MAKE) $(FLAGS_TO_PASS) DO=realclean "DODIRS=$(SUBDIRS)" subdir_do rm -f c-exp.tab.c m2-exp.tab.c ch-exp.tab.c TAGS rm -f tm.h xm.h config.status rm -f Makefile depend - @$(MAKE) $(FLAGS_TO_PASS) DO=realclean "DODIRS=$(SUBDIRS)" subdir_do STAGESTUFF=${OBS} ${TSOBS} ${NTSOBS} ${ADD_FILES} init.c init.o version.c gdb diff --git a/gdb/config/i386/go32.mh b/gdb/config/i386/go32.mh new file mode 100644 index 00000000000..45edac871ed --- /dev/null +++ b/gdb/config/i386/go32.mh @@ -0,0 +1,3 @@ +MH_CFLAGS=-D__GO32__ -D__MSDOS__ +XDEPFILES= go32-xdep.o +XM_FILE= xm-go32.h diff --git a/gdb/config/i386/i386bsd.mh b/gdb/config/i386/i386bsd.mh index 20339ca5b6e..c9183768a7e 100644 --- a/gdb/config/i386/i386bsd.mh +++ b/gdb/config/i386/i386bsd.mh @@ -1,5 +1,5 @@ # Host: Intel 386 running 386BSD -XDEPFILES= ser-bsd.o +XDEPFILES= NATDEPFILES= exec.o fork-child.o infptrace.o inftarg.o corelow.o coredep.o i386b-nat.o XM_FILE= xm-i386bsd.h NAT_FILE= nm-i386bsd.h diff --git a/gdb/config/m68k/apollo68b.mh b/gdb/config/m68k/apollo68b.mh index 23860d63ed7..6f554978939 100644 --- a/gdb/config/m68k/apollo68b.mh +++ b/gdb/config/m68k/apollo68b.mh @@ -1,6 +1,6 @@ # Host: Apollo m68k, BSD mode. XM_FILE= xm-apollo68b.h -XDEPFILES= ser-bsd.o +XDEPFILES= NAT_FILE= nm-apollo68b.h NATDEPFILES= infptrace.o inftarg.o fork-child.o a68v-nat.o diff --git a/gdb/config/sparc/sun4os4.mh b/gdb/config/sparc/sun4os4.mh index 7cdb2d0d53a..6f9cc7960dd 100644 --- a/gdb/config/sparc/sun4os4.mh +++ b/gdb/config/sparc/sun4os4.mh @@ -1,5 +1,5 @@ # Host: Sun 4 or Sparcstation, running SunOS 4 -XDEPFILES= ser-bsd.o +XDEPFILES= XM_FILE= xm-sun4os4.h NAT_FILE= nm-sun4os4.h NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o sparc-nat.o diff --git a/gdb/configure.in b/gdb/configure.in index 013bd621b2a..5a1cc698c6e 100644 --- a/gdb/configure.in +++ b/gdb/configure.in @@ -1,6 +1,7 @@ configdirs="doc testsuite" srcname="GDB" srctrigger=main.c +gdb_serial_driver=ser-unix.c # per-host: @@ -36,7 +37,9 @@ i[34]86-ncr-*) gdb_host=ncr3000 ;; i[34]86-sequent-*) gdb_host=symmetry ;; i[34]86-*-bsd*) gdb_host=i386bsd ;; -i[34]86-*-go32) gdb_host=go32 ;; +i[34]86-*-go32) gdb_host=go32 + gdb_serial_driver=ser-go32.c + ;; i[34]86-*-linux) gdb_host=linux ;; i[34]86-*-mach) gdb_host=i386mach ;; i[34]86-*-sco3.2v4*) gdb_host=i386sco4 ;; @@ -267,6 +270,7 @@ target_makefile_frag=config/${gdb_target_cpu}/${gdb_target}.mt files= links= rm -f xm.h +rm -f ser-hardwire.c if [ "${hostfile}" != "" ]; then if [ -f ${srcdir}/config/${hostfile} ]; then files="${files} config/${hostfile}" @@ -274,6 +278,9 @@ if [ "${hostfile}" != "" ]; then files="${files} config/${gdb_host_cpu}/${hostfile}" fi links="${links} xm.h" + + files="${files} ${gdb_serial_driver}" + links="${links} ser-hardwire.c" fi rm -f tm.h if [ "${targetfile}" != "" ]; then diff --git a/gdb/ser-bsd.c b/gdb/ser-bsd.c index a7414d7fa61..e69de29bb2d 100644 --- a/gdb/ser-bsd.c +++ b/gdb/ser-bsd.c @@ -1,226 +0,0 @@ -/* Remote serial interface for OS's with sgttyb - Copyright 1992 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include "defs.h" -#include -#include -#include -#include "serial.h" - -static int desc = -1; - -void -serial_raw(fd, oldstate) - int fd; - struct ttystate *oldstate; -{ - struct sgttyb sgttyb; - - oldstate->flags = fcntl(fd, F_GETFL, 0); - - fcntl(fd, F_SETFL, oldstate->flags|FNDELAY); - - if (ioctl(fd, TIOCGETP, &sgttyb)) - { - fprintf(stderr, "TIOCGETP failed: %s\n", safe_strerror(errno)); - } - - oldstate->sgttyb = sgttyb; - - sgttyb.sg_flags = RAW; - - if (ioctl(fd, TIOCSETP, &sgttyb)) - { - fprintf(stderr, "TIOCSETP failed: %s\n", safe_strerror(errno)); - } -} - -void -serial_restore(fd, oldstate) - int fd; - struct ttystate *oldstate; -{ - fcntl(fd, F_SETFL, oldstate->flags); - - ioctl(fd, TIOCSETP, &oldstate->sgttyb); -} - -static struct ttystate oldstate; - -static fd_set readfds; - -int -serial_open(name) - const char *name; -{ - desc = open (name, O_RDWR); - if (desc < 0) - error("Open of %s failed: %s", name, safe_strerror(errno)); - - serial_raw(desc, &oldstate); - -/* Setup constant stuff for select */ - - FD_ZERO(&readfds); - - return desc; -} - -/* 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_readchar(timeout) - int timeout; -{ - static unsigned char buf[BUFSIZ]; - static unsigned char *bufp; - static int bufcnt = 0; - int numfds; - struct timeval tv; - - if (bufcnt-- > 0) - return *bufp++; - - tv.tv_sec = timeout; - tv.tv_usec = 0; - - FD_SET(desc, &readfds); - - if (timeout >= 0) - numfds = select(desc+1, &readfds, 0, 0, &tv); - else - numfds = select(desc+1, &readfds, 0, 0, 0); - - if (numfds <= 0) - if (numfds == 0) - return -2; /* Timeout */ - else - return -3; /* Got an error from select */ - - bufcnt = read(desc, buf, BUFSIZ); - - if (bufcnt <= 0) - if (bufcnt == 0) - return EOF; /* 0 chars means end of file */ - else - return -3; /* Got an error from read */ - - bufcnt--; - bufp = buf; - return *bufp++; -} - -#ifndef B19200 -#define B19200 EXTA -#endif - -#ifndef B38400 -#define B38400 EXTB -#endif - -/* Translate baud rates from integers to damn B_codes. Unix should - have outgrown this crap years ago, but even POSIX wouldn't buck it. */ - -static struct -{ - int rate; - int code; -} baudtab[] = { - {50, B50}, - {75, B75}, - {110, B110}, - {134, B134}, - {150, B150}, - {200, B200}, - {300, B300}, - {600, B600}, - {1200, B1200}, - {1800, B1800}, - {2400, B2400}, - {4800, B4800}, - {9600, B9600}, - {19200, B19200}, - {38400, B38400}, - {-1, -1}, -}; - -static int -rate_to_code(rate) - int rate; -{ - int i; - - for (i = 0; baudtab[i].rate != -1; i++) - if (rate == baudtab[i].rate) - return baudtab[i].code; - - return -1; -} - -int -serial_setbaudrate(rate) - int rate; -{ - struct sgttyb sgttyb; - - if (ioctl(desc, TIOCGETP, &sgttyb)) - error("TIOCGETP failed: %s\n", safe_strerror(errno)); - - sgttyb.sg_ospeed = rate_to_code(rate); - sgttyb.sg_ispeed = rate_to_code(rate); - - if (ioctl(desc, TIOCSETP, &sgttyb)) - error("TIOCSETP failed: %s\n", safe_strerror(errno)); - - return 1; -} - -int -serial_write(str, len) - const char *str; - int len; -{ - int cc; - - while (len > 0) - { - cc = write(desc, str, len); - - if (cc < 0) - return 0; - len -= cc; - str += cc; - } - return 1; -} - -void -serial_close() -{ - if (desc < 0) - return; - - serial_restore(desc, &oldstate); - - close(desc); - desc = -1; -} diff --git a/gdb/ser-termios.c b/gdb/ser-termios.c index b759632f8a3..e69de29bb2d 100644 --- a/gdb/ser-termios.c +++ b/gdb/ser-termios.c @@ -1,223 +0,0 @@ -/* Remote serial interface for OS's with termios, for GDB. - Copyright 1992 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include "defs.h" -#include -#include -#include "serial.h" - -static int desc = -1; - -void -serial_raw(fd, oldstate) - int fd; - struct ttystate *oldstate; -{ - struct termios termios; - - oldstate->flags = fcntl(fd, F_GETFL, 0); - - fcntl(fd, F_SETFL, oldstate->flags|FNDELAY); - - if (tcgetattr(fd, &termios)) - { - fprintf(stderr, "tcgetattr failed: %s\n", safe_strerror(errno)); - } - - oldstate->termios = termios; - - termios.c_iflag = 0; - termios.c_oflag = 0; - termios.c_lflag = 0; - termios.c_cc[VMIN] = 0; - termios.c_cc[VTIME] = 0; - - if (tcsetattr(fd, TCSANOW, &termios)) - { - fprintf(stderr, "tcsetattr failed: %s\n", safe_strerror(errno)); - } -} - -void -serial_restore(fd, oldstate) - int fd; - struct ttystate *oldstate; -{ - fcntl(fd, F_SETFL, oldstate->flags); - - tcsetattr(fd, TCSANOW, &oldstate->termios); -} - -static struct ttystate oldstate; - -static fd_set readfds; - -int -serial_open(name) - const char *name; -{ - struct termios termios; - - desc = open (name, O_RDWR); - if (desc < 0) - error("Open of %s failed: %s", name, safe_strerror(errno)); - - serial_raw(desc, &oldstate); - -/* Setup constant stuff for select */ - - FD_ZERO(&readfds); - - return desc; -} - -/* 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_readchar(timeout) - int timeout; -{ - static unsigned char buf[BUFSIZ]; - static unsigned char *bufp; - static int bufcnt = 0; - int numfds; - struct timeval tv; - - if (bufcnt-- > 0) - return *bufp++; - - tv.tv_sec = timeout; - tv.tv_usec = 0; - - FD_SET(desc, &readfds); - - if (timeout >= 0) - numfds = select(desc+1, &readfds, 0, 0, &tv); - else - numfds = select(desc+1, &readfds, 0, 0, 0); - - if (numfds <= 0) - if (numfds == 0) - return -2; /* Timeout */ - else - return -3; /* Got an error from select */ - - bufcnt = read(desc, buf, BUFSIZ); - - if (bufcnt <= 0) - if (bufcnt == 0) - return EOF; /* 0 chars means end of file */ - else - return -3; /* Got an error from read */ - - bufcnt--; - bufp = buf; - return *bufp++; -} - -/* Translate baud rates from integers to damn B_codes. Unix should - have outgrown this crap years ago, but even POSIX wouldn't buck it. */ - -static struct -{ - int rate; - int code; -} baudtab[] = { - {50, B50}, - {75, B75}, - {110, B110}, - {134, B134}, - {150, B150}, - {200, B200}, - {300, B300}, - {600, B600}, - {1200, B1200}, - {1800, B1800}, - {2400, B2400}, - {4800, B4800}, - {9600, B9600}, - {19200, B19200}, - {38400, B38400}, - {-1, -1}, -}; - -static int -rate_to_code(rate) - int rate; -{ - int i; - - for (i = 0; baudtab[i].rate != -1; i++) - if (rate == baudtab[i].rate) - return baudtab[i].code; - - return -1; -} - -int -serial_setbaudrate(rate) - int rate; -{ - struct termios termios; - - if (tcgetattr(desc, &termios)) - error("tcgetattr failed: %s\n", safe_strerror(errno)); - - cfsetospeed(&termios, rate_to_code(rate)); - cfsetispeed(&termios, rate_to_code(rate)); - - if (tcsetattr(desc, TCSANOW, &termios)) - error("tcsetattr failed: %s\n", safe_strerror(errno)); - - return 1; -} - -int -serial_write(str, len) - const char *str; - int len; -{ - int cc; - - while (len > 0) - { - cc = write(desc, str, len); - - if (cc < 0) - return 0; - len -= cc; - str += cc; - } - return 1; -} - -void -serial_close() -{ - if (desc < 0) - return; - - serial_restore(desc, &oldstate); - - close(desc); - desc = -1; -} diff --git a/gdb/ser-unix.c b/gdb/ser-unix.c new file mode 100644 index 00000000000..541e4c21add --- /dev/null +++ b/gdb/ser-unix.c @@ -0,0 +1,324 @@ +/* Serial interface for local (hardwired) serial ports on Un*x like systems + Copyright 1992, 1993 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "defs.h" +#include "serial.h" +#include +#include +#include + +#if !defined (HAVE_TERMIOS) && !defined (HAVE_TERMIO) && !defined (HAVE_SGTTY) +#define HAVE_SGTTY +#endif + +#ifdef HAVE_TERMIOS +#include +#include +#endif +#ifdef HAVE_TERMIO +#include +#endif +#ifdef HAVE_SGTTY +#include +#endif + +/* Open up a real live device for serial I/O */ + +static int +hardwire_open(scb, name) + serial_t scb; + const char *name; +{ + scb->fd = open (name, O_RDWR); + if (scb->fd < 0) + return errno; + + return 0; +} + +static void +hardwire_raw(scb) + serial_t scb; +{ +#ifdef HAVE_TERMIOS + struct termios termios; + + if (tcgetattr(scb->fd, &termios)) + { + fprintf(stderr, "tcgetattr failed: %s\n", safe_strerror(errno)); + } + + termios.c_iflag = 0; + termios.c_oflag = 0; + termios.c_lflag = 0; + termios.c_cflag &= ~(CSIZE|PARENB); + termios.c_cflag |= CS8; + termios.c_cc[VMIN] = 0; + termios.c_cc[VTIME] = 0; + + if (tcsetattr(scb->fd, TCSANOW, &termios)) + { + fprintf(stderr, "tcsetattr failed: %s\n", safe_strerror(errno)); + } +#endif + +#ifdef HAVE_TERMIO + struct termio termio; + + if (ioctl (scb->fd, TCGETA, &termio)) + { + fprintf(stderr, "TCGETA failed: %s\n", safe_strerror(errno)); + } + + termio.c_iflag = 0; + termio.c_oflag = 0; + termio.c_lflag = 0; + termio.c_cflag &= ~(CSIZE|PARENB); + termio.c_cflag |= CS8; + termio.c_cc[VMIN] = 0; + termio.c_cc[VTIME] = 0; + + if (ioctl (scb->fd, TCSETA, &termio)) + { + fprintf(stderr, "TCSETA failed: %s\n", safe_strerror(errno)); + } +#endif + +#ifdef HAVE_SGTTY + struct sgttyb sgttyb; + + if (ioctl (scb->fd, TIOCGETP, &sgttyb)) + fprintf(stderr, "TIOCGETP failed: %s\n", safe_strerror(errno)); + + sgttyb.sg_flags |= RAW | ANYP; + sgttyb.sg_flags &= ~(CBREAK | ECHO); + + if (ioctl (scb->fd, TIOCSETP, &sgttyb)) + fprintf(stderr, "TIOCSETP failed: %s\n", safe_strerror(errno)); +#endif +} + +/* 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 +hardwire_readchar(scb, timeout) + serial_t scb; + int timeout; +{ + int numfds; + struct timeval tv; + fd_set readfds; + + if (scb->bufcnt-- > 0) + return *scb->bufp++; + + FD_ZERO (&readfds); + + tv.tv_sec = timeout; + tv.tv_usec = 0; + + FD_SET(scb->fd, &readfds); + + 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 -2; /* Timeout */ + else + return -3; /* Got an error from select */ + + scb->bufcnt = read(scb->fd, scb->buf, BUFSIZ); + + if (scb->bufcnt <= 0) + if (scb->bufcnt == 0) + return EOF; /* 0 chars means end of file */ + else + return -3; /* Got an error from read */ + + scb->bufcnt--; + scb->bufp = scb->buf; + return *scb->bufp++; +} + +#ifndef B19200 +#define B19200 EXTA +#endif + +#ifndef B38400 +#define B38400 EXTB +#endif + +/* Translate baud rates from integers to damn B_codes. Unix should + have outgrown this crap years ago, but even POSIX wouldn't buck it. */ + +static struct +{ + int rate; + int code; +} +baudtab[] = +{ + {50, B50}, + {75, B75}, + {110, B110}, + {134, B134}, + {150, B150}, + {200, B200}, + {300, B300}, + {600, B600}, + {1200, B1200}, + {1800, B1800}, + {2400, B2400}, + {4800, B4800}, + {9600, B9600}, + {19200, B19200}, + {38400, B38400}, + {-1, -1}, +}; + +static int +rate_to_code(rate) + int rate; +{ + int i; + + for (i = 0; baudtab[i].rate != -1; i++) + if (rate == baudtab[i].rate) + return baudtab[i].code; + + return -1; +} + +static int +hardwire_setbaudrate(scb, rate) + serial_t scb; + int rate; +{ +#ifdef HAVE_TERMIOS + struct termios termios; + + if (tcgetattr (scb->fd, &termios)) + error("hardwire_setbaudrate: tcgetattr failed: %s\n", safe_strerror(errno)); + + cfsetospeed (&termios, rate_to_code (rate)); + cfsetispeed (&termios, rate_to_code (rate)); + + if (tcsetattr (scb->fd, TCSANOW, &termios)) + error ("hardwire_setbaudrate: tcsetattr failed: %s\n", safe_strerror(errno)); + + return 1; +#endif + +#ifdef HAVE_TERMIO + struct termio termio; + + if (ioctl (scb->fd, TCGETA, &termio)) + { + fprintf(stderr, "TCGETA failed: %s\n", safe_strerror(errno)); + } + +#ifndef CIBAUD +#define CIBAUD CBAUD +#endif + + termio.c_cflag &= ~(CBAUD | CIBAUD); + termio.c_cflag |= rate_to_code (rate); + + if (ioctl (scb->fd, TCSETA, &termio)) + { + fprintf(stderr, "TCSETA failed: %s\n", safe_strerror(errno)); + } +#endif + +#ifdef HAVE_SGTTY + struct sgttyb sgttyb; + + if (ioctl (scb->fd, TIOCGETP, &sgttyb)) + fprintf (stderr, "TIOCGETP failed: %s\n", safe_strerror (errno)); + + sgttyb.sg_ispeed = rate_to_code (rate); + sgttyb.sg_ospeed = rate_to_code (rate); + + if (ioctl (scb->fd, TIOCSETP, &sgttyb)) + fprintf (stderr, "TIOCSETP failed: %s\n", safe_strerror (errno)); +#endif +} + +static int +hardwire_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 +hardwire_restore(scb) + serial_t scb; +{ +} + +static void +hardwire_close(scb) + serial_t scb; +{ + if (scb->fd < 0) + return; + + SERIAL_RESTORE(scb); + + close(scb->fd); + scb->fd = -1; +} + +static struct serial_ops hardwire_ops = +{ + "hardwire", + 0, + hardwire_open, + hardwire_close, + hardwire_readchar, + hardwire_write, + hardwire_raw, + hardwire_restore, + hardwire_setbaudrate +}; + +_initialize_ser_hardwire () +{ + serial_add_interface (&hardwire_ops); +} diff --git a/gdb/serial.c b/gdb/serial.c new file mode 100644 index 00000000000..5a4fcf42398 --- /dev/null +++ b/gdb/serial.c @@ -0,0 +1,181 @@ +/* Generic serial interface routines + Copyright 1992, 1993 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "defs.h" +#include "serial.h" + +/* Open up a device or a network socket, depending upon the syntax of NAME. */ + +static struct serial_ops *serial_ops_list = NULL; + +static struct serial_ops * +serial_interface_lookup (name) + char *name; +{ + struct serial_ops *ops; + + for (ops = serial_ops_list; ops; ops = ops->next) + if (strcmp (name, ops->name) == 0) + return ops; + + return NULL; +} + +void +serial_add_interface(optable) + struct serial_ops *optable; +{ + optable->next = serial_ops_list; + serial_ops_list = optable; +} + +serial_t +serial_open(name) + const char *name; +{ + serial_t scb; + struct serial_ops *ops; + + ops = serial_interface_lookup ("hardwire"); + + if (!ops) + return NULL; + + scb = (serial_t)xmalloc (sizeof (struct _serial_t)); + + scb->ops = ops; + + scb->bufcnt = 0; + scb->bufp = scb->buf; + + if (SERIAL_OPEN (scb, name)) + { + free (scb); + return NULL; + } + + return scb; +} + +#if 0 +/* Connect the user directly to the remote system. This command acts just like + the 'cu' or 'tip' command. Use ~. or ~^D to break out. */ + +static void +cleanup_tty(ttystate) + struct ttystate ttystate; +{ + printf("\r\n[Exiting connect mode]\r\n"); + serial_restore(0, &ttystate); +} + +static void +connect_command (args, fromtty) + char *args; + int fromtty; +{ + fd_set readfds; + int numfds; + int c; + char cur_esc = 0; + static struct ttystate ttystate; + + dont_repeat(); + + if (desc < 0) + error("target not open."); + + if (args) + fprintf("This command takes no args. They have been ignored.\n"); + + printf("[Entering connect mode. Use ~. or ~^D to escape]\n"); + + serial_raw(0, &ttystate); + + make_cleanup(cleanup_tty, &ttystate); + + FD_ZERO(&readfds); + + while (1) + { + do + { + FD_SET(0, &readfds); + FD_SET(desc, &readfds); + numfds = select(sizeof(readfds)*8, &readfds, 0, 0, 0); + } + while (numfds == 0); + + if (numfds < 0) + perror_with_name("select"); + + if (FD_ISSET(0, &readfds)) + { /* tty input, send to stdebug */ + char cx; + + c = serial_readchar(-1); + if (c < 0) + perror_with_name("connect"); + + cx = c; + serial_write(&cx, 1); + switch (cur_esc) + { + case 0: + if (c == '\r') + cur_esc = c; + break; + case '\r': + if (c == '~') + cur_esc = c; + else + cur_esc = 0; + break; + case '~': + if (c == '.' || c == '\004') + return; + else + cur_esc = 0; + } + } + + if (FD_ISSET(desc, &readfds)) + { + while (1) + { + c = serial_readchar(-1); + if (c < 0) + break; + putchar(c); + } + fflush(stdout); + } + } +} +#endif + +#if 0 +void +_initialize_serial () +{ + add_com ("connect", class_obscure, connect_command, + "Connect the terminal directly up to the command monitor.\n\ +Use ~. or ~^D to break out."); +} +#endif diff --git a/gdb/serial.h b/gdb/serial.h index 147873c51f2..767a91b3161 100644 --- a/gdb/serial.h +++ b/gdb/serial.h @@ -17,75 +17,70 @@ 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#ifdef __GO32__ +/* Terminal state pointer. This is specific to each type of interface. */ -/* Then you use the asynctsr */ +typedef PTR ttystate; -struct ttystate { - /* No members */ +struct _serial_t +{ + int fd; + struct serial_ops *ops; + ttystate ttystate; + int bufcnt; + unsigned char *bufp; + unsigned char buf[BUFSIZ]; }; -#else -#ifdef HAVE_TERMIO - -#include -#include - -struct ttystate -{ - int flags; /* Flags from fcntl F_GETFL */ - struct termios termios; /* old tty driver settings */ +typedef struct _serial_t *serial_t; + +struct serial_ops { + char *name; + struct serial_ops *next; + int (*open) PARAMS ((serial_t, const char *name)); + void (*close) PARAMS ((serial_t)); + int (*readchar) PARAMS ((serial_t, int timeout)); + int (*write) PARAMS ((serial_t, const char *str, int len)); + void (*go_raw) PARAMS ((serial_t)); + void (*restore) PARAMS ((serial_t)); + int (*setbaudrate) PARAMS ((serial_t, int rate)); }; -#else /* not HAVE_TERMIO */ +/* Add a new serial interface to the interface list */ -#include +void serial_add_interface PARAMS ((struct serial_ops *optable)); -struct ttystate { - int flags; /* Flags from fcntl F_GETFL */ - struct sgttyb sgttyb; /* old tty driver settings */ -}; +/* Try to open the serial device "name", returns a serial_t if ok, NULL if not. + */ -#endif /* not HAVE_TERMIO */ -#endif -/* Return a sensible default name for a serial device, something which - can be used as an argument to serial_open. */ - -const char *serial_default_name PARAMS ((void)); +serial_t serial_open PARAMS ((const char *name)); -/* Try to open the serial device "name", return 1 if ok, 0 if not. */ +/* Internal open routine for specific I/O interface */ -int serial_open PARAMS ((const char *name)); +#define SERIAL_OPEN(SERIAL_T, NAME) (SERIAL_T)->ops->open((SERIAL_T), NAME) /* Turn the port into raw mode. */ -void serial_raw PARAMS ((int fd, struct ttystate *oldstate)); - -/* Turn the port into normal mode. */ - -void serial_normal PARAMS ((void)); +#define SERIAL_RAW(SERIAL_T) (SERIAL_T)->ops->go_raw((SERIAL_T)) /* Read one char from the serial device with -second timeout. Returns char if ok, else EOF, -2 for timeout, -3 for anything else */ -int serial_readchar PARAMS ((int to)); - -/* Set the baudrate to the decimal value supplied, and return 1, or fail and - return 0. */ +#define SERIAL_READCHAR(SERIAL_T, TIMEOUT) ((SERIAL_T)->ops->readchar((SERIAL_T), TIMEOUT)) -int serial_setbaudrate PARAMS ((int rate)); +/* Set the baudrate to the decimal value supplied. Return 1 on failure, + 0 otherwise. */ -/* Return the next rate in the sequence, or return 0 for failure. */ +#define SERIAL_SETBAUDRATE(SERIAL_T, RATE) ((SERIAL_T)->ops->setbaudrate((SERIAL_T), RATE)) /* Write some chars to the device, returns 0 for failure. See errno for details. */ -int serial_write PARAMS ((const char *str, int len)); +#define SERIAL_WRITE(SERIAL_T, STRING, LEN) ((SERIAL_T)->ops->write((SERIAL_T), STRING, LEN)) /* Close the serial port */ -void serial_close PARAMS ((void)); +#define SERIAL_CLOSE(SERIAL_T) (SERIAL_T)->ops->close((SERIAL_T)) /* Restore the serial port to the state saved in oldstate */ -void serial_restore PARAMS ((int desc, struct ttystate *oldstate)); +#define SERIAL_RESTORE(SERIAL_T) (SERIAL_T)->ops->restore((SERIAL_T)) -- 2.30.2