mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-27 03:51:15 +08:00
* 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.
This commit is contained in:
parent
9acdb2dc82
commit
4e772f4426
@ -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.
|
||||
|
@ -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
|
||||
|
||||
|
3
gdb/config/i386/go32.mh
Normal file
3
gdb/config/i386/go32.mh
Normal file
@ -0,0 +1,3 @@
|
||||
MH_CFLAGS=-D__GO32__ -D__MSDOS__
|
||||
XDEPFILES= go32-xdep.o
|
||||
XM_FILE= xm-go32.h
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
226
gdb/ser-bsd.c
226
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 <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <fcntl.h>
|
||||
#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;
|
||||
}
|
@ -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 <fcntl.h>
|
||||
#include <sys/time.h>
|
||||
#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;
|
||||
}
|
324
gdb/ser-unix.c
Normal file
324
gdb/ser-unix.c
Normal file
@ -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 <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#if !defined (HAVE_TERMIOS) && !defined (HAVE_TERMIO) && !defined (HAVE_SGTTY)
|
||||
#define HAVE_SGTTY
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TERMIOS
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_TERMIO
|
||||
#include <sys/termio.h>
|
||||
#endif
|
||||
#ifdef HAVE_SGTTY
|
||||
#include <sgtty.h>
|
||||
#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);
|
||||
}
|
181
gdb/serial.c
Normal file
181
gdb/serial.c
Normal file
@ -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 <CR>~. or <CR>~^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 <CR>~. or <CR>~^D to break out.");
|
||||
}
|
||||
#endif
|
81
gdb/serial.h
81
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 */
|
||||
};
|
||||
|
||||
#else
|
||||
#ifdef HAVE_TERMIO
|
||||
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
struct ttystate
|
||||
struct _serial_t
|
||||
{
|
||||
int flags; /* Flags from fcntl F_GETFL */
|
||||
struct termios termios; /* old tty driver settings */
|
||||
int fd;
|
||||
struct serial_ops *ops;
|
||||
ttystate ttystate;
|
||||
int bufcnt;
|
||||
unsigned char *bufp;
|
||||
unsigned char buf[BUFSIZ];
|
||||
};
|
||||
|
||||
#else /* not HAVE_TERMIO */
|
||||
typedef struct _serial_t *serial_t;
|
||||
|
||||
#include <sgtty.h>
|
||||
|
||||
struct ttystate {
|
||||
int flags; /* Flags from fcntl F_GETFL */
|
||||
struct sgttyb sgttyb; /* old tty driver settings */
|
||||
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));
|
||||
};
|
||||
|
||||
#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));
|
||||
/* Add a new serial interface to the interface list */
|
||||
|
||||
/* Try to open the serial device "name", return 1 if ok, 0 if not. */
|
||||
void serial_add_interface PARAMS ((struct serial_ops *optable));
|
||||
|
||||
int serial_open PARAMS ((const char *name));
|
||||
/* Try to open the serial device "name", returns a serial_t if ok, NULL if not.
|
||||
*/
|
||||
|
||||
serial_t serial_open PARAMS ((const char *name));
|
||||
|
||||
/* Internal open routine for specific I/O interface */
|
||||
|
||||
#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 <TO>-second timeout.
|
||||
Returns char if ok, else EOF, -2 for timeout, -3 for anything else */
|
||||
|
||||
int serial_readchar PARAMS ((int to));
|
||||
#define SERIAL_READCHAR(SERIAL_T, TIMEOUT) ((SERIAL_T)->ops->readchar((SERIAL_T), TIMEOUT))
|
||||
|
||||
/* Set the baudrate to the decimal value supplied, and return 1, or fail and
|
||||
return 0. */
|
||||
/* Set the baudrate to the decimal value supplied. Return 1 on failure,
|
||||
0 otherwise. */
|
||||
|
||||
int serial_setbaudrate PARAMS ((int rate));
|
||||
|
||||
/* 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))
|
||||
|
Loading…
Reference in New Issue
Block a user