[Lldb-commits] Remove the use of mkstemp, as it's not portable

Zachary Turner zturner at google.com
Thu Jul 31 13:46:51 PDT 2014


Sorry, here's a more easily digestable patch.


On Thu, Jul 31, 2014 at 1:45 PM, Zachary Turner <zturner at google.com> wrote:

> mkstemp doesn't exist on Windows.  LLVM already has a support function
> which is the same in spirit as mkstemp.  This patch adds a method to the
> host layer to create a temporary file, and the implementation of this
> method on the private side delegates to the corresponding LLVM support
> function.
>
> This fixes the build on Windows and should have identical semantics on
> other platforms, but please verify.
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20140731/c88d6388/attachment.html>
-------------- next part --------------
diff --git a/include/lldb/API/SBHostOS.h b/include/lldb/API/SBHostOS.h
index 7ab22ca..0239d11 100644
--- a/include/lldb/API/SBHostOS.h
+++ b/include/lldb/API/SBHostOS.h
@@ -31,6 +31,11 @@ public:
     static void
     ThreadCreated (const char *name);
 
+    static int
+    CreateTemporaryFile (const char *directory,
+                         const char *pathTemplate,
+                         lldb::SBFileSpec &result);
+
     static lldb::thread_t
     ThreadCreate (const char *name,
                   lldb::thread_func_t thread_function,
diff --git a/include/lldb/Host/Host.h b/include/lldb/Host/Host.h
index aa934d9..e3be3b5 100644
--- a/include/lldb/Host/Host.h
+++ b/include/lldb/Host/Host.h
@@ -464,6 +464,34 @@ public:
                  FileSpec &file_spec);
 
     //------------------------------------------------------------------
+    /// Creates a temporary file in the specified directory.
+    ///
+    /// Operating systems provide different levels of support when it
+    /// comes to creating temporary files.  This function abstracts
+    /// that logic into a platform-agnostic interface.
+    ///
+    /// @param[in] directory
+    ///     The folder in which to create the temporary file.
+    ///
+    /// @param[in] pathTemplate
+    ///     A templated used to determine how to name the file.  Occurrences
+    ///     of the character '%' are replaced with random symbols in [0-9a-f]
+    ///
+    /// @param[out] result
+    ///     A FileSpec representing the path that was created.  The caller
+    ///     should check the resulting path to get the actual filename that
+    ///     was created.
+    ///
+    /// @return
+    ///     A file descriptor referring to the newly created temporary file,
+    ///     or -1 if the file could not be created.
+    //------------------------------------------------------------------
+    static int
+    CreateTemporaryFile (const char *directory,
+                         const char *pathTemplate,
+                         FileSpec &result);
+
+    //------------------------------------------------------------------
     /// Set a string that can be displayed if host application crashes.
     ///
     /// Some operating systems have the ability to print a description
diff --git a/source/API/SBHostOS.cpp b/source/API/SBHostOS.cpp
index b3c7bc5..2d0c855 100644
--- a/source/API/SBHostOS.cpp
+++ b/source/API/SBHostOS.cpp
@@ -49,6 +49,17 @@ SBHostOS::GetLLDBPath (lldb::PathType path_type)
     return sb_fspec;
 }
 
+int
+SBHostOS::CreateTemporaryFile (const char *directory,
+                               const char *pathTemplate,
+                               lldb::SBFileSpec &result)
+{
+    FileSpec fsresult;
+    return Host::CreateTemporaryFile(directory, pathTemplate, fsresult);
+    result.SetFileSpec(fsresult);
+}
+
+
 lldb::thread_t
 SBHostOS::ThreadCreate
 (
diff --git a/source/Host/common/Host.cpp b/source/Host/common/Host.cpp
index df1c787..2f582ef 100644
--- a/source/Host/common/Host.cpp
+++ b/source/Host/common/Host.cpp
@@ -75,6 +75,7 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/Host.h"
+#include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
 
@@ -1397,6 +1398,20 @@ Host::GetLLDBPath (PathType path_type, FileSpec &file_spec)
     return false;
 }
 
+int
+Host::CreateTemporaryFile (const char *directory,
+                           const char *pathTemplate,
+                           FileSpec &result)
+{
+    FileSpec templateFileSpec(directory, false);
+    templateFileSpec.AppendPathComponent(pathTemplate);
+    int result_fd = -1;
+    llvm::SmallString<64> result_path;
+    std::error_code error = llvm::sys::fs::createUniqueFile(templateFileSpec.GetPath(), result_fd, result_path);
+    return (error) ? -1 : result_fd;
+}
+
+
 
 bool
 Host::GetHostname (std::string &s)
diff --git a/tools/driver/Driver.cpp b/tools/driver/Driver.cpp
index 0d0d03d..7f79e69 100644
--- a/tools/driver/Driver.cpp
+++ b/tools/driver/Driver.cpp
@@ -904,13 +904,13 @@ Driver::MainLoop ()
     // so we can then run the command interpreter using the file contents. 
     if (commands_stream.GetData() && commands_stream.GetSize())
     {
-        char lldb_cmds_file[PATH_MAX];
+        char lldb_cmds_dir[PATH_MAX];
         SBFileSpec lldb_temp_dir_spec = SBHostOS::GetLLDBPath (lldb::ePathTypeLLDBTempSystemDir);
-        lldb_temp_dir_spec.SetFilename("lldb-cmds.XXXXXX");
         
-        if (lldb_temp_dir_spec.GetPath(lldb_cmds_file, sizeof(lldb_cmds_file)))
+        if (lldb_temp_dir_spec.GetPath(lldb_cmds_dir, sizeof(lldb_cmds_dir)))
         {
-            int fd = mkstemp(lldb_cmds_file);
+            SBFileSpec lldb_cmds_file_spec;
+            int fd = SBHostOS::CreateTemporaryFile(lldb_cmds_dir, "lldb-cmds.%%%%%%", lldb_cmds_file_spec);
             if (fd == -1)
             {
                 fprintf(stderr, "error: can't create temporary file for LLDB commands\n");
@@ -930,7 +930,8 @@ Driver::MainLoop ()
             
             // Now re-open the file so we can use it as an input file handle for the real
             // command interpreter
-            FILE *commands_file = ::fopen(lldb_cmds_file, "r");
+            lldb_cmds_file_spec.GetPath(lldb_cmds_dir, sizeof(lldb_cmds_dir));
+            FILE *commands_file = ::fopen(lldb_cmds_dir, "r");
             if (commands_file)
             {
                 // Hand ownership over to the debugger for "commands_file".
@@ -939,7 +940,7 @@ Driver::MainLoop ()
             }
             else
             {
-                fprintf(stderr, "error: fopen(\"%s\", \"r\") failed (errno = %i) when trying to open LLDB commands file\n", lldb_cmds_file, errno);
+                fprintf(stderr, "error: fopen(\"%s\", \"r\") failed (errno = %i) when trying to open LLDB commands file\n", lldb_cmds_dir, errno);
                 exit (3);
             }
         }


More information about the lldb-commits mailing list