* Makefile.in: Add new file ser-tcp.c.
* defs.h (memcmp): Add decl for memcmp to #ifndef MEM_FNS_DECLARED. * findvar.c (write_register): See if we are writing back the same value that's already in the register. If so, don't bother. * remote.c (putpkt, getpkt): Improve handling of communication problems. * ser-go32.c: Prototype it to death. Update serial_ops and add dummy routines where appropriate. * ser-tcp.c: New module to implement serial I/O via TCP connections. * ser-unix.c: Clean up getting/setting of tty state. Get rid of SERIAL_RESTORE, add SERIAL_{GET|SET}_TTY_STATE interfaces. * serial.c: Add start of support for connect command. (serial_open): Distinguish between tcp and local devices. * serial.h (struct serial_ops): Get rid of restore, add get_tty_state and set_tty_state. Define protoypes and macros for this mess. * gdbserver/remote-utils.c: Add tcp support. (readchar): Do some real buffering. Handle error conditions gracefully. * gdbserver/remote-inflow-sparc.c: Update to remote-inflow.c (Lynx), remove lots of cruft.
This commit is contained in:
parent
633c8b0a9d
commit
38dc5e123f
10 changed files with 740 additions and 357 deletions
|
@ -1,3 +1,27 @@
|
||||||
|
Fri May 28 17:18:05 1993 Stu Grossman (grossman@cygnus.com)
|
||||||
|
|
||||||
|
* Makefile.in: Add new file ser-tcp.c.
|
||||||
|
* defs.h (memcmp): Add decl for memcmp to #ifndef MEM_FNS_DECLARED.
|
||||||
|
* findvar.c (write_register): See if we are writing back the same
|
||||||
|
value that's already in the register. If so, don't bother.
|
||||||
|
* remote.c (putpkt, getpkt): Improve handling of communication
|
||||||
|
problems.
|
||||||
|
* ser-go32.c: Prototype it to death. Update serial_ops and add
|
||||||
|
dummy routines where appropriate.
|
||||||
|
* ser-tcp.c: New module to implement serial I/O via TCP
|
||||||
|
connections.
|
||||||
|
* ser-unix.c: Clean up getting/setting of tty state. Get rid of
|
||||||
|
SERIAL_RESTORE, add SERIAL_{GET|SET}_TTY_STATE interfaces.
|
||||||
|
* serial.c: Add start of support for connect command.
|
||||||
|
(serial_open): Distinguish between tcp and local devices.
|
||||||
|
* serial.h (struct serial_ops): Get rid of restore, add
|
||||||
|
get_tty_state and set_tty_state. Define protoypes and macros for
|
||||||
|
this mess.
|
||||||
|
* gdbserver/remote-utils.c: Add tcp support. (readchar): Do
|
||||||
|
some real buffering. Handle error conditions gracefully.
|
||||||
|
* gdbserver/remote-inflow-sparc.c: Update to remote-inflow.c
|
||||||
|
(Lynx), remove lots of cruft.
|
||||||
|
|
||||||
Fri May 28 17:24:51 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
|
Fri May 28 17:24:51 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
|
||||||
|
|
||||||
* printcmd.c (print_address_symbolic): turn this into an assigment
|
* printcmd.c (print_address_symbolic): turn this into an assigment
|
||||||
|
|
|
@ -185,7 +185,7 @@ RUNTESTFLAGS=
|
||||||
# part of libiberty) a POSIX interface. But at least for now the
|
# part of libiberty) a POSIX interface. But at least for now the
|
||||||
# host-dependent makefile fragment might need to use something else
|
# host-dependent makefile fragment might need to use something else
|
||||||
# besides ser-unix.o
|
# besides ser-unix.o
|
||||||
SER_HARDWIRE=ser-unix.o
|
SER_HARDWIRE=ser-unix.o ser-tcp.o
|
||||||
|
|
||||||
# Host and target-dependent makefile fragments come in here.
|
# Host and target-dependent makefile fragments come in here.
|
||||||
####
|
####
|
||||||
|
@ -304,7 +304,7 @@ SFILES = ${srcdir}/blockframe.c ${srcdir}/breakpoint.c ${srcdir}/buildsym.c \
|
||||||
${srcdir}/target.c ${srcdir}/typeprint.c ${srcdir}/utils.c \
|
${srcdir}/target.c ${srcdir}/typeprint.c ${srcdir}/utils.c \
|
||||||
${srcdir}/valarith.c \
|
${srcdir}/valarith.c \
|
||||||
${srcdir}/valops.c ${srcdir}/valprint.c ${srcdir}/values.c \
|
${srcdir}/valops.c ${srcdir}/valprint.c ${srcdir}/values.c \
|
||||||
${srcdir}/serial.c ${srcdir}/ser-unix.c
|
${srcdir}/serial.c ${srcdir}/ser-unix.c ${srcdir}/ser-tcp.c
|
||||||
|
|
||||||
# Files that are not source code, but need to go into gdb-$(VERSION).tar.Z.
|
# Files that are not source code, but need to go into gdb-$(VERSION).tar.Z.
|
||||||
NONSRC = ${srcdir}/Makefile.in ${srcdir}/depend ${srcdir}/alldeps.mak \
|
NONSRC = ${srcdir}/Makefile.in ${srcdir}/depend ${srcdir}/alldeps.mak \
|
||||||
|
|
21
gdb/defs.h
21
gdb/defs.h
|
@ -434,20 +434,23 @@ enum val_prettyprint
|
||||||
/* Defaults for system-wide constants (if not defined by xm.h, we fake it). */
|
/* Defaults for system-wide constants (if not defined by xm.h, we fake it). */
|
||||||
|
|
||||||
#if !defined (UINT_MAX)
|
#if !defined (UINT_MAX)
|
||||||
#define UINT_MAX 0xffffffff
|
#define UINT_MAX ((unsigned int)(~0)) /* 0xFFFFFFFF for 32-bits */
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined (LONG_MAX)
|
|
||||||
#define LONG_MAX 0x7fffffff
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined (INT_MAX)
|
#if !defined (INT_MAX)
|
||||||
#define INT_MAX 0x7fffffff
|
#define INT_MAX (UINT_MAX >> 1) /* 0x7FFFFFFF for 32-bits */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined (INT_MIN)
|
#if !defined (INT_MIN)
|
||||||
/* Two's complement, 32 bit. */
|
#define INT_MIN (-INT_MAX - 1) /* 0x80000000 for 32-bits */
|
||||||
#define INT_MIN -0x80000000
|
#endif
|
||||||
|
|
||||||
|
#if !defined (ULONG_MAX)
|
||||||
|
#define ULONG_MAX ((unsigned long)(~0L)) /* 0xFFFFFFFF for 32-bits */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined (LONG_MAX)
|
||||||
|
#define LONG_MAX ((long)(ULONG_MAX >> 1)) /* 0x7FFFFFFF for 32-bits */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Number of bits in a char or unsigned char for the target machine.
|
/* Number of bits in a char or unsigned char for the target machine.
|
||||||
|
@ -722,10 +725,10 @@ qsort PARAMS ((void *base, size_t nmemb, /* 4.10.5.2 */
|
||||||
#ifndef MEM_FNS_DECLARED /* Some non-ANSI use void *, not char *. */
|
#ifndef MEM_FNS_DECLARED /* Some non-ANSI use void *, not char *. */
|
||||||
extern PTR
|
extern PTR
|
||||||
memcpy PARAMS ((void *, const void *, size_t)); /* 4.11.2.1 */
|
memcpy PARAMS ((void *, const void *, size_t)); /* 4.11.2.1 */
|
||||||
#endif
|
|
||||||
|
|
||||||
extern int
|
extern int
|
||||||
memcmp PARAMS ((const void *, const void *, size_t)); /* 4.11.4.1 */
|
memcmp PARAMS ((const void *, const void *, size_t)); /* 4.11.4.1 */
|
||||||
|
#endif
|
||||||
|
|
||||||
extern char *
|
extern char *
|
||||||
strchr PARAMS ((const char *, int)); /* 4.11.5.2 */
|
strchr PARAMS ((const char *, int)); /* 4.11.5.2 */
|
||||||
|
|
|
@ -1,9 +1,24 @@
|
||||||
/* Low level interface to ptrace, for GDB when running under Unix.
|
/* Low level interface to ptrace, for the remote server for GDB.
|
||||||
Copyright (C) 1986, 1987 Free Software Foundation, Inc.
|
Copyright (C) 1986, 1987, 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 "defs.h"
|
||||||
#include "wait.h"
|
#include "/usr/include/sys/wait.h"
|
||||||
#include "frame.h"
|
#include "frame.h"
|
||||||
#include "inferior.h"
|
#include "inferior.h"
|
||||||
/***************************
|
/***************************
|
||||||
|
@ -38,12 +53,6 @@ extern int errno;
|
||||||
extern int inferior_pid;
|
extern int inferior_pid;
|
||||||
void error (), quit (), perror_with_name ();
|
void error (), quit (), perror_with_name ();
|
||||||
int query ();
|
int query ();
|
||||||
void supply_register (), write_register ();
|
|
||||||
CORE_ADDR read_register ();
|
|
||||||
|
|
||||||
/* Nonzero if we are debugging an attached outside process
|
|
||||||
rather than an inferior. */
|
|
||||||
|
|
||||||
|
|
||||||
/* Start an inferior process and returns its pid.
|
/* Start an inferior process and returns its pid.
|
||||||
ALLARGS is a vector of program-name and args.
|
ALLARGS is a vector of program-name and args.
|
||||||
|
@ -101,52 +110,52 @@ kill_inferior ()
|
||||||
/*************inferior_died ();****VK**************/
|
/*************inferior_died ();****VK**************/
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Resume execution of the inferior process.
|
/* Wait for process, returns status */
|
||||||
If STEP is nonzero, single-step it.
|
|
||||||
If SIGNAL is nonzero, give it that signal. */
|
|
||||||
|
|
||||||
unsigned char
|
unsigned char
|
||||||
myresume (step, signal, status)
|
mywait (status)
|
||||||
int step;
|
|
||||||
int signal;
|
|
||||||
char *status;
|
char *status;
|
||||||
{
|
{
|
||||||
int pid;
|
int pid;
|
||||||
WAITTYPE w;
|
union wait w;
|
||||||
|
|
||||||
errno = 0;
|
|
||||||
ptrace (step ? 9 : 7, inferior_pid, 1, signal);
|
|
||||||
if (errno)
|
|
||||||
perror_with_name ("ptrace");
|
|
||||||
pid = wait (&w);
|
pid = wait (&w);
|
||||||
if (pid != inferior_pid)
|
if (pid != inferior_pid)
|
||||||
perror_with_name ("wait");
|
perror_with_name ("wait");
|
||||||
|
|
||||||
fetch_inferior_registers (0);
|
|
||||||
|
|
||||||
if (WIFEXITED (w))
|
if (WIFEXITED (w))
|
||||||
{
|
{
|
||||||
printf ("\nChild exited with retcode = %x \n", WEXITSTATUS (w));
|
fprintf (stderr, "\nChild exited with retcode = %x \n", WEXITSTATUS (w));
|
||||||
*status = 'E';
|
*status = 'E';
|
||||||
return ((unsigned char) WEXITSTATUS (w));
|
return ((unsigned char) WEXITSTATUS (w));
|
||||||
}
|
}
|
||||||
else if (!WIFSTOPPED (w))
|
else if (!WIFSTOPPED (w))
|
||||||
{
|
{
|
||||||
printf ("\nChild terminated with signal = %x \n", WTERMSIG (w));
|
fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w));
|
||||||
*status = 'T';
|
*status = 'T';
|
||||||
return ((unsigned char) WTERMSIG (w));
|
return ((unsigned char) WTERMSIG (w));
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
fetch_inferior_registers (0);
|
||||||
printf ("\nChild stopped with signal = %x \n", WSTOPSIG (w));
|
|
||||||
*status = 'S';
|
*status = 'S';
|
||||||
return ((unsigned char) WSTOPSIG (w));
|
return ((unsigned char) WSTOPSIG (w));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define INT_REGS 1
|
/* Resume execution of the inferior process.
|
||||||
#define STACK_REGS 2
|
If STEP is nonzero, single-step it.
|
||||||
#define FP_REGS 4
|
If SIGNAL is nonzero, give it that signal. */
|
||||||
|
|
||||||
|
void
|
||||||
|
myresume (step, signal)
|
||||||
|
int step;
|
||||||
|
int signal;
|
||||||
|
{
|
||||||
|
errno = 0;
|
||||||
|
ptrace (step ? PTRACE_SINGLESTEP : PTRACE_CONT, inferior_pid, 1, signal);
|
||||||
|
if (errno)
|
||||||
|
perror_with_name ("ptrace");
|
||||||
|
}
|
||||||
|
|
||||||
/* Fetch one or more registers from the inferior. REGNO == -1 to get
|
/* Fetch one or more registers from the inferior. REGNO == -1 to get
|
||||||
them all. We actually fetch more than requested, when convenient,
|
them all. We actually fetch more than requested, when convenient,
|
||||||
|
@ -234,63 +243,6 @@ store_inferior_registers (ignored)
|
||||||
perror("ptrace_setfpregs");
|
perror("ptrace_setfpregs");
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
void
|
|
||||||
fetch_inferior_registers ()
|
|
||||||
{
|
|
||||||
struct regs inferior_registers;
|
|
||||||
struct fp_status inferior_fp_registers;
|
|
||||||
extern char registers[];
|
|
||||||
|
|
||||||
ptrace (PTRACE_GETREGS, inferior_pid, &inferior_registers);
|
|
||||||
if (errno)
|
|
||||||
perror_with_name ("ptrace");
|
|
||||||
/**********debugging begin **********/
|
|
||||||
print_some_registers (&inferior_registers);
|
|
||||||
/**********debugging end **********/
|
|
||||||
ptrace (PTRACE_GETFPREGS, inferior_pid, &inferior_fp_registers);
|
|
||||||
if (errno)
|
|
||||||
perror_with_name ("ptrace");
|
|
||||||
|
|
||||||
bcopy (&inferior_registers, registers, 16 * 4);
|
|
||||||
bcopy (&inferior_fp_registers, ®isters[REGISTER_BYTE (FP0_REGNUM)],
|
|
||||||
sizeof inferior_fp_registers.fpu_regs);
|
|
||||||
*(int *) ®isters[REGISTER_BYTE (PS_REGNUM)] = inferior_registers.r_ps;
|
|
||||||
*(int *) ®isters[REGISTER_BYTE (PC_REGNUM)] = inferior_registers.r_pc;
|
|
||||||
bcopy (&inferior_fp_registers.fpu_flags,
|
|
||||||
®isters[REGISTER_BYTE (FPC_REGNUM)],
|
|
||||||
sizeof inferior_fp_registers - sizeof inferior_fp_registers.fpu_regs);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Store our register values back into the inferior.
|
|
||||||
If REGNO is -1, do this for all registers.
|
|
||||||
Otherwise, REGNO specifies which register (so we can save time). */
|
|
||||||
|
|
||||||
store_inferior_registers (regno)
|
|
||||||
int regno;
|
|
||||||
{
|
|
||||||
struct regs inferior_registers;
|
|
||||||
struct fp_status inferior_fp_registers;
|
|
||||||
extern char registers[];
|
|
||||||
|
|
||||||
bcopy (registers, &inferior_registers, 16 * 4);
|
|
||||||
bcopy (®isters[REGISTER_BYTE (FP0_REGNUM)], &inferior_fp_registers,
|
|
||||||
sizeof inferior_fp_registers.fps_regs);
|
|
||||||
inferior_registers.r_ps = *(int *) ®isters[REGISTER_BYTE (PS_REGNUM)];
|
|
||||||
inferior_registers.r_pc = *(int *) ®isters[REGISTER_BYTE (PC_REGNUM)];
|
|
||||||
bcopy (®isters[REGISTER_BYTE (FPC_REGNUM)],
|
|
||||||
&inferior_fp_registers.fps_control,
|
|
||||||
sizeof inferior_fp_registers - sizeof inferior_fp_registers.fps_regs);
|
|
||||||
|
|
||||||
ptrace (PTRACE_SETREGS, inferior_pid, &inferior_registers);
|
|
||||||
if (errno)
|
|
||||||
perror_with_name ("ptrace");
|
|
||||||
ptrace (PTRACE_SETFPREGS, inferior_pid, &inferior_fp_registers);
|
|
||||||
if (errno)
|
|
||||||
perror_with_name ("ptrace");
|
|
||||||
}
|
|
||||||
#endif /* 0 */
|
|
||||||
|
|
||||||
/* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
|
/* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
|
||||||
in the NEW_SUN_PTRACE case.
|
in the NEW_SUN_PTRACE case.
|
||||||
It ought to be straightforward. But it appears that writing did
|
It ought to be straightforward. But it appears that writing did
|
||||||
|
@ -373,79 +325,14 @@ write_inferior_memory (memaddr, myaddr, len)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
try_writing_regs_command ()
|
|
||||||
{
|
|
||||||
register int i;
|
|
||||||
register int val;
|
|
||||||
|
|
||||||
if (inferior_pid == 0)
|
|
||||||
error ("There is no inferior process now.");
|
|
||||||
|
|
||||||
fetch_inferior_registers (0);
|
|
||||||
for (i = 0; i < 18; i++)
|
|
||||||
{
|
|
||||||
QUIT;
|
|
||||||
errno = 0;
|
|
||||||
val = read_register (i);
|
|
||||||
write_register (i, val);
|
|
||||||
if (errno == 0)
|
|
||||||
{
|
|
||||||
printf (" Succeeded with register %d; value 0x%x (%d).\n",
|
|
||||||
i, val, val);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
printf (" Failed with register %d.\n", i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
initialize ()
|
initialize ()
|
||||||
{
|
{
|
||||||
|
|
||||||
inferior_pid = 0;
|
inferior_pid = 0;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Return the contents of register REGNO,
|
|
||||||
regarding it as an integer. */
|
|
||||||
|
|
||||||
CORE_ADDR
|
|
||||||
read_register (regno)
|
|
||||||
int regno;
|
|
||||||
{
|
|
||||||
/* This loses when REGISTER_RAW_SIZE (regno) != sizeof (int) */
|
|
||||||
return *(int *) ®isters[REGISTER_BYTE (regno)];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Store VALUE in the register number REGNO, regarded as an integer. */
|
|
||||||
|
|
||||||
void
|
|
||||||
write_register (regno, val)
|
|
||||||
int regno, val;
|
|
||||||
{
|
|
||||||
/* This loses when REGISTER_RAW_SIZE (regno) != sizeof (int) */
|
|
||||||
*(int *) ®isters[REGISTER_BYTE (regno)] = val;
|
|
||||||
|
|
||||||
if (have_inferior_p ())
|
|
||||||
store_inferior_registers (regno);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
have_inferior_p ()
|
have_inferior_p ()
|
||||||
{
|
{
|
||||||
return inferior_pid != 0;
|
return inferior_pid != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
print_some_registers (regs)
|
|
||||||
int regs[];
|
|
||||||
{
|
|
||||||
register int i;
|
|
||||||
for (i = 0; i < 18; i++)
|
|
||||||
{
|
|
||||||
printf ("reg[%d] = %x\n", i, regs[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -25,10 +25,15 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
#include <a.out.h>
|
#include <a.out.h>
|
||||||
#include <sys/file.h>
|
#include <sys/file.h>
|
||||||
#include <sgtty.h>
|
#include <sgtty.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <netinet/tcp.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
extern int remote_desc;
|
extern int remote_desc;
|
||||||
extern int remote_debugging;
|
extern int remote_debugging;
|
||||||
extern int kiodebug;
|
|
||||||
|
|
||||||
void remote_open ();
|
void remote_open ();
|
||||||
void remote_send ();
|
void remote_send ();
|
||||||
|
@ -53,13 +58,56 @@ remote_open (name, from_tty)
|
||||||
|
|
||||||
remote_debugging = 0;
|
remote_debugging = 0;
|
||||||
|
|
||||||
remote_desc = open (name, O_RDWR);
|
if (!strchr (name, ':'))
|
||||||
if (remote_desc < 0)
|
{
|
||||||
perror_with_name ("Could not open remote device");
|
remote_desc = open (name, O_RDWR);
|
||||||
|
if (remote_desc < 0)
|
||||||
|
perror_with_name ("Could not open remote device");
|
||||||
|
|
||||||
ioctl (remote_desc, TIOCGETP, &sg);
|
ioctl (remote_desc, TIOCGETP, &sg);
|
||||||
sg.sg_flags = RAW;
|
sg.sg_flags = RAW;
|
||||||
ioctl (remote_desc, TIOCSETP, &sg);
|
ioctl (remote_desc, TIOCSETP, &sg);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char *port_str;
|
||||||
|
int port;
|
||||||
|
struct sockaddr_in sockaddr;
|
||||||
|
int tmp;
|
||||||
|
|
||||||
|
port_str = strchr (name, ':');
|
||||||
|
|
||||||
|
port = atoi (port_str + 1);
|
||||||
|
|
||||||
|
remote_desc = socket (PF_INET, SOCK_STREAM, 0);
|
||||||
|
if (remote_desc < 0)
|
||||||
|
perror_with_name ("Can't open socket");
|
||||||
|
|
||||||
|
/* Allow rapid reuse of this port. */
|
||||||
|
tmp = 1;
|
||||||
|
setsockopt (remote_desc, SOL_SOCKET, SO_REUSEADDR, (char *)&tmp,
|
||||||
|
sizeof(tmp));
|
||||||
|
|
||||||
|
/* Enable TCP keep alive process. */
|
||||||
|
tmp = 1;
|
||||||
|
setsockopt (remote_desc, SOL_SOCKET, SO_KEEPALIVE, (char *)&tmp, sizeof(tmp));
|
||||||
|
|
||||||
|
sockaddr.sin_family = PF_INET;
|
||||||
|
sockaddr.sin_port = htons(port);
|
||||||
|
sockaddr.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
|
||||||
|
if (bind (remote_desc, &sockaddr, sizeof (sockaddr))
|
||||||
|
|| listen (remote_desc, 1))
|
||||||
|
perror_with_name ("Can't bind address");
|
||||||
|
|
||||||
|
tmp = sizeof (sockaddr);
|
||||||
|
remote_desc = accept (remote_desc, &sockaddr, &tmp);
|
||||||
|
if (remote_desc == -1)
|
||||||
|
perror_with_name ("Accept failed");
|
||||||
|
|
||||||
|
tmp = 1;
|
||||||
|
setsockopt (remote_desc, 6, TCP_NODELAY, (char *)&tmp, sizeof(tmp));
|
||||||
|
}
|
||||||
|
|
||||||
fprintf (stderr, "Remote debugging using %s\n", name);
|
fprintf (stderr, "Remote debugging using %s\n", name);
|
||||||
remote_debugging = 1;
|
remote_debugging = 1;
|
||||||
|
@ -148,9 +196,24 @@ putpkt (buf)
|
||||||
static int
|
static int
|
||||||
readchar ()
|
readchar ()
|
||||||
{
|
{
|
||||||
char buf[1];
|
static char buf[BUFSIZ];
|
||||||
while (read (remote_desc, buf, 1) != 1);
|
static int bufcnt = 0;
|
||||||
return buf[0] & 0x7f;
|
static char *bufp;
|
||||||
|
|
||||||
|
if (bufcnt-- > 0)
|
||||||
|
return *bufp++ & 0x7f;
|
||||||
|
|
||||||
|
bufcnt = read (remote_desc, buf, sizeof (buf));
|
||||||
|
|
||||||
|
if (bufcnt <= 0)
|
||||||
|
{
|
||||||
|
perror ("readchar");
|
||||||
|
fatal ("read error, quitting");
|
||||||
|
}
|
||||||
|
|
||||||
|
bufp = buf;
|
||||||
|
bufcnt--;
|
||||||
|
return *bufp++ & 0x7f;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read a packet from the remote machine, with error checking,
|
/* Read a packet from the remote machine, with error checking,
|
||||||
|
@ -161,12 +224,13 @@ getpkt (buf)
|
||||||
char *buf;
|
char *buf;
|
||||||
{
|
{
|
||||||
char *bp;
|
char *bp;
|
||||||
unsigned char csum, c, c1, c2;
|
unsigned char csum, c1, c2;
|
||||||
extern kiodebug;
|
int c;
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
csum = 0;
|
csum = 0;
|
||||||
|
|
||||||
while ((c = readchar ()) != '$');
|
while ((c = readchar ()) != '$');
|
||||||
|
|
||||||
bp = buf;
|
bp = buf;
|
||||||
|
|
|
@ -21,6 +21,33 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
#include "serial.h"
|
#include "serial.h"
|
||||||
#include <sys/dos.h>
|
#include <sys/dos.h>
|
||||||
|
|
||||||
|
/* This is unused for now. We just return a placeholder. */
|
||||||
|
struct go32_ttystate
|
||||||
|
{
|
||||||
|
int bogus;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int go32_open PARAMS ((serial_t scb, const char *name));
|
||||||
|
static void go32_raw PARAMS ((serial_t scb));
|
||||||
|
static int wait_for PARAMS ((serial_t scb, int timeout));
|
||||||
|
static int go32_readchar PARAMS ((serial_t scb, int timeout));
|
||||||
|
static int rate_to_code PARAMS ((int rate));
|
||||||
|
static int go32_setbaudrate PARAMS ((serial_t scb, int rate));
|
||||||
|
static int go32_write PARAMS ((serial_t scb, const char *str, int len));
|
||||||
|
static void go32_restore PARAMS ((serial_t scb));
|
||||||
|
static void go32_close PARAMS ((serial_t scb));
|
||||||
|
serial_ttystate go32_get_tty_state PARAMS ((serial_t scb));
|
||||||
|
static int go32_set_tty_state PARAMS ((serial_t scb, serial_ttystate state));
|
||||||
|
static int strncasecmp PARAMS ((char *str1, char *str2, int len));
|
||||||
|
static char *aptr PARAMS ((short p));
|
||||||
|
static ASYNC_STRUCT *getivec PARAMS ((int which));
|
||||||
|
static int dos_async_init PARAMS ((int port));
|
||||||
|
static void dos_async_tx PARAMS ((const char c));
|
||||||
|
static int dos_async_ready PARAMS (());
|
||||||
|
static int dos_async_rx PARAMS (());
|
||||||
|
static int dosasync_read PARAMS ((int fd, char *buf, int len, int timeout));
|
||||||
|
static int dosasync_write PARAMS ((int fd, const char *buf, int len, int timeout));
|
||||||
|
|
||||||
#define SIGNATURE 0x4154
|
#define SIGNATURE 0x4154
|
||||||
#define VERSION 1
|
#define VERSION 1
|
||||||
#define OFFSET 0x104
|
#define OFFSET 0x104
|
||||||
|
@ -260,6 +287,30 @@ go32_readchar (scb, timeout)
|
||||||
return SERIAL_TIMEOUT;
|
return SERIAL_TIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* go32_{get set}_tty_state() are both dummys to fill out the function
|
||||||
|
vector. Someday, they may do something real... */
|
||||||
|
|
||||||
|
static serial_ttystate
|
||||||
|
go32_get_tty_state(scb)
|
||||||
|
serial_t scb;
|
||||||
|
{
|
||||||
|
struct go32_ttystate *state;
|
||||||
|
|
||||||
|
state = (struct go32_ttystate *)xmalloc(sizeof *state);
|
||||||
|
|
||||||
|
return (serial_ttystate)state;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
go32_set_tty_state(scb, ttystate)
|
||||||
|
serial_t scb;
|
||||||
|
serial_ttystate ttystate;
|
||||||
|
{
|
||||||
|
struct go32_ttystate *state;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
go32_setbaudrate (scb, rate)
|
go32_setbaudrate (scb, rate)
|
||||||
serial_t scb;
|
serial_t scb;
|
||||||
|
@ -284,12 +335,6 @@ go32_close ()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
go32_restore (scb)
|
|
||||||
serial_t scb;
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct serial_ops go32_ops =
|
static struct serial_ops go32_ops =
|
||||||
{
|
{
|
||||||
"hardwire",
|
"hardwire",
|
||||||
|
@ -299,7 +344,8 @@ static struct serial_ops go32_ops =
|
||||||
go32_readchar,
|
go32_readchar,
|
||||||
go32_write,
|
go32_write,
|
||||||
go32_raw,
|
go32_raw,
|
||||||
go32_restore,
|
go32_get_tty_state,
|
||||||
|
go32_set_tty_state,
|
||||||
go32_setbaudrate
|
go32_setbaudrate
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
270
gdb/ser-tcp.c
Normal file
270
gdb/ser-tcp.c
Normal file
|
@ -0,0 +1,270 @@
|
||||||
|
/* Serial interface for raw TCP connections 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 <sys/types.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/tcp.h>
|
||||||
|
#include "signals.h"
|
||||||
|
|
||||||
|
struct tcp_ttystate
|
||||||
|
{
|
||||||
|
int bogus;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int tcp_open PARAMS ((serial_t scb, const char *name));
|
||||||
|
static void tcp_raw PARAMS ((serial_t scb));
|
||||||
|
static int wait_for PARAMS ((serial_t scb, int timeout));
|
||||||
|
static int tcp_readchar PARAMS ((serial_t scb, int timeout));
|
||||||
|
static int tcp_setbaudrate PARAMS ((serial_t scb, int rate));
|
||||||
|
static int tcp_write PARAMS ((serial_t scb, const char *str, int len));
|
||||||
|
static void tcp_restore PARAMS ((serial_t scb));
|
||||||
|
static void tcp_close PARAMS ((serial_t scb));
|
||||||
|
static serial_ttystate tcp_get_tty_state PARAMS ((serial_t scb));
|
||||||
|
static int tcp_set_tty_state PARAMS ((serial_t scb, serial_ttystate state));
|
||||||
|
|
||||||
|
/* Open up a raw tcp socket */
|
||||||
|
|
||||||
|
static int
|
||||||
|
tcp_open(scb, name)
|
||||||
|
serial_t scb;
|
||||||
|
const char *name;
|
||||||
|
{
|
||||||
|
char *port_str;
|
||||||
|
int port;
|
||||||
|
struct hostent *hostent;
|
||||||
|
struct sockaddr_in sockaddr;
|
||||||
|
int tmp;
|
||||||
|
char hostname[100];
|
||||||
|
|
||||||
|
port_str = strchr (name, ':');
|
||||||
|
|
||||||
|
if (!port_str)
|
||||||
|
error ("tcp_open: No colon in host name!"); /* Shouldn't ever happen */
|
||||||
|
|
||||||
|
tmp = min(port_str - name + 1, sizeof hostname);
|
||||||
|
strncpy (hostname, name, tmp - 1); /* Don't want colon */
|
||||||
|
port = atoi (port_str + 1);
|
||||||
|
|
||||||
|
hostent = gethostbyname (hostname);
|
||||||
|
|
||||||
|
if (!hostent)
|
||||||
|
{
|
||||||
|
errno = ENOENT;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
scb->fd = socket (PF_INET, SOCK_STREAM, 0);
|
||||||
|
if (scb->fd < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Allow rapid reuse of this port. */
|
||||||
|
tmp = 1;
|
||||||
|
setsockopt (scb->fd, SOL_SOCKET, SO_REUSEADDR, (char *)&tmp, sizeof(tmp));
|
||||||
|
|
||||||
|
/* Enable TCP keep alive process. */
|
||||||
|
tmp = 1;
|
||||||
|
setsockopt (scb->fd, SOL_SOCKET, SO_KEEPALIVE, (char *)&tmp, sizeof(tmp));
|
||||||
|
|
||||||
|
sockaddr.sin_family = PF_INET;
|
||||||
|
sockaddr.sin_port = htons(port);
|
||||||
|
memcpy (&sockaddr.sin_addr.s_addr, hostent->h_addr,
|
||||||
|
sizeof (struct in_addr));
|
||||||
|
|
||||||
|
if (connect(scb->fd, &sockaddr, sizeof(sockaddr)))
|
||||||
|
{
|
||||||
|
close(scb->fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = 1;
|
||||||
|
if (setsockopt (scb->fd, 6, TCP_NODELAY, (char *)&tmp, sizeof(tmp)))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
signal(SIGPIPE, SIG_IGN); /* If we don't do this, then GDB simply exits
|
||||||
|
when the remote side dies. */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static serial_ttystate
|
||||||
|
tcp_get_tty_state(scb)
|
||||||
|
serial_t scb;
|
||||||
|
{
|
||||||
|
struct tcp_ttystate *state;
|
||||||
|
|
||||||
|
state = (struct tcp_ttystate *)xmalloc(sizeof *state);
|
||||||
|
|
||||||
|
return (serial_ttystate)state;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
tcp_set_tty_state(scb, ttystate)
|
||||||
|
serial_t scb;
|
||||||
|
serial_ttystate ttystate;
|
||||||
|
{
|
||||||
|
struct tcp_ttystate *state;
|
||||||
|
|
||||||
|
state = (struct tcp_ttystate *)ttystate;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tcp_raw(scb)
|
||||||
|
serial_t scb;
|
||||||
|
{
|
||||||
|
return; /* Always in raw mode */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait for input on scb, with timeout seconds. Returns 0 on success,
|
||||||
|
otherwise SERIAL_TIMEOUT or SERIAL_ERROR.
|
||||||
|
|
||||||
|
For termio{s}, we actually just setup VTIME if necessary, and let the
|
||||||
|
timeout occur in the read() in tcp_read().
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int
|
||||||
|
wait_for(scb, timeout)
|
||||||
|
serial_t scb;
|
||||||
|
int timeout;
|
||||||
|
{
|
||||||
|
int numfds;
|
||||||
|
struct timeval tv;
|
||||||
|
fd_set readfds;
|
||||||
|
|
||||||
|
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 SERIAL_TIMEOUT;
|
||||||
|
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(scb, timeout)
|
||||||
|
serial_t scb;
|
||||||
|
int timeout;
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
|
||||||
|
if (scb->bufcnt-- > 0)
|
||||||
|
return *scb->bufp++;
|
||||||
|
|
||||||
|
status = wait_for(scb, timeout);
|
||||||
|
|
||||||
|
if (status < 0)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
scb->bufcnt = read(scb->fd, scb->buf, BUFSIZ);
|
||||||
|
|
||||||
|
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_setbaudrate(scb, rate)
|
||||||
|
serial_t scb;
|
||||||
|
int rate;
|
||||||
|
{
|
||||||
|
return 0; /* Never fails! */
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
tcp_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
|
||||||
|
tcp_close(scb)
|
||||||
|
serial_t scb;
|
||||||
|
{
|
||||||
|
if (scb->fd < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
close(scb->fd);
|
||||||
|
scb->fd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct serial_ops tcp_ops =
|
||||||
|
{
|
||||||
|
"tcp",
|
||||||
|
0,
|
||||||
|
tcp_open,
|
||||||
|
tcp_close,
|
||||||
|
tcp_readchar,
|
||||||
|
tcp_write,
|
||||||
|
tcp_raw,
|
||||||
|
tcp_get_tty_state,
|
||||||
|
tcp_set_tty_state,
|
||||||
|
tcp_setbaudrate,
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
_initialize_ser_tcp ()
|
||||||
|
{
|
||||||
|
serial_add_interface (&tcp_ops);
|
||||||
|
}
|
245
gdb/ser-unix.c
245
gdb/ser-unix.c
|
@ -30,12 +30,29 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
#ifdef HAVE_TERMIOS
|
#ifdef HAVE_TERMIOS
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
struct hardwire_ttystate
|
||||||
|
{
|
||||||
|
struct termios termios;
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_TERMIO
|
#ifdef HAVE_TERMIO
|
||||||
#include <termio.h>
|
#include <termio.h>
|
||||||
|
|
||||||
|
struct hardwire_ttystate
|
||||||
|
{
|
||||||
|
struct termio termio;
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_SGTTY
|
#ifdef HAVE_SGTTY
|
||||||
#include <sgtty.h>
|
#include <sgtty.h>
|
||||||
|
|
||||||
|
struct hardwire_ttystate
|
||||||
|
{
|
||||||
|
struct sgttyb sgttyb;
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int hardwire_open PARAMS ((serial_t scb, const char *name));
|
static int hardwire_open PARAMS ((serial_t scb, const char *name));
|
||||||
|
@ -47,6 +64,10 @@ static int hardwire_setbaudrate PARAMS ((serial_t scb, int rate));
|
||||||
static int hardwire_write PARAMS ((serial_t scb, const char *str, int len));
|
static int hardwire_write PARAMS ((serial_t scb, const char *str, int len));
|
||||||
static void hardwire_restore PARAMS ((serial_t scb));
|
static void hardwire_restore PARAMS ((serial_t scb));
|
||||||
static void hardwire_close PARAMS ((serial_t scb));
|
static void hardwire_close PARAMS ((serial_t scb));
|
||||||
|
static int get_tty_state PARAMS ((serial_t scb, struct hardwire_ttystate *state));
|
||||||
|
static int set_tty_state PARAMS ((serial_t scb, struct hardwire_ttystate *state));
|
||||||
|
static serial_ttystate hardwire_get_tty_state PARAMS ((serial_t scb));
|
||||||
|
static int hardwire_set_tty_state PARAMS ((serial_t scb, serial_ttystate state));
|
||||||
|
|
||||||
/* Open up a real live device for serial I/O */
|
/* Open up a real live device for serial I/O */
|
||||||
|
|
||||||
|
@ -62,68 +83,108 @@ hardwire_open(scb, name)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
get_tty_state(scb, state)
|
||||||
|
serial_t scb;
|
||||||
|
struct hardwire_ttystate *state;
|
||||||
|
{
|
||||||
|
#ifdef HAVE_TERMIOS
|
||||||
|
return tcgetattr(scb->fd, &state->termios);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_TERMIO
|
||||||
|
return ioctl (scb->fd, TCGETA, &state->termio);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_SGTTY
|
||||||
|
return ioctl (scb->fd, TIOCGETP, &state->sgttyb);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
set_tty_state(scb, state)
|
||||||
|
serial_t scb;
|
||||||
|
struct hardwire_ttystate *state;
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
#ifdef HAVE_TERMIOS
|
||||||
|
return tcsetattr(scb->fd, TCSANOW, &state->termios);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_TERMIO
|
||||||
|
return ioctl (scb->fd, TCSETA, &state->termio);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_SGTTY
|
||||||
|
return ioctl (scb->fd, TIOCSETP, &state->sgttyb);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static serial_ttystate
|
||||||
|
hardwire_get_tty_state(scb)
|
||||||
|
serial_t scb;
|
||||||
|
{
|
||||||
|
struct hardwire_ttystate *state;
|
||||||
|
|
||||||
|
state = (struct hardwire_ttystate *)xmalloc(sizeof *state);
|
||||||
|
|
||||||
|
if (get_tty_state(scb, state))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return (serial_ttystate)state;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
hardwire_set_tty_state(scb, ttystate)
|
||||||
|
serial_t scb;
|
||||||
|
serial_ttystate ttystate;
|
||||||
|
{
|
||||||
|
struct hardwire_ttystate *state;
|
||||||
|
|
||||||
|
state = (struct hardwire_ttystate *)ttystate;
|
||||||
|
|
||||||
|
return set_tty_state(scb, state);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
hardwire_raw(scb)
|
hardwire_raw(scb)
|
||||||
serial_t scb;
|
serial_t scb;
|
||||||
{
|
{
|
||||||
|
struct hardwire_ttystate state;
|
||||||
|
|
||||||
|
if (get_tty_state(scb, &state))
|
||||||
|
fprintf(stderr, "get_tty_state failed: %s\n", safe_strerror(errno));
|
||||||
|
|
||||||
#ifdef HAVE_TERMIOS
|
#ifdef HAVE_TERMIOS
|
||||||
struct termios termios;
|
state.termios.c_iflag = 0;
|
||||||
|
state.termios.c_oflag = 0;
|
||||||
if (tcgetattr(scb->fd, &termios))
|
state.termios.c_lflag = 0;
|
||||||
{
|
state.termios.c_cflag &= ~(CSIZE|PARENB);
|
||||||
fprintf(stderr, "tcgetattr failed: %s\n", safe_strerror(errno));
|
state.termios.c_cflag |= CS8;
|
||||||
}
|
state.termios.c_cc[VMIN] = 0;
|
||||||
|
state.termios.c_cc[VTIME] = 0;
|
||||||
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
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_TERMIO
|
#ifdef HAVE_TERMIO
|
||||||
struct termio termio;
|
state.termio.c_iflag = 0;
|
||||||
|
state.termio.c_oflag = 0;
|
||||||
if (ioctl (scb->fd, TCGETA, &termio))
|
state.termio.c_lflag = 0;
|
||||||
{
|
state.termio.c_cflag &= ~(CSIZE|PARENB);
|
||||||
fprintf(stderr, "TCGETA failed: %s\n", safe_strerror(errno));
|
state.termio.c_cflag |= CS8;
|
||||||
}
|
state.termio.c_cc[VMIN] = 0;
|
||||||
|
state.termio.c_cc[VTIME] = 0;
|
||||||
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
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_SGTTY
|
#ifdef HAVE_SGTTY
|
||||||
struct sgttyb sgttyb;
|
state.sgttyb.sg_flags |= RAW | ANYP;
|
||||||
|
state.sgttyb.sg_flags &= ~(CBREAK | ECHO);
|
||||||
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
|
#endif
|
||||||
|
|
||||||
scb->current_timeout = 0;
|
scb->current_timeout = 0;
|
||||||
|
|
||||||
|
if (set_tty_state (scb, &state))
|
||||||
|
fprintf(stderr, "set_tty_state failed: %s\n", safe_strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wait for input on scb, with timeout seconds. Returns 0 on success,
|
/* Wait for input on scb, with timeout seconds. Returns 0 on success,
|
||||||
|
@ -171,31 +232,24 @@ wait_for(scb, timeout)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
struct hardwire_ttystate state;
|
||||||
|
|
||||||
|
if (get_tty_state(scb, &state))
|
||||||
|
fprintf(stderr, "get_tty_state failed: %s\n", safe_strerror(errno));
|
||||||
|
|
||||||
#ifdef HAVE_TERMIOS
|
#ifdef HAVE_TERMIOS
|
||||||
struct termios termios;
|
state.termios.c_cc[VTIME] = timeout * 10;
|
||||||
|
#endif
|
||||||
if (tcgetattr(scb->fd, &termios))
|
|
||||||
fprintf(stderr, "wait_for() tcgetattr failed: %s\n", safe_strerror(errno));
|
|
||||||
|
|
||||||
termios.c_cc[VTIME] = timeout * 10;
|
|
||||||
|
|
||||||
if (tcsetattr(scb->fd, TCSANOW, &termios))
|
|
||||||
fprintf(stderr, "wait_for() tcsetattr failed: %s\n", safe_strerror(errno));
|
|
||||||
#endif /* HAVE_TERMIOS */
|
|
||||||
|
|
||||||
#ifdef HAVE_TERMIO
|
#ifdef HAVE_TERMIO
|
||||||
struct termio termio;
|
state.termio.c_cc[VTIME] = timeout * 10;
|
||||||
|
#endif
|
||||||
if (ioctl (scb->fd, TCGETA, &termio))
|
|
||||||
fprintf(stderr, "wait_for() TCGETA failed: %s\n", safe_strerror(errno));
|
|
||||||
|
|
||||||
termio.c_cc[VTIME] = timeout * 10;
|
|
||||||
|
|
||||||
if (ioctl (scb->fd, TCSETA, &termio))
|
|
||||||
fprintf(stderr, "TCSETA failed: %s\n", safe_strerror(errno));
|
|
||||||
#endif /* HAVE_TERMIO */
|
|
||||||
|
|
||||||
scb->current_timeout = timeout;
|
scb->current_timeout = timeout;
|
||||||
|
|
||||||
|
if (set_tty_state (scb, &state))
|
||||||
|
fprintf(stderr, "set_tty_state failed: %s\n", safe_strerror(errno));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif /* HAVE_TERMIO || HAVE_TERMIOS */
|
#endif /* HAVE_TERMIO || HAVE_TERMIOS */
|
||||||
|
@ -290,49 +344,31 @@ hardwire_setbaudrate(scb, rate)
|
||||||
serial_t scb;
|
serial_t scb;
|
||||||
int rate;
|
int rate;
|
||||||
{
|
{
|
||||||
|
struct hardwire_ttystate state;
|
||||||
|
|
||||||
|
if (get_tty_state(scb, &state))
|
||||||
|
return -1;
|
||||||
|
|
||||||
#ifdef HAVE_TERMIOS
|
#ifdef HAVE_TERMIOS
|
||||||
struct termios termios;
|
cfsetospeed (&state.termios, rate_to_code (rate));
|
||||||
|
cfsetispeed (&state.termios, rate_to_code (rate));
|
||||||
if (tcgetattr (scb->fd, &termios))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
cfsetospeed (&termios, rate_to_code (rate));
|
|
||||||
cfsetispeed (&termios, rate_to_code (rate));
|
|
||||||
|
|
||||||
if (tcsetattr (scb->fd, TCSANOW, &termios))
|
|
||||||
return -1;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_TERMIO
|
#ifdef HAVE_TERMIO
|
||||||
struct termio termio;
|
|
||||||
|
|
||||||
if (ioctl (scb->fd, TCGETA, &termio))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
#ifndef CIBAUD
|
#ifndef CIBAUD
|
||||||
#define CIBAUD CBAUD
|
#define CIBAUD CBAUD
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
termio.c_cflag &= ~(CBAUD | CIBAUD);
|
state.termio.c_cflag &= ~(CBAUD | CIBAUD);
|
||||||
termio.c_cflag |= rate_to_code (rate);
|
state.termio.c_cflag |= rate_to_code (rate);
|
||||||
|
|
||||||
if (ioctl (scb->fd, TCSETA, &termio))
|
|
||||||
return -1;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_SGTTY
|
#ifdef HAVE_SGTTY
|
||||||
struct sgttyb sgttyb;
|
state.sgttyb.sg_ispeed = rate_to_code (rate);
|
||||||
|
state.sgttyb.sg_ospeed = rate_to_code (rate);
|
||||||
if (ioctl (scb->fd, TIOCGETP, &sgttyb))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
sgttyb.sg_ispeed = rate_to_code (rate);
|
|
||||||
sgttyb.sg_ospeed = rate_to_code (rate);
|
|
||||||
|
|
||||||
if (ioctl (scb->fd, TIOCSETP, &sgttyb))
|
|
||||||
return -1;
|
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
|
||||||
|
return set_tty_state (scb, &state);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -355,12 +391,6 @@ hardwire_write(scb, str, len)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
hardwire_restore(scb)
|
|
||||||
serial_t scb;
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
hardwire_close(scb)
|
hardwire_close(scb)
|
||||||
serial_t scb;
|
serial_t scb;
|
||||||
|
@ -381,8 +411,9 @@ static struct serial_ops hardwire_ops =
|
||||||
hardwire_readchar,
|
hardwire_readchar,
|
||||||
hardwire_write,
|
hardwire_write,
|
||||||
hardwire_raw,
|
hardwire_raw,
|
||||||
hardwire_restore,
|
hardwire_get_tty_state,
|
||||||
hardwire_setbaudrate
|
hardwire_set_tty_state,
|
||||||
|
hardwire_setbaudrate,
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
165
gdb/serial.c
165
gdb/serial.c
|
@ -20,10 +20,14 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
#include "serial.h"
|
#include "serial.h"
|
||||||
|
|
||||||
/* Open up a device or a network socket, depending upon the syntax of NAME. */
|
/* Linked list of serial I/O handlers */
|
||||||
|
|
||||||
static struct serial_ops *serial_ops_list = NULL;
|
static struct serial_ops *serial_ops_list = NULL;
|
||||||
|
|
||||||
|
/* This is the last serial stream opened. Used by connect command. */
|
||||||
|
|
||||||
|
static serial_t last_serial_opened = NULL;
|
||||||
|
|
||||||
static struct serial_ops *
|
static struct serial_ops *
|
||||||
serial_interface_lookup (name)
|
serial_interface_lookup (name)
|
||||||
char *name;
|
char *name;
|
||||||
|
@ -45,6 +49,8 @@ serial_add_interface(optable)
|
||||||
serial_ops_list = optable;
|
serial_ops_list = optable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Open up a device or a network socket, depending upon the syntax of NAME. */
|
||||||
|
|
||||||
serial_t
|
serial_t
|
||||||
serial_open(name)
|
serial_open(name)
|
||||||
const char *name;
|
const char *name;
|
||||||
|
@ -52,7 +58,10 @@ serial_open(name)
|
||||||
serial_t scb;
|
serial_t scb;
|
||||||
struct serial_ops *ops;
|
struct serial_ops *ops;
|
||||||
|
|
||||||
ops = serial_interface_lookup ("hardwire");
|
if (strchr (name, ':'))
|
||||||
|
ops = serial_interface_lookup ("tcp");
|
||||||
|
else
|
||||||
|
ops = serial_interface_lookup ("hardwire");
|
||||||
|
|
||||||
if (!ops)
|
if (!ops)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -70,6 +79,34 @@ serial_open(name)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
last_serial_opened = scb;
|
||||||
|
|
||||||
|
return scb;
|
||||||
|
}
|
||||||
|
|
||||||
|
serial_t
|
||||||
|
serial_fdopen(fd)
|
||||||
|
const int fd;
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
scb->fd = fd;
|
||||||
|
|
||||||
|
last_serial_opened = scb;
|
||||||
|
|
||||||
return scb;
|
return scb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,21 +114,28 @@ void
|
||||||
serial_close(scb)
|
serial_close(scb)
|
||||||
serial_t scb;
|
serial_t scb;
|
||||||
{
|
{
|
||||||
|
last_serial_opened = NULL;
|
||||||
|
|
||||||
scb->ops->close(scb);
|
scb->ops->close(scb);
|
||||||
|
|
||||||
free(scb);
|
free(scb);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|
||||||
/* Connect the user directly to the remote system. This command acts just like
|
/* 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. */
|
the 'cu' or 'tip' command. Use <CR>~. or <CR>~^D to break out. */
|
||||||
|
|
||||||
|
static serial_t tty_desc; /* Controlling terminal */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cleanup_tty(ttystate)
|
cleanup_tty(ttystate)
|
||||||
struct ttystate ttystate;
|
serial_ttystate ttystate;
|
||||||
{
|
{
|
||||||
printf("\r\n[Exiting connect mode]\r\n");
|
printf ("\r\n[Exiting connect mode]\r\n");
|
||||||
serial_restore(0, &ttystate);
|
SERIAL_SET_TTY_STATE (tty_desc, ttystate);
|
||||||
|
free (ttystate);
|
||||||
|
SERIAL_CLOSE (tty_desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -99,87 +143,94 @@ connect_command (args, fromtty)
|
||||||
char *args;
|
char *args;
|
||||||
int fromtty;
|
int fromtty;
|
||||||
{
|
{
|
||||||
fd_set readfds;
|
|
||||||
int numfds;
|
|
||||||
int c;
|
int c;
|
||||||
char cur_esc = 0;
|
char cur_esc = 0;
|
||||||
static struct ttystate ttystate;
|
serial_ttystate ttystate;
|
||||||
|
serial_t port_desc; /* TTY port */
|
||||||
|
|
||||||
dont_repeat();
|
dont_repeat();
|
||||||
|
|
||||||
if (desc < 0)
|
|
||||||
error("target not open.");
|
|
||||||
|
|
||||||
if (args)
|
if (args)
|
||||||
fprintf("This command takes no args. They have been ignored.\n");
|
fprintf(stderr, "This command takes no args. They have been ignored.\n");
|
||||||
|
|
||||||
printf("[Entering connect mode. Use ~. or ~^D to escape]\n");
|
printf("[Entering connect mode. Use ~. or ~^D to escape]\n");
|
||||||
|
|
||||||
serial_raw(0, &ttystate);
|
tty_desc = SERIAL_FDOPEN (0);
|
||||||
|
port_desc = last_serial_opened;
|
||||||
|
|
||||||
make_cleanup(cleanup_tty, &ttystate);
|
ttystate = SERIAL_GET_TTY_STATE (tty_desc);
|
||||||
|
|
||||||
FD_ZERO(&readfds);
|
SERIAL_RAW (tty_desc);
|
||||||
|
SERIAL_RAW (port_desc);
|
||||||
|
|
||||||
|
make_cleanup (cleanup_tty, ttystate);
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
do
|
int mask;
|
||||||
{
|
|
||||||
FD_SET(0, &readfds);
|
|
||||||
FD_SET(desc, &readfds);
|
|
||||||
numfds = select(sizeof(readfds)*8, &readfds, 0, 0, 0);
|
|
||||||
}
|
|
||||||
while (numfds == 0);
|
|
||||||
|
|
||||||
if (numfds < 0)
|
mask = SERIAL_WAIT_2 (tty_desc, port_desc, -1);
|
||||||
perror_with_name("select");
|
|
||||||
|
|
||||||
if (FD_ISSET(0, &readfds))
|
if (mask & 2)
|
||||||
{ /* tty input, send to stdebug */
|
{ /* tty input */
|
||||||
char cx;
|
char cx;
|
||||||
|
|
||||||
c = serial_readchar(-1);
|
while (1)
|
||||||
if (c < 0)
|
|
||||||
perror_with_name("connect");
|
|
||||||
|
|
||||||
cx = c;
|
|
||||||
serial_write(&cx, 1);
|
|
||||||
switch (cur_esc)
|
|
||||||
{
|
{
|
||||||
case 0:
|
c = SERIAL_READCHAR(tty_desc, 0);
|
||||||
if (c == '\r')
|
|
||||||
cur_esc = c;
|
if (c == SERIAL_TIMEOUT)
|
||||||
break;
|
break;
|
||||||
case '\r':
|
|
||||||
if (c == '~')
|
if (c < 0)
|
||||||
cur_esc = c;
|
perror_with_name("connect");
|
||||||
else
|
|
||||||
cur_esc = 0;
|
cx = c;
|
||||||
break;
|
SERIAL_WRITE(port_desc, &cx, 1);
|
||||||
case '~':
|
|
||||||
if (c == '.' || c == '\004')
|
switch (cur_esc)
|
||||||
return;
|
{
|
||||||
else
|
case 0:
|
||||||
cur_esc = 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))
|
if (mask & 1)
|
||||||
{
|
{ /* Port input */
|
||||||
|
char cx;
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
c = serial_readchar(-1);
|
c = SERIAL_READCHAR(port_desc, 0);
|
||||||
|
|
||||||
|
if (c == SERIAL_TIMEOUT)
|
||||||
|
break;
|
||||||
|
|
||||||
if (c < 0)
|
if (c < 0)
|
||||||
break;
|
perror_with_name("connect");
|
||||||
putchar(c);
|
|
||||||
|
cx = c;
|
||||||
|
|
||||||
|
SERIAL_WRITE(tty_desc, &cx, 1);
|
||||||
}
|
}
|
||||||
fflush(stdout);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
void
|
void
|
||||||
_initialize_serial ()
|
_initialize_serial ()
|
||||||
{
|
{
|
||||||
|
@ -187,4 +238,4 @@ _initialize_serial ()
|
||||||
"Connect the terminal directly up to the command monitor.\n\
|
"Connect the terminal directly up to the command monitor.\n\
|
||||||
Use <CR>~. or <CR>~^D to break out.");
|
Use <CR>~. or <CR>~^D to break out.");
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* 0 */
|
||||||
|
|
21
gdb/serial.h
21
gdb/serial.h
|
@ -19,13 +19,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
/* Terminal state pointer. This is specific to each type of interface. */
|
/* Terminal state pointer. This is specific to each type of interface. */
|
||||||
|
|
||||||
typedef PTR ttystate;
|
typedef PTR serial_ttystate;
|
||||||
|
|
||||||
struct _serial_t
|
struct _serial_t
|
||||||
{
|
{
|
||||||
int fd; /* File descriptor */
|
int fd; /* File descriptor */
|
||||||
struct serial_ops *ops; /* Function vector */
|
struct serial_ops *ops; /* Function vector */
|
||||||
ttystate ttystate; /* Not used (yet) */
|
serial_ttystate ttystate; /* Not used (yet) */
|
||||||
int bufcnt; /* Amount of data in receive buffer */
|
int bufcnt; /* Amount of data in receive buffer */
|
||||||
unsigned char *bufp; /* Current byte */
|
unsigned char *bufp; /* Current byte */
|
||||||
unsigned char buf[BUFSIZ]; /* Da buffer itself */
|
unsigned char buf[BUFSIZ]; /* Da buffer itself */
|
||||||
|
@ -42,7 +42,8 @@ struct serial_ops {
|
||||||
int (*readchar) PARAMS ((serial_t, int timeout));
|
int (*readchar) PARAMS ((serial_t, int timeout));
|
||||||
int (*write) PARAMS ((serial_t, const char *str, int len));
|
int (*write) PARAMS ((serial_t, const char *str, int len));
|
||||||
void (*go_raw) PARAMS ((serial_t));
|
void (*go_raw) PARAMS ((serial_t));
|
||||||
void (*restore) PARAMS ((serial_t));
|
serial_ttystate (*get_tty_state) PARAMS ((serial_t));
|
||||||
|
int (*set_tty_state) PARAMS ((serial_t, serial_ttystate));
|
||||||
int (*setbaudrate) PARAMS ((serial_t, int rate));
|
int (*setbaudrate) PARAMS ((serial_t, int rate));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -52,6 +53,8 @@ void serial_add_interface PARAMS ((struct serial_ops *optable));
|
||||||
|
|
||||||
serial_t serial_open PARAMS ((const char *name));
|
serial_t serial_open PARAMS ((const char *name));
|
||||||
|
|
||||||
|
serial_t serial_fdopen PARAMS ((int fd));
|
||||||
|
|
||||||
/* For most routines, if a failure is indicated, then errno should be
|
/* For most routines, if a failure is indicated, then errno should be
|
||||||
examined. */
|
examined. */
|
||||||
|
|
||||||
|
@ -60,10 +63,18 @@ serial_t serial_open PARAMS ((const char *name));
|
||||||
|
|
||||||
#define SERIAL_OPEN(NAME) serial_open(NAME)
|
#define SERIAL_OPEN(NAME) serial_open(NAME)
|
||||||
|
|
||||||
|
/* Open a new serial stream using a file handle. */
|
||||||
|
|
||||||
|
#define SERIAL_FDOPEN(FD) serial_fdopen(FD)
|
||||||
|
|
||||||
/* Turn the port into raw mode. */
|
/* Turn the port into raw mode. */
|
||||||
|
|
||||||
#define SERIAL_RAW(SERIAL_T) (SERIAL_T)->ops->go_raw((SERIAL_T))
|
#define SERIAL_RAW(SERIAL_T) (SERIAL_T)->ops->go_raw((SERIAL_T))
|
||||||
|
|
||||||
|
#define SERIAL_GET_TTY_STATE(SERIAL_T) (SERIAL_T)->ops->get_tty_state((SERIAL_T))
|
||||||
|
|
||||||
|
#define SERIAL_SET_TTY_STATE(SERIAL_T, TTYSTATE) (SERIAL_T)->ops->set_tty_state((SERIAL_T), (TTYSTATE))
|
||||||
|
|
||||||
/* Read one char from the serial device with TIMEOUT seconds timeout.
|
/* Read one char from the serial device with TIMEOUT seconds timeout.
|
||||||
Returns char if ok, else one of the following codes. Note that all
|
Returns char if ok, else one of the following codes. Note that all
|
||||||
error codes are guaranteed to be < 0. */
|
error codes are guaranteed to be < 0. */
|
||||||
|
@ -90,7 +101,3 @@ void serial_close PARAMS ((serial_t));
|
||||||
|
|
||||||
#define SERIAL_CLOSE(SERIAL_T) serial_close(SERIAL_T)
|
#define SERIAL_CLOSE(SERIAL_T) serial_close(SERIAL_T)
|
||||||
|
|
||||||
/* Restore the serial port to the state saved in oldstate. XXX - currently
|
|
||||||
unused! */
|
|
||||||
|
|
||||||
#define SERIAL_RESTORE(SERIAL_T) (SERIAL_T)->ops->restore((SERIAL_T))
|
|
||||||
|
|
Loading…
Reference in a new issue