* defs.h maint.c monitor.c remote-mips.c remote.c: Add support
for `watchdog' variable. This allows the user to put an upper limit on the amount of time that GDB will wait for the target to return from a step or continue operation. This will primarily be used for the testsuite, where it is difficult to come up with a reasonable timeout for things like function calls, which can take as long as three minutes under some circumstances. If the watchdog timer expires, GDB will generate an error that looks like `Watchdog has expired.', and will detach from the target. * remote-mips.c (mips_open): Setup initial frame from target. Print it out so that user is told where the program is stopped when they attach. * remote-nrom.c: Loads of cleanups. Use serial code to open network connections. Use expect() to wait for response to download command. * ser-tcp.c (tcp_open): Retry connection if we get ECONNREFUSED. * serial.c serial.h (serial_open serial_fdopen serial_close): Allow users to open the same device multiple times. They all get to share the same serial_t. This is about the only way to have multiple active targets use the same device (for download and debug). * sparcl-tdep.c: Keep #include <unistd.h> away from GO32. * target.c: Add `targetdebug' variable. If this is non-zero, then a special target is put at the top of the target stack which will cause all calls through the target vector to have their args and results printed out.
This commit is contained in:
parent
311f7c4b6a
commit
4887063b3c
@ -1,3 +1,42 @@
|
||||
Thu Jun 8 15:06:00 1995 Stu Grossman (grossman@cygnus.com)
|
||||
|
||||
* defs.h maint.c monitor.c remote-mips.c remote.c: Add support
|
||||
for `watchdog' variable. This allows the user to put an upper
|
||||
limit on the amount of time that GDB will wait for the target to
|
||||
return from a step or continue operation. This will primarily be
|
||||
used for the testsuite, where it is difficult to come up with a
|
||||
reasonable timeout for things like function calls, which can take
|
||||
as long as three minutes under some circumstances. If the
|
||||
watchdog timer expires, GDB will generate an error that looks like
|
||||
`Watchdog has expired.', and will detach from the target.
|
||||
|
||||
* remote-mips.c (mips_open): Setup initial frame from target.
|
||||
Print it out so that user is told where the program is stopped
|
||||
when they attach.
|
||||
|
||||
* remote-nrom.c: Loads of cleanups. Use serial code to open
|
||||
network connections. Use expect() to wait for response to
|
||||
download command.
|
||||
|
||||
* ser-tcp.c (tcp_open): Retry connection if we get ECONNREFUSED.
|
||||
|
||||
* serial.c serial.h (serial_open serial_fdopen serial_close):
|
||||
Allow users to open the same device multiple times. They all get
|
||||
to share the same serial_t. This is about the only way to have
|
||||
multiple active targets use the same device (for download and
|
||||
debug).
|
||||
|
||||
* sparcl-tdep.c: Keep #include <unistd.h> away from GO32.
|
||||
|
||||
* target.c: Add `targetdebug' variable. If this is non-zero,
|
||||
then a special target is put at the top of the target stack which
|
||||
will cause all calls through the target vector to have their args
|
||||
and results printed out.
|
||||
|
||||
Wed Jun 7 17:40:37 1995 Per Bothner <bothner@kalessin.cygnus.com>
|
||||
|
||||
* ch-exp.y: Handle <primitive_value> "->" <modename>.
|
||||
|
||||
Wed Jun 7 17:46:33 1995 Michael Meissner <meissner@tiktok.cygnus.com>
|
||||
|
||||
* mem-break.c (LITTLE_BREAKPOINT): If BREAKPOINT and
|
||||
|
||||
16
gdb/maint.c
16
gdb/maint.c
@ -43,6 +43,14 @@ static void maintenance_time_display PARAMS ((char *, int));
|
||||
|
||||
static void maintenance_space_display PARAMS ((char *, int));
|
||||
|
||||
/* Set this to the maximum number of seconds to wait instead of waiting forever
|
||||
in target_wait(). If this timer times out, then it generates an error and
|
||||
the command is aborted. This replaces most of the need for timeouts in the
|
||||
GDB test suite, and makes it possible to distinguish between a hung target
|
||||
and one with slow communications. */
|
||||
|
||||
int watchdog = 0;
|
||||
|
||||
/*
|
||||
|
||||
LOCAL FUNCTION
|
||||
@ -330,5 +338,13 @@ If a SOURCE file is specified, dump only that file's partial symbols.",
|
||||
add_cmd ("check-symtabs", class_maintenance, maintenance_check_symtabs,
|
||||
"Check consistency of psymtabs and symtabs.",
|
||||
&maintenancelist);
|
||||
|
||||
add_show_from_set (
|
||||
add_set_cmd ("watchdog", class_maintenance, var_zinteger, (char *)&watchdog,
|
||||
"Set watchdog timer.\n\
|
||||
When non-zero, this timeout is used instead of waiting forever for a target to\n\
|
||||
finish a low-level step or continue operation. If the specified amount of time\n\
|
||||
passes without a response from the target, an error occurs.", &setlist),
|
||||
&showlist);
|
||||
#endif /* MAINTENANCE_CMDS */
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/* Remote debugging interface for MIPS remote debugging protocol.
|
||||
Copyright 1993, 1994 Free Software Foundation, Inc.
|
||||
Copyright 1993, 1994, 1995 Free Software Foundation, Inc.
|
||||
Contributed by Cygnus Support. Written by Ian Lance Taylor
|
||||
<ian@cygnus.com>.
|
||||
|
||||
@ -128,7 +128,7 @@ extern struct target_ops mips_ops;
|
||||
The value is
|
||||
0x40 + seq
|
||||
An acknowlegment packet contains the sequence number of the
|
||||
packet being acknowledged plus 1 module 64. Data packets are
|
||||
packet being acknowledged plus 1 modulo 64. Data packets are
|
||||
transmitted in sequence. There may only be one outstanding
|
||||
unacknowledged data packet at a time. The sequence numbers
|
||||
are independent in each direction. If an acknowledgement for
|
||||
@ -334,10 +334,24 @@ mips_readchar (timeout)
|
||||
int ch;
|
||||
static int state = 0;
|
||||
static char nextstate[5] = { '<', 'I', 'D', 'T', '>' };
|
||||
#ifdef MAINTENANCE_CMDS
|
||||
int i;
|
||||
|
||||
i = timeout;
|
||||
if (i == -1 && watchdog > 0)
|
||||
i = watchdog;
|
||||
#endif
|
||||
|
||||
if (state == 5)
|
||||
timeout = 1;
|
||||
ch = SERIAL_READCHAR (mips_desc, timeout);
|
||||
#ifdef MAINTENANCE_CMDS
|
||||
if (ch == SERIAL_TIMEOUT && timeout == -1) /* Watchdog went off */
|
||||
{
|
||||
target_mourn_inferior ();
|
||||
error ("Watchdog has expired. Target detached.\n");
|
||||
}
|
||||
#endif
|
||||
if (ch == SERIAL_EOF)
|
||||
mips_error ("End of file from remote");
|
||||
if (ch == SERIAL_ERROR)
|
||||
@ -373,7 +387,10 @@ mips_readchar (timeout)
|
||||
|
||||
state = 0;
|
||||
|
||||
mips_error ("Remote board reset");
|
||||
/* At this point, about the only thing we can do is abort the command
|
||||
in progress and get back to command level as quickly as possible. */
|
||||
|
||||
error ("Remote board reset, debug protocol re-initialized.");
|
||||
}
|
||||
|
||||
if (ch == nextstate[state])
|
||||
@ -874,7 +891,7 @@ mips_request (cmd, addr, data, perr, timeout)
|
||||
char rcmd;
|
||||
int rerrflg;
|
||||
int rresponse;
|
||||
|
||||
|
||||
if (cmd != '\0')
|
||||
{
|
||||
if (mips_need_reply)
|
||||
@ -1031,6 +1048,18 @@ device is attached to the target board (e.g., /dev/ttya).");
|
||||
ptype = mips_read_processor_type ();
|
||||
if (ptype)
|
||||
mips_set_processor_type_command (strsave (ptype), 0);
|
||||
|
||||
/* This is really the job of start_remote however, that makes an assumption
|
||||
that the target is about to print out a status message of some sort. That
|
||||
doesn't happen here (in fact, it may not be possible to get the monitor to
|
||||
send the appropriate packet). */
|
||||
|
||||
flush_cached_frames ();
|
||||
registers_changed ();
|
||||
stop_pc = read_pc ();
|
||||
set_current_frame (create_new_frame (read_fp (), stop_pc));
|
||||
select_frame (get_current_frame (), 0);
|
||||
print_stack_frame (selected_frame, -1, 1);
|
||||
}
|
||||
|
||||
/* Close a connection to the remote board. */
|
||||
|
||||
@ -28,6 +28,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "gdbcmd.h"
|
||||
#include "serial.h"
|
||||
|
||||
#include <string.h>
|
||||
#include "inferior.h"
|
||||
#include "wait.h"
|
||||
@ -229,6 +231,10 @@ static int nrom_load_sock = -1;
|
||||
static int nrom_targ_sock = -1;
|
||||
static int nrom_ctrl_sock = -1;
|
||||
|
||||
static serial_t load_desc = NULL;
|
||||
static serial_t targ_desc = NULL;
|
||||
static serial_t ctrl_desc = NULL;
|
||||
|
||||
/* For binding to the socket we ned a sockaddr_in structure. */
|
||||
|
||||
static struct sockaddr_in nrom_sin;
|
||||
@ -256,6 +262,8 @@ static int bufindex = 0;
|
||||
static char workbuf[NROM_BUF_SIZE];
|
||||
static char sendbuf[NROM_BUF_SIZE];
|
||||
|
||||
static char nrom_hostname[100];
|
||||
|
||||
/* Forward data declaration. */
|
||||
|
||||
extern struct target_ops nrom_ops;
|
||||
@ -404,68 +412,75 @@ mem2hex (mem, buf, count)
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* Scan input from the remote system, until STRING is found. If BUF is non-
|
||||
zero, then collect input until we have collected either STRING or BUFLEN-1
|
||||
chars. In either case we terminate BUF with a 0. If input overflows BUF
|
||||
because STRING can't be found, return -1, else return number of chars in BUF
|
||||
(minus the terminating NUL). Note that in the non-overflow case, STRING
|
||||
will be at the end of BUF. */
|
||||
|
||||
static int
|
||||
expect (string)
|
||||
char *string;
|
||||
{
|
||||
char *p = string;
|
||||
int c;
|
||||
|
||||
immediate_quit = 1;
|
||||
|
||||
while (1)
|
||||
{
|
||||
c = SERIAL_READCHAR (ctrl_desc, 5);
|
||||
|
||||
if (c == *p++)
|
||||
{
|
||||
if (*p == '\0')
|
||||
{
|
||||
immediate_quit = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fputc_unfiltered (c, gdb_stdout);
|
||||
p = string;
|
||||
if (c == *p)
|
||||
p++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
nrom_control_send (s, nbytes)
|
||||
char *s;
|
||||
int nbytes;
|
||||
{
|
||||
long len;
|
||||
char buf[10];
|
||||
SERIAL_WRITE (ctrl_desc, s, nbytes);
|
||||
|
||||
/* clear leading characters */
|
||||
/* FIXME: The ioctl uses here seem bogus to me. -sts */
|
||||
len = 1;
|
||||
while (len > 0)
|
||||
{
|
||||
if (ioctl (nrom_ctrl_sock, FIONREAD, &len) < 0)
|
||||
{
|
||||
perror ("nrom_control_send ioctl");
|
||||
return (-1);
|
||||
}
|
||||
if (len > 0)
|
||||
{
|
||||
if (read (nrom_ctrl_sock, buf, 1) < 0)
|
||||
{
|
||||
perror ("nrom_control_send read");
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (remote_debug)
|
||||
printf_filtered ("nrom_control_send: sending '%s' (%d bytes) to NetROM\n",
|
||||
s, nbytes);
|
||||
|
||||
if (writen (nrom_ctrl_sock, s, nbytes) < 0)
|
||||
{
|
||||
perror ("nrom_control_send");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* clear trailing characters */
|
||||
len = 1;
|
||||
while (len > 0)
|
||||
{
|
||||
if (ioctl (nrom_ctrl_sock, FIONREAD, &len) < 0)
|
||||
{
|
||||
perror ("nrom_control_send ioctl");
|
||||
return (-1);
|
||||
}
|
||||
if (len > 0)
|
||||
{
|
||||
if (read (nrom_ctrl_sock, buf, 1) < 0)
|
||||
{
|
||||
perror ("nrom_control_send read");
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
nrom_kill ()
|
||||
{
|
||||
nrom_close (0);
|
||||
}
|
||||
|
||||
static serial_t
|
||||
open_socket (name, port)
|
||||
char *name;
|
||||
int port;
|
||||
{
|
||||
char sockname[100];
|
||||
serial_t desc;
|
||||
|
||||
sprintf (sockname, "%s:%d", name, port);
|
||||
desc = SERIAL_OPEN (sockname);
|
||||
if (!desc)
|
||||
perror_with_name (sockname);
|
||||
|
||||
return desc;
|
||||
}
|
||||
|
||||
/* Download a file specified in ARGS to the netROM. */
|
||||
@ -485,20 +500,9 @@ nrom_load (args, fromtty)
|
||||
if (nrom_control_send (downloadstring, strlen (downloadstring)) < 0)
|
||||
error ("nrom_load: control_send() of `%s' failed", downloadstring);
|
||||
|
||||
/* Wait for the download daemon to start up. */
|
||||
sleep (1);
|
||||
expect ("Waiting for a connection...\n");
|
||||
|
||||
nrom_load_sock = socket (AF_INET, SOCK_STREAM, 0);
|
||||
if (nrom_load_sock == -1)
|
||||
error ("Could not create download socket, error %d", errno);
|
||||
|
||||
memset (&sin, 0, sizeof(struct sockaddr_in));
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = htons (load_port);
|
||||
sin.sin_addr.s_addr = htonl (nrom_ipaddr);
|
||||
|
||||
if (connect (nrom_load_sock, &sin, sizeof(sin)) == -1)
|
||||
error ("Connect failed, error %d", errno);
|
||||
load_desc = open_socket (nrom_hostname, load_port);
|
||||
|
||||
pbfd = bfd_openr (args, 0);
|
||||
|
||||
@ -540,7 +544,7 @@ nrom_load (args, fromtty)
|
||||
bfd_get_section_contents (pbfd, section, buffer, fptr,
|
||||
count);
|
||||
|
||||
writen (nrom_load_sock, buffer, count);
|
||||
SERIAL_WRITE (load_desc, buffer, count);
|
||||
section_address += count;
|
||||
fptr += count;
|
||||
section_size -= count;
|
||||
@ -557,7 +561,8 @@ nrom_load (args, fromtty)
|
||||
else
|
||||
error ("\"%s\": Could not open", args);
|
||||
|
||||
close (nrom_load_sock);
|
||||
SERIAL_CLOSE (load_desc);
|
||||
load_desc = NULL;
|
||||
}
|
||||
|
||||
/* This is called not only when we first attach, but also when the
|
||||
@ -580,52 +585,24 @@ nrom_open (name, from_tty)
|
||||
{
|
||||
int errn;
|
||||
|
||||
if (name)
|
||||
nrom_set_ipaddr (name, from_tty);
|
||||
else if (nrom_ipaddr == 0)
|
||||
if (!name || strchr (name, '/') || strchr (name, ':'))
|
||||
error (
|
||||
"To open a NetROM connection, you must specify the hostname\n\
|
||||
or IP address of the NetROM device you wish to use.");
|
||||
|
||||
strcpy (nrom_hostname, name);
|
||||
|
||||
target_preopen (from_tty);
|
||||
|
||||
unpush_target (&nrom_ops);
|
||||
|
||||
targ_desc = open_socket (nrom_hostname, target_port);
|
||||
ctrl_desc = open_socket (nrom_hostname, control_port);
|
||||
|
||||
push_target (&nrom_ops);
|
||||
|
||||
/* Create the socket used for talking with the target. */
|
||||
nrom_targ_sock = socket (AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
/* Bind the socket. */
|
||||
nrom_sin.sin_family = AF_INET;
|
||||
nrom_sin.sin_port = htons (target_port);
|
||||
nrom_sin.sin_addr.S_un.S_addr = htonl (nrom_ipaddr);
|
||||
|
||||
/* Connect to the remote host. */
|
||||
if (connect (nrom_targ_sock, &nrom_sin, sizeof(nrom_sin)) == -1)
|
||||
error ("Connect failed, error %d", errno);
|
||||
|
||||
/* Create the socket used for talking with the debugger services. */
|
||||
nrom_ctrl_sock = socket (AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
/* Bind the socket. */
|
||||
nrom_sin.sin_family = AF_INET;
|
||||
nrom_sin.sin_port = htons (control_port);
|
||||
nrom_sin.sin_addr.S_un.S_addr = htonl (nrom_ipaddr);
|
||||
|
||||
/* Connect to the remote host. */
|
||||
if (connect (nrom_ctrl_sock, &nrom_sin, sizeof(nrom_sin)) == -1)
|
||||
{
|
||||
errn = errno;
|
||||
close (nrom_targ_sock);
|
||||
error ("Connect control_socket failed, error %d", errn);
|
||||
}
|
||||
|
||||
if (from_tty)
|
||||
{
|
||||
unsigned char *i;
|
||||
|
||||
printf_filtered ("Connected to NetROM device \"%s\"", name);
|
||||
i = (unsigned char *) &nrom_ipaddr;
|
||||
printf_filtered (" (%d.%d.%d.%d)\n",
|
||||
UC(i[0]), UC(i[1]), UC(i[2]), UC(i[3]));
|
||||
}
|
||||
printf_filtered ("Connected to NetROM device \"%s\"\n", nrom_hostname);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -640,6 +617,16 @@ static void
|
||||
nrom_close (quitting)
|
||||
int quitting;
|
||||
{
|
||||
if (load_desc)
|
||||
SERIAL_CLOSE (load_desc);
|
||||
if (targ_desc)
|
||||
SERIAL_CLOSE (targ_desc);
|
||||
if (ctrl_desc)
|
||||
SERIAL_CLOSE (ctrl_desc);
|
||||
|
||||
load_desc = NULL;
|
||||
targ_desc = NULL;
|
||||
ctrl_desc = NULL;
|
||||
}
|
||||
|
||||
/* Attach to the target that is already loaded and possibly running */
|
||||
@ -1312,7 +1299,7 @@ struct target_ops nrom_ops = {
|
||||
nrom_can_run,
|
||||
0, /* to_notice_signals */
|
||||
0,
|
||||
process_stratum, /* to_stratum */
|
||||
download_stratum, /* to_stratum */
|
||||
NULL, /* to_next */
|
||||
1,
|
||||
1,
|
||||
|
||||
@ -79,28 +79,38 @@ tcp_open(scb, name)
|
||||
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, (struct sockaddr *) &sockaddr, sizeof(sockaddr)))
|
||||
for (i = 1; i <= 15; i++)
|
||||
{
|
||||
close(scb->fd);
|
||||
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, (struct sockaddr *) &sockaddr, sizeof(sockaddr)))
|
||||
break;
|
||||
|
||||
close (scb->fd);
|
||||
scb->fd = -1;
|
||||
return -1;
|
||||
|
||||
/* We retry for ECONNREFUSED because that is often a temporary condition, which
|
||||
happens when the server is being restarted. */
|
||||
|
||||
if (errno != ECONNREFUSED)
|
||||
return -1;
|
||||
|
||||
sleep (1);
|
||||
}
|
||||
|
||||
protoent = getprotobyname ("tcp");
|
||||
|
||||
50
gdb/serial.c
50
gdb/serial.c
@ -58,6 +58,13 @@ serial_open (name)
|
||||
serial_t scb;
|
||||
struct serial_ops *ops;
|
||||
|
||||
for (scb = scb_base; scb; scb = scb->next)
|
||||
if (scb->name && strcmp (scb->name, name) == 0)
|
||||
{
|
||||
scb->refcnt++;
|
||||
return scb;
|
||||
}
|
||||
|
||||
if (strcmp (name, "pc") == 0)
|
||||
ops = serial_interface_lookup ("pc");
|
||||
else if (strchr (name, ':'))
|
||||
@ -81,18 +88,30 @@ serial_open (name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
scb->name = strsave (name);
|
||||
scb->next = scb_base;
|
||||
scb->refcnt = 1;
|
||||
scb_base = scb;
|
||||
|
||||
last_serial_opened = scb;
|
||||
|
||||
return scb;
|
||||
}
|
||||
|
||||
serial_t
|
||||
serial_fdopen(fd)
|
||||
serial_fdopen (fd)
|
||||
const int fd;
|
||||
{
|
||||
serial_t scb;
|
||||
struct serial_ops *ops;
|
||||
|
||||
for (scb = scb_base; scb; scb = scb->next)
|
||||
if (scb->fd == fd)
|
||||
{
|
||||
scb->refcnt++;
|
||||
return scb;
|
||||
}
|
||||
|
||||
ops = serial_interface_lookup ("hardwire");
|
||||
|
||||
if (!ops)
|
||||
@ -107,6 +126,11 @@ serial_fdopen(fd)
|
||||
|
||||
scb->fd = fd;
|
||||
|
||||
scb->name = NULL;
|
||||
scb->next = scb_base;
|
||||
scb->refcnt = 1;
|
||||
scb_base = scb;
|
||||
|
||||
last_serial_opened = scb;
|
||||
|
||||
return scb;
|
||||
@ -116,6 +140,8 @@ void
|
||||
serial_close(scb)
|
||||
serial_t scb;
|
||||
{
|
||||
serial_t tmp_scb;
|
||||
|
||||
last_serial_opened = NULL;
|
||||
|
||||
/* This is bogus. It's not our fault if you pass us a bad scb...! Rob, you
|
||||
@ -124,7 +150,27 @@ serial_close(scb)
|
||||
if (!scb)
|
||||
return;
|
||||
|
||||
scb->ops->close(scb);
|
||||
scb->refcnt--;
|
||||
if (scb->refcnt > 0)
|
||||
return;
|
||||
|
||||
scb->ops->close (scb);
|
||||
|
||||
if (scb->name)
|
||||
free (scb->name);
|
||||
|
||||
if (scb_base == scb)
|
||||
scb_base = scb_base->next;
|
||||
else
|
||||
for (tmp_scb = scb_base; tmp_scb; tmp_scb = tmp_scb->next)
|
||||
{
|
||||
if (tmp_scb->next != scb)
|
||||
continue;
|
||||
|
||||
tmp_scb->next = tmp_scb->next->next;
|
||||
break;
|
||||
}
|
||||
|
||||
free(scb);
|
||||
}
|
||||
|
||||
|
||||
@ -36,10 +36,15 @@ struct _serial_t
|
||||
/* ser-unix.c termio{,s} only, we still need to wait for this many more
|
||||
seconds. */
|
||||
int timeout_remaining;
|
||||
char *name; /* The name of the device or host */
|
||||
struct _serial_t *next; /* Pointer to the next serial_t */
|
||||
int refcnt; /* Number of pointers to this block */
|
||||
};
|
||||
|
||||
typedef struct _serial_t *serial_t;
|
||||
|
||||
serial_t scb_base; /* Pointer to list of scb's */
|
||||
|
||||
struct serial_ops {
|
||||
char *name;
|
||||
struct serial_ops *next;
|
||||
|
||||
@ -24,8 +24,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#include "serial.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#ifndef __GO32__
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user