blob: 216d9ada47e547d518a8bfed7329379ef31e1020 [file] [log] [blame]
/*
* ====================================================================
* Copyright (c) 2012, PLUMgrid, http://plumgrid.com
*
* This source is subject to the PLUMgrid License.
* All rights reserved.
*
* THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF
* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
* PARTICULAR PURPOSE.
*
* PLUMgrid confidential information, delete if you are not the
* intended recipient.
*
* ====================================================================
*/
#pragma once
#include <exception>
#include <string>
#include <tuple>
#include <cstring>
#include <cerrno>
#include <cstdlib>
#undef NDEBUG
namespace ebpf {
class Exception : public std::exception {
public:
virtual ~Exception() throw() {}
};
class StringException : public Exception {
public:
StringException() : errstr_("unknown") {}
virtual ~StringException() throw() {}
explicit StringException(const std::string& s) : errstr_(s) {}
explicit StringException(const char* s) : errstr_(s) {}
template <typename... Args>
StringException(const char* s, Args... args) {
char x[1024];
snprintf(x, sizeof(x), s, args...);
errstr_.assign(x);
}
virtual const char* what() const throw() {
return errstr_.c_str();
}
protected:
std::string errstr_;
};
class ErrnoException : public StringException {
public:
ErrnoException() : StringException(strerror(errno)) {}
explicit ErrnoException(const std::string& s) : StringException(s + ": " + strerror(errno)) {}
explicit ErrnoException(const std::string& s, int err) : StringException(s + ": " + strerror(err)) {}
};
class SystemException : public StringException {
public:
explicit SystemException(int status) {
if (status == -1) {
errstr_.assign("command not found");
} else {
errstr_.assign("command exited with ");
errstr_ += std::to_string(WEXITSTATUS(status));
}
}
SystemException(int status, const std::string& s) {
if (status == -1) {
errstr_.assign("command not found");
} else {
errstr_.assign("command exited with ");
errstr_ += std::to_string(WEXITSTATUS(status));
}
errstr_ += "; " + s + ": " + strerror(errno);
}
};
class CompilerException : public StringException {
public:
explicit CompilerException(const std::string& s) : StringException(s) {}
template <typename... Args>
CompilerException(const char* s, Args... args) : StringException(s, args...) {}
};
class WatermarkException : public Exception {
public:
WatermarkException() {}
virtual const char* what() const throw() {
return "Reached High Watermark";
}
};
class TerminateException : public Exception {
public:
TerminateException() {}
virtual const char* what() const throw() {
return "Terminated";
}
};
class StatusException : public Exception {
public:
explicit StatusException(int st, const std::string &msg) : st_(st), msg_(msg) {}
virtual const char* what() const throw() {
return msg_.c_str();
}
int status() const { return st_; }
const std::string & message() { return msg_; }
protected:
int st_;
std::string msg_;
};
template <typename... Args>
std::tuple<int, std::string> mkstatus(int ret, const char *fmt, Args... args) {
char buf[1024];
snprintf(buf, sizeof(buf), fmt, args...);
return std::make_tuple(ret, std::string(buf));
}
static inline std::tuple<int, std::string> mkstatus(int ret, const char *msg) {
return std::make_tuple(ret, std::string(msg));
}
static inline std::tuple<int, std::string> mkstatus(int ret) {
return std::make_tuple(ret, std::string());
}
#define TRYT(CMD) \
do { \
int __status = (CMD); \
if (__status != 0) { \
throw StatusException(__status); \
} \
} while (0)
#define TRY2T(CMD) \
do { \
std::tuple<int, std::string> __stp = (CMD); \
if (std::get<0>(__stp) != 0) { \
throw StatusException(std::get<0>(__stp)); \
} \
} while (0)
#define TRY(CMD) \
do { \
int __status = (CMD); \
if (__status != 0) { \
return __status; \
} \
} while (0)
#define TRY2(CMD) \
do { \
std::tuple<int, std::string> __stp = (CMD); \
if (std::get<0>(__stp) != 0) { \
return __stp; \
} \
} while (0)
} // namespace ebpf