Browse Source

fix windows case

David Rose 18 years ago
parent
commit
083ae71bac
2 changed files with 68 additions and 16 deletions
  1. 67 16
      panda/src/gobj/vertexDataSaveFile.cxx
  2. 1 0
      panda/src/gobj/vertexDataSaveFile.h

+ 67 - 16
panda/src/gobj/vertexDataSaveFile.cxx

@@ -28,39 +28,82 @@ VertexDataSaveFile(const Filename &directory, const string &prefix,
                    size_t max_size) :
   _allocator(max_size)
 {
+  Filename dir;
+  if (directory.empty()) {
+    dir = Filename::get_temp_directory();
+  } else {
+    dir = directory;
+  }
+
+  _is_valid = false;
+
   // Try to open and lock a writable temporary filename.
   int index = 0;
   while (true) {
     ++index;
     ostringstream strm;
     strm << prefix << "_" << index << ".dat";
+
     string basename = strm.str();
-    _filename = Filename(directory, basename);
+    _filename = Filename(dir, basename);
     string os_specific = _filename.to_os_specific();
 
+    if (gobj_cat.is_debug()) {
+      gobj_cat.debug()
+        << "Creating vertex data save file " << os_specific << "\n"; 
+    }
+
 #ifdef _WIN32
     // Windows case.
     _handle = CreateFile(os_specific.c_str(), GENERIC_READ | GENERIC_WRITE,
                          0, NULL, CREATE_ALWAYS, 
                          FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE | FILE_FLAG_RANDOM_ACCESS,
                          NULL);
-    if (_handle == INVALID_HANDLE_VALUE) {
+    if (_handle != INVALID_HANDLE_VALUE) {
+      // The file was successfully opened and locked.
+      break;
+
+    } else {
       // Couldn't open the file.  Either the directory was bad, or the
-      // file was locked.
+      // file was already locked by another.
       DWORD err = GetLastError();
-      if (err == ERROR_SHARING_VIOLATION) {
-        // Try the next file.
-        break;
+
+      if (err != ERROR_SHARING_VIOLATION) {
+        // File couldn't be opened; permission problem or bogus directory.
+        if (!dir.empty()) {
+          // Try the current directory, once.
+          dir = Filename();
+        } else {
+          gobj_cat.error()
+            << "Couldn't open vertex data save file.\n";
+          return;
+        }
       }
 
-      // File couldn't be opened; permission problem or bogus directory.
-      // TODO: handle this
+      // Couldn't lock the file.  Try the next one.
     }
 
 #else
     // Posix case.
     _fd = open(os_specific.c_str(), O_RDWR | O_CREAT, 0666);
-    nassertv(_fd != -1);  // TODO: handle this.
+    if (_fd == -1) {
+      // Couldn't open the file: permissions problem or bad directory.
+      if (!_filename.exists()) {
+        // It must be a bad directory.
+        if (!dir.empty()) {
+          // Try the current directory, once.
+          dir = Filename();
+        } else {
+          gobj_cat.error()
+            << "Couldn't open vertex data save file.\n";
+          return;
+        }
+      }
+
+      // If it's a permissions problem, it might be a user-level
+      // permissions issue.  Continue to the next.
+      continue;
+    }
     
     // Now try to lock the file, so we can be sure that no other
     // process is simultaneously writing to the same save file.
@@ -70,13 +113,14 @@ VertexDataSaveFile(const Filename &directory, const string &prefix,
       // case there's an old version of the file we picked up.
       ftruncate(_fd, 0);
 
-      // On Unix, it's safe to unlink (delete) the temporary file after
-      // it's been opened.  The file remains open, but disappears from
-      // the directory.  This ensures it won't accidentally get left
-      // behind should this process crash without closing and deleting
-      // the file cleanly.
-      //unlink(os_specific.c_str());
-      //_filename = Filename();
+      // On Unix, it's safe to unlink (delete) the temporary file
+      // after it's been opened.  The file remains open, but
+      // disappears from the directory.  This is kind of like
+      // DELETE_ON_CLOSE, to ensure the temporary file won't
+      // accidentally get left behind, except it's a little more
+      // proactive.
+      unlink(os_specific.c_str());
+      _filename = Filename();
       break;
     }
 
@@ -84,6 +128,8 @@ VertexDataSaveFile(const Filename &directory, const string &prefix,
     close(_fd);
 #endif  // _WIN32
   }
+
+  _is_valid = true;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -103,9 +149,14 @@ VertexDataSaveFile::
   }
 #endif  // _WIN32
 
+  // No need to remove the file, since in both above cases we have
+  // already removed it.  And removing it now, after we have closed
+  // and unlocked it, might accidentally remove someone else's copy.
+  /*
   if (!_filename.empty()) {
     _filename.unlink();
   }
+  */
 }
 
 ////////////////////////////////////////////////////////////////////

+ 1 - 0
panda/src/gobj/vertexDataSaveFile.h

@@ -48,6 +48,7 @@ public:
 private:
   SimpleAllocator _allocator;
   Filename _filename;
+  bool _is_valid;
 
 #ifdef _WIN32
   HANDLE _handle;