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) :
_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) {
// Couldn't open the file. Either the directory was bad, or the
// file was locked.
DWORD err = GetLastError();
if (err == ERROR_SHARING_VIOLATION) {
// Try the next file.
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 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.
// 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();
}
*/
}
////////////////////////////////////////////////////////////////////

View File

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