For PR797:

Make the Win32 code exception free (untested/uncompiled) which forced some
interface changes which had ripple effect. This should be the last of 797.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@29884 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Reid Spencer
2006-08-25 21:37:17 +00:00
parent dcea140073
commit 0554575567
11 changed files with 70 additions and 79 deletions

View File

@ -134,7 +134,7 @@ namespace sys {
/// areas of memory after this call. /// areas of memory after this call.
/// @throws std::string if an error occurs /// @throws std::string if an error occurs
/// @brief Set the size of the file and memory mapping. /// @brief Set the size of the file and memory mapping.
void size(size_t new_size); bool size(size_t new_size, std::string* ErrMsg = 0);
void close() { if (info_) terminate(); } void close() { if (info_) terminate(); }

View File

@ -24,13 +24,13 @@ namespace sys {
/// This function registers signal handlers to ensure that if a signal gets /// This function registers signal handlers to ensure that if a signal gets
/// delivered that the named file is removed. /// delivered that the named file is removed.
/// @brief Remove a file if a fatal signal occurs. /// @brief Remove a file if a fatal signal occurs.
void RemoveFileOnSignal(const Path &Filename); bool RemoveFileOnSignal(const Path &Filename, std::string* ErrMsg = 0);
/// This function registers a signal handler to ensure that if a fatal signal /// This function registers a signal handler to ensure that if a fatal signal
/// gets delivered to the process that the named directory and all its /// gets delivered to the process that the named directory and all its
/// contents are removed. /// contents are removed.
/// @brief Remove a directory if a fatal signal occurs. /// @brief Remove a directory if a fatal signal occurs.
void RemoveDirectoryOnSignal(const Path& path); bool RemoveDirectoryOnSignal(const Path& path, std::string* ErrMsg = 0);
/// When an error signal (such as SIBABRT or SIGSEGV) is delivered to the /// When an error signal (such as SIBABRT or SIGSEGV) is delivered to the
/// process, print a stack trace and then exit. /// process, print a stack trace and then exit.

View File

@ -122,7 +122,7 @@ size_t MappedFile::size() const {
return info_->Size; return info_->Size;
} }
void MappedFile::size(size_t new_size) { bool MappedFile::size(size_t new_size, std::string* ErrMsg) {
assert(info_ && "MappedFile not initialized"); assert(info_ && "MappedFile not initialized");
// Take the mapping out of memory // Take the mapping out of memory
@ -140,12 +140,14 @@ void MappedFile::size(size_t new_size) {
if (new_size > cur_size) { if (new_size > cur_size) {
// Ensure we can allocate at least the idodes necessary to handle the // Ensure we can allocate at least the idodes necessary to handle the
// file size requested. // file size requested.
::lseek(info_->FD, new_size, SEEK_SET); if ((off_t)-1 == ::lseek(info_->FD, new_size, SEEK_SET))
::write(info_->FD, "\0", 1); return MakeErrMsg(ErrMsg, "Can't lseek: ");
if (-1 == ::write(info_->FD, "\0", 1))
return MakeErrMsg(ErrMsg, "Can't write: ");
} }
// Put the mapping back into memory. // Put the mapping back into memory.
this->map(0); return this->map(ErrMsg);
} }
} }

View File

@ -154,7 +154,7 @@ void sys::SetInterruptFunction(void (*IF)()) {
} }
// RemoveFileOnSignal - The public API // RemoveFileOnSignal - The public API
void sys::RemoveFileOnSignal(const sys::Path &Filename) { bool sys::RemoveFileOnSignal(const sys::Path &Filename, std::string* ErrMsg) {
if (FilesToRemove == 0) if (FilesToRemove == 0)
FilesToRemove = new std::vector<sys::Path>; FilesToRemove = new std::vector<sys::Path>;
@ -162,14 +162,18 @@ void sys::RemoveFileOnSignal(const sys::Path &Filename) {
std::for_each(IntSigs, IntSigsEnd, RegisterHandler); std::for_each(IntSigs, IntSigsEnd, RegisterHandler);
std::for_each(KillSigs, KillSigsEnd, RegisterHandler); std::for_each(KillSigs, KillSigsEnd, RegisterHandler);
return false;
} }
// RemoveDirectoryOnSignal - The public API // RemoveDirectoryOnSignal - The public API
void sys::RemoveDirectoryOnSignal(const sys::Path& path) { bool sys::RemoveDirectoryOnSignal(const sys::Path& path, std::string* ErrMsg) {
// Not a directory? // Not a directory?
sys::FileStatus Status; sys::FileStatus Status;
if (path.getFileStatus(Status) || !Status.isDir) if (path.getFileStatus(Status) || !Status.isDir) {
return; if (ErrMsg)
*ErrMsg = path.toString() + " is not a directory";
return true;
}
if (DirectoriesToRemove == 0) if (DirectoriesToRemove == 0)
DirectoriesToRemove = new std::vector<sys::Path>; DirectoriesToRemove = new std::vector<sys::Path>;
@ -178,6 +182,7 @@ void sys::RemoveDirectoryOnSignal(const sys::Path& path) {
std::for_each(IntSigs, IntSigsEnd, RegisterHandler); std::for_each(IntSigs, IntSigsEnd, RegisterHandler);
std::for_each(KillSigs, KillSigsEnd, RegisterHandler); std::for_each(KillSigs, KillSigsEnd, RegisterHandler);
return false;
} }
/// PrintStackTraceOnErrorSignal - When an error signal (such as SIBABRT or /// PrintStackTraceOnErrorSignal - When an error signal (such as SIBABRT or

View File

@ -94,7 +94,7 @@ inline bool MakeErrMsg(
// but, oh well, just use a generic message // but, oh well, just use a generic message
sprintf(buffer, "Error #%d", errnum); sprintf(buffer, "Error #%d", errnum);
#endif #endif
*ErrMsg = buffer; *ErrMsg = prefix + buffer;
return true; return true;
} }

View File

@ -65,16 +65,6 @@ DynamicLibrary::DynamicLibrary() : handle(0) {
OpenedHandles.push_back((HMODULE)handle); OpenedHandles.push_back((HMODULE)handle);
} }
DynamicLibrary::DynamicLibrary(const char*filename) : handle(0) {
HMODULE a_handle = LoadLibrary(filename);
if (a_handle == 0)
ThrowError(std::string(filename) + ": Can't open : ");
handle = a_handle;
OpenedHandles.push_back(a_handle);
}
DynamicLibrary::~DynamicLibrary() { DynamicLibrary::~DynamicLibrary() {
if (handle == 0) if (handle == 0)
return; return;
@ -100,7 +90,7 @@ bool DynamicLibrary::LoadLibraryPermanently(const char *filename,
HMODULE a_handle = LoadLibrary(filename); HMODULE a_handle = LoadLibrary(filename);
if (a_handle == 0) if (a_handle == 0)
return GetError(std::string(filename) + ": Can't open : ", ErrMsg); return MakeErrMsg(ErrMsg, std::string(filename) + ": Can't open : ");
OpenedHandles.push_back(a_handle); OpenedHandles.push_back(a_handle);
} else { } else {

View File

@ -27,7 +27,7 @@ struct sys::MappedFileInfo {
size_t size; size_t size;
}; };
void MappedFile::initialize() { bool MappedFile::initialize(std::string* ErrMsg) {
assert(!info_); assert(!info_);
info_ = new MappedFileInfo; info_ = new MappedFileInfo;
info_->hFile = INVALID_HANDLE_VALUE; info_->hFile = INVALID_HANDLE_VALUE;
@ -42,7 +42,8 @@ void MappedFile::initialize() {
if (info_->hFile == INVALID_HANDLE_VALUE) { if (info_->hFile == INVALID_HANDLE_VALUE) {
delete info_; delete info_;
info_ = NULL; info_ = NULL;
ThrowError(std::string("Can't open file: ") + path_.toString()); return MakeErrMsg(ErrMsg,
std::string("Can't open file: ") + path_.toString());
} }
LARGE_INTEGER size; LARGE_INTEGER size;
@ -51,7 +52,8 @@ void MappedFile::initialize() {
CloseHandle(info_->hFile); CloseHandle(info_->hFile);
delete info_; delete info_;
info_ = NULL; info_ = NULL;
ThrowError(std::string("Can't get size of file: ") + path_.toString()); return MakeErrMsg(ErrMsg,
std::string("Can't get size of file: ") + path_.toString());
} }
} }
@ -75,7 +77,7 @@ void MappedFile::unmap() {
} }
} }
void* MappedFile::map() { void* MappedFile::map(std::string* ErrMsg) {
if (!isMapped()) { if (!isMapped()) {
DWORD prot = PAGE_READONLY; DWORD prot = PAGE_READONLY;
if (options_ & EXEC_ACCESS) if (options_ & EXEC_ACCESS)
@ -83,15 +85,18 @@ void* MappedFile::map() {
else if (options_ & WRITE_ACCESS) else if (options_ & WRITE_ACCESS)
prot = PAGE_READWRITE; prot = PAGE_READWRITE;
info_->hMapping = CreateFileMapping(info_->hFile, NULL, prot, 0, 0, NULL); info_->hMapping = CreateFileMapping(info_->hFile, NULL, prot, 0, 0, NULL);
if (info_->hMapping == NULL) if (info_->hMapping == NULL) {
ThrowError(std::string("Can't map file: ") + path_.toString()); MakeErrMsg(ErrMsg, std::string("Can't map file: ") + path_.toString());
return 0;
}
prot = (options_ & WRITE_ACCESS) ? FILE_MAP_WRITE : FILE_MAP_READ; prot = (options_ & WRITE_ACCESS) ? FILE_MAP_WRITE : FILE_MAP_READ;
base_ = MapViewOfFileEx(info_->hMapping, prot, 0, 0, 0, NULL); base_ = MapViewOfFileEx(info_->hMapping, prot, 0, 0, 0, NULL);
if (base_ == NULL) { if (base_ == NULL) {
CloseHandle(info_->hMapping); CloseHandle(info_->hMapping);
info_->hMapping = NULL; info_->hMapping = NULL;
ThrowError(std::string("Can't map file: ") + path_.toString()); MakeErrMsg(ErrMsg, std::string("Can't map file: ") + path_.toString());
return 0;
} }
} }
return base_; return base_;
@ -102,7 +107,7 @@ size_t MappedFile::size() const {
return info_->size; return info_->size;
} }
void MappedFile::size(size_t new_size) { bool MappedFile::size(size_t new_size, std::string* ErrMsg) {
assert(info_ && "MappedFile not initialized"); assert(info_ && "MappedFile not initialized");
// Take the mapping out of memory. // Take the mapping out of memory.
@ -117,14 +122,16 @@ void MappedFile::size(size_t new_size) {
LARGE_INTEGER eof; LARGE_INTEGER eof;
eof.QuadPart = new_size; eof.QuadPart = new_size;
if (!SetFilePointerEx(info_->hFile, eof, NULL, FILE_BEGIN)) if (!SetFilePointerEx(info_->hFile, eof, NULL, FILE_BEGIN))
ThrowError(std::string("Can't set end of file: ") + path_.toString()); return MakeErrMsg(ErrMsg,
std::string("Can't set end of file: ") + path_.toString());
if (!SetEndOfFile(info_->hFile)) if (!SetEndOfFile(info_->hFile))
ThrowError(std::string("Can't set end of file: ") + path_.toString()); return MakeErrMsg(ErrMsg,
std::string("Can't set end of file: ") + path_.toString());
info_->size = new_size; info_->size = new_size;
} }
// Remap the file. // Remap the file.
map(); return map(ErrMsg);
} }
} }

View File

@ -36,7 +36,7 @@ MemoryBlock Memory::AllocateRWX(unsigned NumBytes,
void *pa = VirtualAlloc(NULL, NumPages*pageSize, MEM_COMMIT, void *pa = VirtualAlloc(NULL, NumPages*pageSize, MEM_COMMIT,
PAGE_EXECUTE_READWRITE); PAGE_EXECUTE_READWRITE);
if (pa == NULL) { if (pa == NULL) {
GetError("Can't allocate RWX Memory: ", ErrMsg); MakeErrMsg(ErrMsg, "Can't allocate RWX Memory: ");
return MemoryBlock(); return MemoryBlock();
} }
@ -49,7 +49,7 @@ MemoryBlock Memory::AllocateRWX(unsigned NumBytes,
bool Memory::ReleaseRWX(MemoryBlock &M, std::string *ErrMsg) { bool Memory::ReleaseRWX(MemoryBlock &M, std::string *ErrMsg) {
if (M.Address == 0 || M.Size == 0) return false; if (M.Address == 0 || M.Size == 0) return false;
if (!VirtualFree(M.Address, 0, MEM_RELEASE)) if (!VirtualFree(M.Address, 0, MEM_RELEASE))
return GetError("Can't release RWX Memory: ", ErrMsg); return MakeErrMsg(ErrMsg, "Can't release RWX Memory: ");
return false; return false;
} }

View File

@ -292,8 +292,8 @@ bool
Path::getFileStatus(FileStatus &info, std::string *ErrStr) const { Path::getFileStatus(FileStatus &info, std::string *ErrStr) const {
WIN32_FILE_ATTRIBUTE_DATA fi; WIN32_FILE_ATTRIBUTE_DATA fi;
if (!GetFileAttributesEx(path.c_str(), GetFileExInfoStandard, &fi)) if (!GetFileAttributesEx(path.c_str(), GetFileExInfoStandard, &fi))
return GetError("getStatusInfo():" + std::string(path) + return MakeErrMsg(ErrStr, "getStatusInfo():" + std::string(path) +
": Can't get status: ", ErrStr); ": Can't get status: ");
info.fileSize = fi.nFileSizeHigh; info.fileSize = fi.nFileSizeHigh;
info.fileSize <<= sizeof(fi.nFileSizeHigh)*8; info.fileSize <<= sizeof(fi.nFileSizeHigh)*8;
@ -547,7 +547,7 @@ Path::eraseFromDisk(bool remove_contents, std::string *ErrStr) const {
// attribute first. // attribute first.
if (attr & FILE_ATTRIBUTE_READONLY) { if (attr & FILE_ATTRIBUTE_READONLY) {
if (!SetFileAttributes(path.c_str(), attr & ~FILE_ATTRIBUTE_READONLY)) if (!SetFileAttributes(path.c_str(), attr & ~FILE_ATTRIBUTE_READONLY))
return GetError(path + ": Can't destroy file: ", ErrStr); return MakeErrMsg(ErrStr, path + ": Can't destroy file: ");
} }
if (!DeleteFile(path.c_str())) if (!DeleteFile(path.c_str()))
@ -593,7 +593,7 @@ Path::eraseFromDisk(bool remove_contents, std::string *ErrStr) const {
FindClose(h); FindClose(h);
if (err != ERROR_NO_MORE_FILES) { if (err != ERROR_NO_MORE_FILES) {
SetLastError(err); SetLastError(err);
return GetError(path + ": Can't read directory: ", ErrStr); return MakeErrMsg(ErrStr, path + ": Can't read directory: ");
} }
for (std::vector<Path>::iterator I = list.begin(); I != list.end(); for (std::vector<Path>::iterator I = list.begin(); I != list.end();
@ -603,14 +603,14 @@ Path::eraseFromDisk(bool remove_contents, std::string *ErrStr) const {
} }
} else { } else {
if (GetLastError() != ERROR_FILE_NOT_FOUND) if (GetLastError() != ERROR_FILE_NOT_FOUND)
return GetError(path + ": Can't read directory: ", ErrStr); return MakeErrMsg(ErrStr, path + ": Can't read directory: ");
} }
} }
pathname[lastchar] = 0; pathname[lastchar] = 0;
if (!RemoveDirectory(pathname)) if (!RemoveDirectory(pathname))
return GetError(std::string(pathname) + ": Can't destroy directory: ", return MakeErrMsg(ErrStr,
ErrStr); std::string(pathname) + ": Can't destroy directory: ");
return false; return false;
} }
// It appears the path doesn't exist. // It appears the path doesn't exist.
@ -671,7 +671,7 @@ Path::setStatusInfoOnDisk(const FileStatus &si, std::string *ErrStr) const {
DWORD err = GetLastError(); DWORD err = GetLastError();
CloseHandle(h); CloseHandle(h);
SetLastError(err); SetLastError(err);
return GetError(path + ": GetFileInformationByHandle: ", ErrStr); return MakeErrMsg(ErrStr, path + ": GetFileInformationByHandle: ");
} }
FILETIME ft; FILETIME ft;
@ -681,7 +681,7 @@ Path::setStatusInfoOnDisk(const FileStatus &si, std::string *ErrStr) const {
CloseHandle(h); CloseHandle(h);
if (!ret) { if (!ret) {
SetLastError(err); SetLastError(err);
return GetError(path + ": SetFileTime: ", ErrStr); return MakeErrMsg(path + ": SetFileTime: ");
} }
// Best we can do with Unix permission bits is to interpret the owner // Best we can do with Unix permission bits is to interpret the owner
@ -690,13 +690,13 @@ Path::setStatusInfoOnDisk(const FileStatus &si, std::string *ErrStr) const {
if (bhfi.dwFileAttributes & FILE_ATTRIBUTE_READONLY) { if (bhfi.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {
if (!SetFileAttributes(path.c_str(), if (!SetFileAttributes(path.c_str(),
bhfi.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY)) bhfi.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY))
return GetError(path + ": SetFileAttributes: ", ErrStr); return MakeErrMsg(ErrStr, path + ": SetFileAttributes: ");
} }
} else { } else {
if (!(bhfi.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) { if (!(bhfi.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) {
if (!SetFileAttributes(path.c_str(), if (!SetFileAttributes(path.c_str(),
bhfi.dwFileAttributes | FILE_ATTRIBUTE_READONLY)) bhfi.dwFileAttributes | FILE_ATTRIBUTE_READONLY))
return GetError(path + ": SetFileAttributes: ", ErrStr); return MakeErrMsg(ErrStr, path + ": SetFileAttributes: ");
} }
} }

View File

@ -80,11 +80,14 @@ static void RegisterHandler() {
} }
// RemoveFileOnSignal - The public API // RemoveFileOnSignal - The public API
void sys::RemoveFileOnSignal(const sys::Path &Filename) { bool sys::RemoveFileOnSignal(const sys::Path &Filename, std::string* ErrMsg) {
RegisterHandler(); RegisterHandler();
if (CleanupExecuted) if (CleanupExecuted) {
throw std::string("Process terminating -- cannot register for removal"); if (ErrMsg)
*ErrMsg = "Process terminating -- cannot register for removal";
return true;
}
if (FilesToRemove == NULL) if (FilesToRemove == NULL)
FilesToRemove = new std::vector<sys::Path>; FilesToRemove = new std::vector<sys::Path>;
@ -92,25 +95,33 @@ void sys::RemoveFileOnSignal(const sys::Path &Filename) {
FilesToRemove->push_back(Filename); FilesToRemove->push_back(Filename);
LeaveCriticalSection(&CriticalSection); LeaveCriticalSection(&CriticalSection);
return false;
} }
// RemoveDirectoryOnSignal - The public API // RemoveDirectoryOnSignal - The public API
void sys::RemoveDirectoryOnSignal(const sys::Path& path) { bool sys::RemoveDirectoryOnSignal(const sys::Path& path, std::string* ErrMsg) {
// Not a directory? // Not a directory?
sys::FileStatus Status; sys::FileStatus Status;
if (path.getFileStatus(Status) || !Status.isDir) if (path.getFileStatus(Status) || !Status.isDir) {
return; if (ErrMsg)
*ErrMsg = path.toString() + " is not a directory";
return true;
}
RegisterHandler(); RegisterHandler();
if (CleanupExecuted) if (CleanupExecuted) {
throw std::string("Process terminating -- cannot register for removal"); if (ErrMsg)
*ErrMsg = "Process terminating -- cannot register for removal";
return true;
}
if (DirectoriesToRemove == NULL) if (DirectoriesToRemove == NULL)
DirectoriesToRemove = new std::vector<sys::Path>; DirectoriesToRemove = new std::vector<sys::Path>;
DirectoriesToRemove->push_back(path); DirectoriesToRemove->push_back(path);
LeaveCriticalSection(&CriticalSection); LeaveCriticalSection(&CriticalSection);
return false;
} }
/// PrintStackTraceOnErrorSignal - When an error signal (such as SIBABRT or /// PrintStackTraceOnErrorSignal - When an error signal (such as SIBABRT or

View File

@ -24,26 +24,6 @@
#include <cassert> #include <cassert>
#include <string> #include <string>
inline bool GetError(const std::string &Prefix, std::string *Dest) {
if (Dest == 0) return true;
char *buffer = NULL;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
NULL, GetLastError(), 0, (LPSTR)&buffer, 1, NULL);
*Dest = Prefix + buffer;
LocalFree(buffer);
return true;
}
inline void ThrowError(const std::string& msg) {
char *buffer = NULL;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
NULL, GetLastError(), 0, (LPSTR)&buffer, 1, NULL);
std::string s(msg);
s += buffer;
LocalFree(buffer);
throw s;
}
inline bool MakeErrMsg(std::string* ErrMsg, const std::string& prefix) { inline bool MakeErrMsg(std::string* ErrMsg, const std::string& prefix) {
if (!ErrMsg) if (!ErrMsg)
return true; return true;
@ -55,10 +35,6 @@ inline bool MakeErrMsg(std::string* ErrMsg, const std::string& prefix) {
return true; return true;
} }
inline void ThrowErrno(const std::string& prefix) {
ThrowError(prefix + ": " + strerror(errno));
}
inline void MakeErrnoMsg(std::string* ErrMsg, const std::string & prefix) { inline void MakeErrnoMsg(std::string* ErrMsg, const std::string & prefix) {
MakeErrorMsg(prefix + ": " + strerror(errno)); MakeErrorMsg(prefix + ": " + strerror(errno));
} }