Skip to content
Snippets Groups Projects
Commit 8b6b93b4 authored by Alexander van Amesfoort's avatar Alexander van Amesfoort
Browse files

Task #4643: add THROW_SYSCALL() macro and remove macro to generate...

Task #4643: add THROW_SYSCALL() macro and remove macro to generate SystemCallException subclass. Only used once for BindException. Removed that w/ perm from author (Jan David). The distinction can now made in the syscall name, which is less clean, but alternatives aren't better.
parent 58bbced3
No related branches found
No related tags found
No related merge requests found
......@@ -31,6 +31,14 @@
namespace LOFAR {
// Use THROW_SYSCALL(...) below instead of 'throw SystemCallException(...)'
// to enforce sampling errno right after the syscall before it can be clobbered.
#define THROW_SYSCALL(msg) \
do { \
int err = errno; \
throw LOFAR::SystemCallException(msg, err, THROW_ARGS); \
} while (0)
class SystemCallException : public Exception
{
public:
......@@ -44,27 +52,17 @@ class SystemCallException : public Exception
virtual ~SystemCallException() throw();
virtual const std::string &type() const;
const std::string& syscall() const;
const int error;
private:
static std::string errorMessage(int error);
};
#define SYSTEMCALLEXCEPTION_CLASS(excp,super) \
class excp : public super \
{ \
public: \
excp(const std::string& syscall, int error = errno, \
const std::string& file="", \
int line=0, const std::string& function="", \
Backtrace* bt=0) : \
super(syscall, error, file, line, function, bt) {} \
virtual const std::string& type() const { \
static const std::string itsType(#excp); \
return itsType; \
} \
}
const std::string syscallName;
};
} // namespace LOFAR
#endif
......@@ -32,7 +32,8 @@ namespace LOFAR {
SystemCallException::SystemCallException(const std::string &syscall, int error, const std::string& file, int line,
const std::string& func, Backtrace* bt) throw()
: Exception(syscall + ": " + errorMessage(error), file, line, func, bt),
error(error)
error(error),
syscallName(syscall)
{
}
......@@ -49,6 +50,12 @@ const std::string& SystemCallException::type() const
}
const std::string& SystemCallException::syscall() const
{
return syscallName;
}
std::string SystemCallException::errorMessage(int error)
{
char buffer[128];
......@@ -65,5 +72,5 @@ std::string SystemCallException::errorMessage(int error)
#endif
}
} // namespace LOFAR
......@@ -37,7 +37,6 @@ class SocketStream : public FileDescriptorBasedStream
{
public:
EXCEPTION_CLASS(TimeOutException, LOFAR::Exception);
SYSTEMCALLEXCEPTION_CLASS(BindException, LOFAR::SystemCallException);
enum Protocol {
TCP, UDP
......
......@@ -144,14 +144,15 @@ SocketStream::SocketStream(const std::string &hostname, uint16 _port, Protocol p
throw SystemCallException("setsockopt(SO_REUSEADDR)", errno, THROW_ARGS);
if (bind(fd, result->ai_addr, result->ai_addrlen) < 0)
throw BindException("bind", errno, THROW_ARGS);
throw SystemCallException("bind", errno, THROW_ARGS);
if (protocol == TCP) {
listen_sk = fd;
fd = -1;
if (listen(listen_sk, 5) < 0)
throw BindException("listen", errno, THROW_ARGS);
int listenBacklog = 15;
if (listen(listen_sk, listenBacklog) < 0)
throw SystemCallException("listen", errno, THROW_ARGS);
if (doAccept)
accept(deadline);
......@@ -168,12 +169,13 @@ SocketStream::SocketStream(const std::string &hostname, uint16 _port, Protocol p
throw;
}
} catch (BindException &) {
if (mode == Server && autoPort) {
continue;
} else {
throw;
} catch (SystemCallException &exc) {
if ( (exc.syscall() == "bind" || exc.syscall() == "listen") &&
mode == Server && autoPort ) {
continue; // try listening on / binding to another server port
}
throw;
}
}
}
......
......@@ -51,10 +51,14 @@ void start()
// found a valid port
LOG_DEBUG_STR( "using TCP port " << PORT );
break;
} catch( SocketStream::BindException& ) {
} catch ( SystemCallException& exc ) {
if (exc.syscall() == "bind" || exc.syscall() == "listen") {
// port is in use -- try the next one
continue;
}
throw;
}
}
if (PORT >= last_port)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment