fix windows case

This commit is contained in:
David Rose 2007-05-13 17:32:47 +00:00
parent 83967af7dc
commit 083ae71bac
2 changed files with 68 additions and 16 deletions

View File

@ -28,39 +28,82 @@ VertexDataSaveFile(const Filename &directory, const string &prefix,
size_t max_size) : size_t max_size) :
_allocator(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. // Try to open and lock a writable temporary filename.
int index = 0; int index = 0;
while (true) { while (true) {
++index; ++index;
ostringstream strm; ostringstream strm;
strm << prefix << "_" << index << ".dat"; strm << prefix << "_" << index << ".dat";
string basename = strm.str(); string basename = strm.str();
_filename = Filename(directory, basename); _filename = Filename(dir, basename);
string os_specific = _filename.to_os_specific(); 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 #ifdef _WIN32
// Windows case. // Windows case.
_handle = CreateFile(os_specific.c_str(), GENERIC_READ | GENERIC_WRITE, _handle = CreateFile(os_specific.c_str(), GENERIC_READ | GENERIC_WRITE,
0, NULL, CREATE_ALWAYS, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE | FILE_FLAG_RANDOM_ACCESS, FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE | FILE_FLAG_RANDOM_ACCESS,
NULL); NULL);
if (_handle == INVALID_HANDLE_VALUE) { if (_handle != INVALID_HANDLE_VALUE) {
// Couldn't open the file. Either the directory was bad, or the // The file was successfully opened and locked.
// file was locked.
DWORD err = GetLastError();
if (err == ERROR_SHARING_VIOLATION) {
// Try the next file.
break; break;
} else {
// Couldn't open the file. Either the directory was bad, or the
// file was already locked by another.
DWORD err = GetLastError();
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. // Couldn't lock the file. Try the next one.
// TODO: handle this
} }
#else #else
// Posix case. // Posix case.
_fd = open(os_specific.c_str(), O_RDWR | O_CREAT, 0666); _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 // Now try to lock the file, so we can be sure that no other
// process is simultaneously writing to the same save file. // 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. // case there's an old version of the file we picked up.
ftruncate(_fd, 0); ftruncate(_fd, 0);
// On Unix, it's safe to unlink (delete) the temporary file after // On Unix, it's safe to unlink (delete) the temporary file
// it's been opened. The file remains open, but disappears from // after it's been opened. The file remains open, but
// the directory. This ensures it won't accidentally get left // disappears from the directory. This is kind of like
// behind should this process crash without closing and deleting // DELETE_ON_CLOSE, to ensure the temporary file won't
// the file cleanly. // accidentally get left behind, except it's a little more
//unlink(os_specific.c_str()); // proactive.
//_filename = Filename(); unlink(os_specific.c_str());
_filename = Filename();
break; break;
} }
@ -84,6 +128,8 @@ VertexDataSaveFile(const Filename &directory, const string &prefix,
close(_fd); close(_fd);
#endif // _WIN32 #endif // _WIN32
} }
_is_valid = true;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -103,9 +149,14 @@ VertexDataSaveFile::
} }
#endif // _WIN32 #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()) { if (!_filename.empty()) {
_filename.unlink(); _filename.unlink();
} }
*/
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

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