summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sim/process.cc25
-rw-r--r--sim/process.hh7
-rw-r--r--sim/syscall_emul.cc7
-rw-r--r--sim/syscall_emul.hh2
4 files changed, 28 insertions, 13 deletions
diff --git a/sim/process.cc b/sim/process.cc
index b04582233..a6cf5ded7 100644
--- a/sim/process.cc
+++ b/sim/process.cc
@@ -191,23 +191,32 @@ Process::dup_fd(int sim_fd, int tgt_fd)
// generate new target fd for sim_fd
int
-Process::open_fd(int sim_fd)
+Process::alloc_fd(int sim_fd)
{
- int free_fd;
-
// in case open() returns an error, don't allocate a new fd
if (sim_fd == -1)
return -1;
// find first free target fd
- for (free_fd = 0; fd_map[free_fd] >= 0; ++free_fd) {
- if (free_fd == MAX_FD)
- panic("Process::open_fd: out of file descriptors!");
+ for (int free_fd = 0; free_fd < MAX_FD; ++free_fd) {
+ if (fd_map[free_fd] == -1) {
+ fd_map[free_fd] = sim_fd;
+ return free_fd;
+ }
}
- fd_map[free_fd] = sim_fd;
+ panic("Process::alloc_fd: out of file descriptors!");
+}
+
+
+// free target fd (e.g., after close)
+void
+Process::free_fd(int tgt_fd)
+{
+ if (fd_map[tgt_fd] == -1)
+ warn("Process::free_fd: request to free unused fd %d", tgt_fd);
- return free_fd;
+ fd_map[tgt_fd] = -1;
}
diff --git a/sim/process.hh b/sim/process.hh
index 28c16a444..2116ef632 100644
--- a/sim/process.hh
+++ b/sim/process.hh
@@ -124,7 +124,7 @@ class Process : public SimObject
private:
// file descriptor remapping support
- static const int MAX_FD = 100; // max legal fd value
+ static const int MAX_FD = 256; // max legal fd value
int fd_map[MAX_FD+1];
public:
@@ -146,7 +146,10 @@ class Process : public SimObject
void dup_fd(int sim_fd, int tgt_fd);
// generate new target fd for sim_fd
- int open_fd(int sim_fd);
+ int alloc_fd(int sim_fd);
+
+ // free target fd (e.g., after close)
+ void free_fd(int tgt_fd);
// look up simulator fd for given target fd
int sim_fd(int tgt_fd);
diff --git a/sim/syscall_emul.cc b/sim/syscall_emul.cc
index 4ae2d2631..50650018e 100644
--- a/sim/syscall_emul.cc
+++ b/sim/syscall_emul.cc
@@ -110,8 +110,11 @@ obreakFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
SyscallReturn
closeFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
{
- int fd = p->sim_fd(xc->getSyscallArg(0));
- return close(fd);
+ int target_fd = xc->getSyscallArg(0);
+ int status = close(p->sim_fd(target_fd));
+ if (status >= 0)
+ p->free_fd(target_fd);
+ return status;
}
diff --git a/sim/syscall_emul.hh b/sim/syscall_emul.hh
index 17889113e..f22b6dcb7 100644
--- a/sim/syscall_emul.hh
+++ b/sim/syscall_emul.hh
@@ -339,7 +339,7 @@ openFunc(SyscallDesc *desc, int callnum, Process *process,
// open the file
int fd = open(path.c_str(), hostFlags, mode);
- return (fd == -1) ? -errno : process->open_fd(fd);
+ return (fd == -1) ? -errno : process->alloc_fd(fd);
}