Actually free Process fd_map entries when a file is closed...
[gem5.git] / sim / process.cc
index ab256454c262771ccb672d9bfb3d3daa0fb04149..a6cf5ded7de2e6cbd6fb8161c4ec1f9f3eedcee6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001-2004 The Regents of The University of Michigan
+ * Copyright (c) 2001-2005 The Regents of The University of Michigan
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -36,6 +36,7 @@
 #include "base/loader/object_file.hh"
 #include "base/loader/symtab.hh"
 #include "base/statistics.hh"
+#include "config/full_system.hh"
 #include "cpu/exec_context.hh"
 #include "cpu/smt.hh"
 #include "encumbered/cpu/full/thread.hh"
@@ -58,7 +59,7 @@ using namespace std;
 // when there's no OS: thus there's no resone to use it in FULL_SYSTEM
 // mode when we do have an OS
 //
-#ifdef FULL_SYSTEM
+#if FULL_SYSTEM
 #error "process.cc not compatible with FULL_SYSTEM"
 #endif
 
@@ -190,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;
 }
 
 
@@ -341,12 +351,13 @@ LiveProcess::LiveProcess(const string &nm, ObjectFile *objFile,
 LiveProcess *
 LiveProcess::create(const string &nm,
                     int stdin_fd, int stdout_fd, int stderr_fd,
+                    string executable,
                     vector<string> &argv, vector<string> &envp)
 {
     LiveProcess *process = NULL;
-    ObjectFile *objFile = createObjectFile(argv[0]);
+    ObjectFile *objFile = createObjectFile(executable);
     if (objFile == NULL) {
-        fatal("Can't load object file %s", argv[0]);
+        fatal("Can't load object file %s", executable);
     }
 
     // check object type & set up syscall emulation pointer
@@ -383,6 +394,7 @@ LiveProcess::create(const string &nm,
 BEGIN_DECLARE_SIM_OBJECT_PARAMS(LiveProcess)
 
     VectorParam<string> cmd;
+    Param<string> executable;
     Param<string> input;
     Param<string> output;
     VectorParam<string> env;
@@ -393,6 +405,7 @@ END_DECLARE_SIM_OBJECT_PARAMS(LiveProcess)
 BEGIN_INIT_SIM_OBJECT_PARAMS(LiveProcess)
 
     INIT_PARAM(cmd, "command line (executable plus arguments)"),
+    INIT_PARAM(executable, "executable (overrides cmd[0] if set)"),
     INIT_PARAM(input, "filename for stdin (dflt: use sim stdin)"),
     INIT_PARAM(output, "filename for stdout/stderr (dflt: use sim stdout)"),
     INIT_PARAM(env, "environment settings")
@@ -424,6 +437,7 @@ CREATE_SIM_OBJECT(LiveProcess)
 
     return LiveProcess::create(getInstanceName(),
                                stdin_fd, stdout_fd, stderr_fd,
+                               (string)executable == "" ? cmd[0] : executable,
                                cmd, env);
 }