arch-arm: Replace call to `tmpnam()` by a deterministic one
authorHoa Nguyen <hoanguyen@ucdavis.edu>
Fri, 25 Sep 2020 22:26:40 +0000 (15:26 -0700)
committerHoa Nguyen <hoanguyen@ucdavis.edu>
Tue, 6 Oct 2020 20:07:26 +0000 (20:07 +0000)
According to the documentation, the use of tmpnam() should be
avoided.

This commit generates a temporary filename by concat-ing the
object name with an index that is internally tracked, the index
is increased until a filename that is not being used is found.

JIRA: https://gem5.atlassian.net/browse/GEM5-206

Change-Id: Ibfe604d741b6b7d7b02fc051add217f95f81d05e
Signed-off-by: Hoa Nguyen <hoanguyen@ucdavis.edu>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/35195
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
src/arch/arm/semihosting.cc
src/arch/arm/semihosting.hh

index bd7b617cf9f7defc6c5a9e3bfc90da0494d4e472..901fdd17b7cf0796bf523b4ff570e657727714d0 100644 (file)
 
 #include "arch/arm/semihosting.hh"
 
+#include <unistd.h>
+
+#include <cerrno>
 #include <cstdio>
 
 #include "arch/arm/utility.hh"
 #include "base/logging.hh"
+#include "base/output.hh"
 #include "base/time.hh"
 #include "debug/Semihosting.hh"
 #include "dev/serial/serial.hh"
@@ -449,16 +453,21 @@ ArmSemihosting::RetErrno
 ArmSemihosting::callTmpNam(ThreadContext *tc, Addr addr, uint64_t id,
                            size_t size)
 {
-    std::vector<char> buf(L_tmpnam);
-    char *path = tmpnam(buf.data());
-    if (!path)
-        return retError(EINVAL);
+    std::string path = "";
+    int64_t unlink_call_ret = 0;
+
+    do {
+        path = simout.resolve(csprintf("%s.tmp%05i", name(), tmpNameIndex++));
+        // remove the (potentially existing) file of the given path
+        unlink_call_ret = unlink(path.c_str());
+    // if the file is busy, find another name
+    } while ((unlink_call_ret < 0) && (errno == EBUSY));
 
-    const size_t path_len = strlen(path);
+    const size_t path_len = path.length();
     if (path_len >= size)
         return retError(ENOSPC);
 
-    portProxy(tc).writeBlob(addr, path, path_len + 1);
+    portProxy(tc).writeBlob(addr, path.c_str(), path_len + 1);
     return retOK(0);
 }
 
index e9dc984e20e07c9261fbe7479763696d26e90339..da0644fd8e4bcda6caa1991da9a8b5523fd0b361 100644 (file)
@@ -581,6 +581,10 @@ class ArmSemihosting : public SimObject
     static const std::map<uint64_t, const char *> exitCodes;
     static const std::vector<uint8_t> features;
     static const std::map<const std::string, FILE *> stdioMap;
+
+    // used in callTmpNam() to deterministically generate a temp filename
+    uint16_t tmpNameIndex = 0;
+
 };
 
 std::ostream &operator << (