ソースを参照

*** empty log message ***

David Rose 24 年 前
コミット
0aa0b38c5a

+ 46 - 1
dtool/src/dtoolutil/filename.cxx

@@ -16,7 +16,8 @@
 #include "dSearchPath.h"
 #include "executionEnvironment.h"
 
-#include <stdio.h>  // For rename()
+#include <stdio.h>  // For rename() and tempnam()
+#include <time.h>   // for clock() and time()
 #include <sys/stat.h>
 #include <algorithm>
 
@@ -280,6 +281,50 @@ from_os_specific(const string &os_specific, Filename::Type type) {
 #endif
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: Filename::temporary
+//       Access: Public
+//  Description: Generates a temporary filename within the indicated
+//               directory, using the indicated prefix.  If the
+//               directory is empty, a system-defined directory is
+//               chosen instead.
+//
+//               The generated filename did not exist when the
+//               Filename checked, but since it does not specifically
+//               create the file, it is possible that another process
+//               could simultaneously create a file by the same name.
+////////////////////////////////////////////////////////////////////
+Filename Filename::
+temporary(const string &dirname, const string &prefix, Type type) {
+  if (dirname.empty()) {
+    // If we are not given a dirname, use the system tempnam()
+    // function to create a system-defined temporary filename.
+    char *name = tempnam(NULL, prefix.c_str());
+    Filename result(name);
+    free(name);
+    result.set_type(type);
+    return result;
+  }
+
+  // If we *are* given a dirname, then use our own algorithm to make
+  // up a filename within that dirname.  We do that because the system
+  // tempnam() (for instance, under Windows) may ignore the dirname.
+
+  Filename result(dirname, "");
+  result.set_type(type);
+  do {
+    // We take the time of day and multiply it by the process time.
+    // This will give us a very large number, of which we take the
+    // bottom 24 bits and generate a 6-character hex code.
+    int hash = (clock() * time(NULL)) & 0xffffff;
+    char hex_code[10];
+    sprintf(hex_code, "%06x", hash);
+    result.set_basename(prefix + hex_code);
+  } while (result.exists());
+
+  return result;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: Filename::set_fullpath
 //       Access: Public

+ 2 - 0
dtool/src/dtoolutil/filename.h

@@ -73,6 +73,8 @@ PUBLISHED:
 
   static Filename from_os_specific(const string &os_specific, 
 				   Type type = T_general);
+  static Filename temporary(const string &dirname, const string &prefix,
+			    Type type = T_general);
 
   // Assignment is via the = operator.
   INLINE Filename &operator = (const string &filename);

+ 2 - 2
pandatool/src/egg-palettize/eggPalettize.cxx

@@ -608,8 +608,7 @@ run() {
   if (dirname.empty()) {
     dirname = ".";
   }
-  char *name = tempnam(dirname.c_str(), "pi");
-  Filename temp_filename(name);
+  Filename temp_filename = Filename::temporary(dirname, "pi");
 
   if (!state_file.open_write(temp_filename) ||
       !state_file.write_object(pal)) {
@@ -620,6 +619,7 @@ run() {
   }
 
   state_file.close();
+  state_filename.unlink();
   if (!temp_filename.rename_to(state_filename)) {
     nout << "Unable to rename temporary file " 
 	 << FilenameUnifier::make_user_filename(temp_filename) << " to "