aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/gdb/ChangeLog6
-rw-r--r--include/gdb/callback.h11
-rw-r--r--sim/common/ChangeLog6
-rw-r--r--sim/common/callback.c53
4 files changed, 60 insertions, 16 deletions
diff --git a/include/gdb/ChangeLog b/include/gdb/ChangeLog
index 3a17b1d..80a9e06 100644
--- a/include/gdb/ChangeLog
+++ b/include/gdb/ChangeLog
@@ -1,3 +1,9 @@
+2004-06-25 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * callback.h (host_callback_struct): Replace members fdopen and
+ alwaysopen with fd_buddy.
+ [sim/common: * callback.c: Changed all users. ]
+
2003-10-31 Kevin Buettner <kevin@redhat.com>
* sim-frv.h: New file.
diff --git a/include/gdb/callback.h b/include/gdb/callback.h
index 3fa4191..aa956d0 100644
--- a/include/gdb/callback.h
+++ b/include/gdb/callback.h
@@ -123,8 +123,15 @@ struct host_callback_struct
int last_errno; /* host format */
int fdmap[MAX_CALLBACK_FDS];
- char fdopen[MAX_CALLBACK_FDS];
- char alwaysopen[MAX_CALLBACK_FDS];
+ /* fd_buddy is used to contruct circular lists of target fds that point to
+ the same host fd. A uniquely mapped fd points to itself; for a closed
+ one, fd_buddy has the value -1. The host file descriptors for stdin /
+ stdout / stderr are never closed by the simulators, so they are put
+ in a special fd_buddy circular list which also has MAX_CALLBACK_FDS
+ as a member. */
+ /* ??? We don't have a callback entry for dup, although it is trival to
+ implement now. */
+ short fd_buddy[MAX_CALLBACK_FDS+1];
/* System call numbers. */
CB_TARGET_DEFS_MAP *syscall_map;
diff --git a/sim/common/ChangeLog b/sim/common/ChangeLog
index 08a1751..573c82d 100644
--- a/sim/common/ChangeLog
+++ b/sim/common/ChangeLog
@@ -1,3 +1,9 @@
+2004-06-25 J"orn Rennecke <joern.rennecke@superh.com>
+
+ [ include/gdb: * callback.h (host_callback_struct): Replace
+ members fdopen and alwaysopen with fd_buddy. ]
+ * callback.c: Changed all users.
+
2004-06-15 Alan Modra <amodra@bigpond.net.au>
* sim-load.c (sim_load_file): Use bfd_get_section_size
diff --git a/sim/common/callback.c b/sim/common/callback.c
index 62848e8..bbb3fe5 100644
--- a/sim/common/callback.c
+++ b/sim/common/callback.c
@@ -110,7 +110,7 @@ fdbad (p, fd)
host_callback *p;
int fd;
{
- if (fd < 0 || fd > MAX_CALLBACK_FDS || !p->fdopen[fd])
+ if (fd < 0 || fd > MAX_CALLBACK_FDS || p->fd_buddy[fd] < 0)
{
p->last_errno = EINVAL;
return -1;
@@ -132,13 +132,20 @@ os_close (p, fd)
int fd;
{
int result;
+ int i, next;
result = fdbad (p, fd);
if (result)
return result;
- result = wrap (p, close (fdmap (p, fd)));
- if (result == 0 && !p->alwaysopen[fd])
- p->fdopen[fd] = 0;
+ /* If this file descripter has one or more buddies (originals /
+ duplicates from a dup), just remove it from the circular list. */
+ for (i = fd; (next = p->fd_buddy[i]) != fd; )
+ i = next;
+ if (fd != i)
+ p->fd_buddy[i] = p->fd_buddy[fd];
+ else
+ result = wrap (p, close (fdmap (p, fd)));
+ p->fd_buddy[fd] = -1;
return result;
}
@@ -234,7 +241,7 @@ os_open (p, name, flags)
int i;
for (i = 0; i < MAX_CALLBACK_FDS; i++)
{
- if (!p->fdopen[i])
+ if (p->fd_buddy[i] < 0)
{
int f = open (name, cb_target_to_host_open (p, flags), 0644);
if (f < 0)
@@ -242,7 +249,7 @@ os_open (p, name, flags)
p->last_errno = errno;
return f;
}
- p->fdopen[i] = 1;
+ p->fd_buddy[i] = i;
p->fdmap[i] = f;
return i;
}
@@ -428,13 +435,31 @@ static int
os_shutdown (p)
host_callback *p;
{
- int i;
+ int i, next, j;
for (i = 0; i < MAX_CALLBACK_FDS; i++)
{
- if (p->fdopen[i] && !p->alwaysopen[i]) {
+ int do_close = 1;
+
+ next = p->fd_buddy[i];
+ if (next < 0)
+ continue;
+ do
+ {
+ j = next;
+ if (j == MAX_CALLBACK_FDS)
+ do_close = 0;
+ next = p->fd_buddy[j];
+ p->fd_buddy[j] = -1;
+ /* At the initial call of os_init, we got -1, 0, 0, 0, ... */
+ if (next < 0)
+ {
+ do_close = 0;
+ break;
+ }
+ }
+ while (j != i);
+ if (do_close)
close (p->fdmap[i]);
- p->fdopen[i] = 0;
- }
}
return 1;
}
@@ -449,9 +474,10 @@ os_init (p)
for (i = 0; i < 3; i++)
{
p->fdmap[i] = i;
- p->fdopen[i] = 1;
- p->alwaysopen[i] = 1;
+ p->fd_buddy[i] = i - 1;
}
+ p->fd_buddy[0] = MAX_CALLBACK_FDS;
+ p->fd_buddy[MAX_CALLBACK_FDS] = 2;
p->syscall_map = cb_init_syscall_map;
p->errno_map = cb_init_errno_map;
@@ -580,8 +606,7 @@ host_callback default_callback =
0, /* last errno */
{ 0, }, /* fdmap */
- { 0, }, /* fdopen */
- { 0, }, /* alwaysopen */
+ { -1, }, /* fd_buddy */
0, /* syscall_map */
0, /* errno_map */