diff options
-rw-r--r-- | include/gdb/ChangeLog | 6 | ||||
-rw-r--r-- | include/gdb/callback.h | 11 | ||||
-rw-r--r-- | sim/common/ChangeLog | 6 | ||||
-rw-r--r-- | sim/common/callback.c | 53 |
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 */ |