aboutsummaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2024-09-10 16:55:32 +0200
committerPierre Ossman <ossman@cendio.se>2024-10-09 13:37:08 +0200
commit40df30d258ebfd24a447fababc649867c24513d8 (patch)
treee29c3abaac640eb1cfe951cae4ce4fe6896c8029 /common
parent56b3460aa318b650f12833ba119fa6decb930148 (diff)
downloadtigervnc-40df30d258ebfd24a447fababc649867c24513d8.tar.gz
tigervnc-40df30d258ebfd24a447fababc649867c24513d8.zip
Split SystemException to handle Windows
Windows has (at least) two error namespaces, both errno and GetLastResult(). These overlap, so it is important we keep track of which one we are dealing with. To make things extra problematic, the BSD socket API normally uses errno, but on Windows it has been mapped in to the GetLastResult() namespace. Try to keep better control of this by using separate classes for the namespaces.
Diffstat (limited to 'common')
-rw-r--r--common/os/Mutex.cxx16
-rw-r--r--common/os/Thread.cxx10
-rw-r--r--common/rdr/Exception.cxx28
-rw-r--r--common/rdr/Exception.h21
-rw-r--r--common/rdr/FileInStream.cxx4
-rw-r--r--common/rdr/RandomStream.cxx6
-rw-r--r--common/rfb/SSecurityRSAAES.cxx4
7 files changed, 53 insertions, 36 deletions
diff --git a/common/os/Mutex.cxx b/common/os/Mutex.cxx
index 2a768b4c..b82de415 100644
--- a/common/os/Mutex.cxx
+++ b/common/os/Mutex.cxx
@@ -43,7 +43,7 @@ Mutex::Mutex()
systemMutex = new pthread_mutex_t;
ret = pthread_mutex_init((pthread_mutex_t*)systemMutex, nullptr);
if (ret != 0)
- throw rdr::SystemException("Failed to create mutex", ret);
+ throw rdr::PosixException("Failed to create mutex", ret);
#endif
}
@@ -67,7 +67,7 @@ void Mutex::lock()
ret = pthread_mutex_lock((pthread_mutex_t*)systemMutex);
if (ret != 0)
- throw rdr::SystemException("Failed to lock mutex", ret);
+ throw rdr::PosixException("Failed to lock mutex", ret);
#endif
}
@@ -80,7 +80,7 @@ void Mutex::unlock()
ret = pthread_mutex_unlock((pthread_mutex_t*)systemMutex);
if (ret != 0)
- throw rdr::SystemException("Failed to unlock mutex", ret);
+ throw rdr::PosixException("Failed to unlock mutex", ret);
#endif
}
@@ -97,7 +97,7 @@ Condition::Condition(Mutex* mutex_)
systemCondition = new pthread_cond_t;
ret = pthread_cond_init((pthread_cond_t*)systemCondition, nullptr);
if (ret != 0)
- throw rdr::SystemException("Failed to create condition variable", ret);
+ throw rdr::PosixException("Failed to create condition variable", ret);
#endif
}
@@ -120,14 +120,14 @@ void Condition::wait()
(CRITICAL_SECTION*)mutex->systemMutex,
INFINITE);
if (!ret)
- throw rdr::SystemException("Failed to wait on condition variable", GetLastError());
+ throw rdr::Win32Exception("Failed to wait on condition variable", GetLastError());
#else
int ret;
ret = pthread_cond_wait((pthread_cond_t*)systemCondition,
(pthread_mutex_t*)mutex->systemMutex);
if (ret != 0)
- throw rdr::SystemException("Failed to wait on condition variable", ret);
+ throw rdr::PosixException("Failed to wait on condition variable", ret);
#endif
}
@@ -140,7 +140,7 @@ void Condition::signal()
ret = pthread_cond_signal((pthread_cond_t*)systemCondition);
if (ret != 0)
- throw rdr::SystemException("Failed to signal condition variable", ret);
+ throw rdr::PosixException("Failed to signal condition variable", ret);
#endif
}
@@ -153,6 +153,6 @@ void Condition::broadcast()
ret = pthread_cond_broadcast((pthread_cond_t*)systemCondition);
if (ret != 0)
- throw rdr::SystemException("Failed to broadcast condition variable", ret);
+ throw rdr::PosixException("Failed to broadcast condition variable", ret);
#endif
}
diff --git a/common/os/Thread.cxx b/common/os/Thread.cxx
index 91f7fd07..e99be63e 100644
--- a/common/os/Thread.cxx
+++ b/common/os/Thread.cxx
@@ -66,7 +66,7 @@ void Thread::start()
#ifdef WIN32
*(HANDLE*)threadId = CreateThread(nullptr, 0, startRoutine, this, 0, nullptr);
if (*(HANDLE*)threadId == nullptr)
- throw rdr::SystemException("Failed to create thread", GetLastError());
+ throw rdr::Win32Exception("Failed to create thread", GetLastError());
#else
int ret;
sigset_t all, old;
@@ -76,14 +76,14 @@ void Thread::start()
sigfillset(&all);
ret = pthread_sigmask(SIG_SETMASK, &all, &old);
if (ret != 0)
- throw rdr::SystemException("Failed to mask signals", ret);
+ throw rdr::PosixException("Failed to mask signals", ret);
ret = pthread_create((pthread_t*)threadId, nullptr, startRoutine, this);
pthread_sigmask(SIG_SETMASK, &old, nullptr);
if (ret != 0)
- throw rdr::SystemException("Failed to create thread", ret);
+ throw rdr::PosixException("Failed to create thread", ret);
#endif
running = true;
@@ -99,13 +99,13 @@ void Thread::wait()
ret = WaitForSingleObject(*(HANDLE*)threadId, INFINITE);
if (ret != WAIT_OBJECT_0)
- throw rdr::SystemException("Failed to join thread", GetLastError());
+ throw rdr::Win32Exception("Failed to join thread", GetLastError());
#else
int ret;
ret = pthread_join(*(pthread_t*)threadId, nullptr);
if (ret != 0)
- throw rdr::SystemException("Failed to join thread", ret);
+ throw rdr::PosixException("Failed to join thread", ret);
#endif
}
diff --git a/common/rdr/Exception.cxx b/common/rdr/Exception.cxx
index d5546274..6a03fa54 100644
--- a/common/rdr/Exception.cxx
+++ b/common/rdr/Exception.cxx
@@ -76,11 +76,23 @@ GAIException::GAIException(const char* s, int err_)
strncat(str_, ")", len-1-strlen(str_));
}
-SystemException::SystemException(const char* s, int err_)
+PosixException::PosixException(const char* s, int err_)
+ : Exception("%s", s), err(err_)
+{
+ strncat(str_, ": ", len-1-strlen(str_));
+ strncat(str_, strerror(err), len-1-strlen(str_));
+ strncat(str_, " (", len-1-strlen(str_));
+ char buf[20];
+ sprintf(buf,"%d",err);
+ strncat(str_, buf, len-1-strlen(str_));
+ strncat(str_, ")", len-1-strlen(str_));
+}
+
+#ifdef WIN32
+Win32Exception::Win32Exception(const char* s, unsigned err_)
: Exception("%s", s), err(err_)
{
strncat(str_, ": ", len-1-strlen(str_));
-#ifdef _WIN32
wchar_t *currStr = new wchar_t[len-strlen(str_)];
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr, err, 0, currStr, len-1-strlen(str_), nullptr);
@@ -92,18 +104,10 @@ SystemException::SystemException(const char* s, int err_)
if ((l >= 2) && (str_[l-2] == '\r') && (str_[l-1] == '\n'))
str_[l-2] = 0;
-#else
- strncat(str_, strerror(err), len-1-strlen(str_));
-#endif
strncat(str_, " (", len-1-strlen(str_));
char buf[20];
-#ifdef WIN32
- if (err < 0)
- sprintf(buf, "%x", err);
- else
-#endif
- sprintf(buf,"%d",err);
+ sprintf(buf,"%d",err);
strncat(str_, buf, len-1-strlen(str_));
strncat(str_, ")", len-1-strlen(str_));
}
-
+#endif
diff --git a/common/rdr/Exception.h b/common/rdr/Exception.h
index 1202c37c..c59f7e55 100644
--- a/common/rdr/Exception.h
+++ b/common/rdr/Exception.h
@@ -32,14 +32,27 @@ namespace rdr {
virtual const char* str() const { return str_; }
};
- struct SystemException : public Exception {
+ struct PosixException : public Exception {
int err;
- SystemException(const char* s, int err_);
+ PosixException(const char* s, int err_);
};
- struct SocketException : public SystemException {
- SocketException(const char* text, int err_) : SystemException(text, err_) {}
+#ifdef WIN32
+ struct Win32Exception : public Exception {
+ unsigned err;
+ Win32Exception(const char* s, unsigned err_);
};
+#endif
+
+#ifdef WIN32
+ struct SocketException : public Win32Exception {
+ SocketException(const char* text, unsigned err_) : Win32Exception(text, err_) {}
+ };
+#else
+ struct SocketException : public PosixException {
+ SocketException(const char* text, int err_) : PosixException(text, err_) {}
+ };
+#endif
struct GAIException : public Exception {
int err;
diff --git a/common/rdr/FileInStream.cxx b/common/rdr/FileInStream.cxx
index 4239a238..db646a7e 100644
--- a/common/rdr/FileInStream.cxx
+++ b/common/rdr/FileInStream.cxx
@@ -33,7 +33,7 @@ FileInStream::FileInStream(const char *fileName)
{
file = fopen(fileName, "rb");
if (!file)
- throw SystemException("fopen", errno);
+ throw PosixException("fopen", errno);
}
FileInStream::~FileInStream(void) {
@@ -48,7 +48,7 @@ bool FileInStream::fillBuffer()
size_t n = fread((uint8_t*)end, 1, availSpace(), file);
if (n == 0) {
if (ferror(file))
- throw SystemException("fread", errno);
+ throw PosixException("fread", errno);
if (feof(file))
throw EndOfStream();
return false;
diff --git a/common/rdr/RandomStream.cxx b/common/rdr/RandomStream.cxx
index 9813abdd..449a84c0 100644
--- a/common/rdr/RandomStream.cxx
+++ b/common/rdr/RandomStream.cxx
@@ -89,7 +89,7 @@ bool RandomStream::fillBuffer() {
#ifdef RFB_HAVE_WINCRYPT
if (provider) {
if (!CryptGenRandom(provider, availSpace(), (uint8_t*)end))
- throw rdr::SystemException("unable to CryptGenRandom", GetLastError());
+ throw rdr::Win32Exception("unable to CryptGenRandom", GetLastError());
end += availSpace();
} else {
#else
@@ -97,8 +97,8 @@ bool RandomStream::fillBuffer() {
if (fp) {
size_t n = fread((uint8_t*)end, 1, availSpace(), fp);
if (n <= 0)
- throw rdr::SystemException("reading /dev/urandom or /dev/random failed",
- errno);
+ throw rdr::PosixException("reading /dev/urandom or /dev/random failed",
+ errno);
end += n;
} else {
#else
diff --git a/common/rfb/SSecurityRSAAES.cxx b/common/rfb/SSecurityRSAAES.cxx
index 92b332d6..6dd700ce 100644
--- a/common/rfb/SSecurityRSAAES.cxx
+++ b/common/rfb/SSecurityRSAAES.cxx
@@ -156,7 +156,7 @@ void SSecurityRSAAES::loadPrivateKey()
{
FILE* file = fopen(keyFile, "rb");
if (!file)
- throw rdr::SystemException("failed to open key file", errno);
+ throw rdr::PosixException("failed to open key file", errno);
fseek(file, 0, SEEK_END);
size_t size = ftell(file);
if (size == 0 || size > MaxKeyFileSize) {
@@ -167,7 +167,7 @@ void SSecurityRSAAES::loadPrivateKey()
std::vector<uint8_t> data(size);
if (fread(data.data(), 1, data.size(), file) != size) {
fclose(file);
- throw rdr::SystemException("failed to read key", errno);
+ throw rdr::PosixException("failed to read key", errno);
}
fclose(file);