1 /* 2 * Copyright (c) 2015 PLUMgrid, Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <cstdio> 20 #include <string> 21 22 namespace ebpf { 23 24 class StatusTuple { 25 public: 26 enum class Code { 27 // Not an error, indicates success. 28 OK = 0, 29 // For any error that is not covered in the existing codes. 30 UNKNOWN, 31 32 INVALID_ARGUMENT, 33 PERMISSION_DENIED, 34 // For any error that was raised when making syscalls. 35 SYSTEM, 36 }; 37 OK()38 static StatusTuple OK() { 39 return StatusTuple(Code::OK, ""); 40 } 41 StatusTuple(int ret)42 StatusTuple(int ret) : ret_(ret) {} 43 StatusTuple(int ret,const char * msg)44 StatusTuple(int ret, const char *msg) : ret_(ret), msg_(msg) {} 45 StatusTuple(int ret,const std::string & msg)46 StatusTuple(int ret, const std::string &msg) : ret_(ret), msg_(msg) {} 47 48 template <typename... Args> StatusTuple(int ret,const char * fmt,Args...args)49 StatusTuple(int ret, const char *fmt, Args... args) : ret_(ret) { 50 char buf[2048]; 51 snprintf(buf, sizeof(buf), fmt, args...); 52 msg_ = std::string(buf); 53 } 54 StatusTuple(Code code,const std::string & msg)55 StatusTuple(Code code, const std::string &msg) : use_enum_code_(true), code_(code), msg_(msg) {} 56 append_msg(const std::string & msg)57 void append_msg(const std::string& msg) { 58 msg_ += msg; 59 } 60 ok()61 bool ok() const { 62 if (use_enum_code_) { 63 return code_ == Code::OK; 64 } 65 return ret_ == 0; 66 } 67 code()68 int code() const { 69 if (use_enum_code_) { 70 return static_cast<int>(code_); 71 } 72 return ret_; 73 } 74 msg()75 const std::string& msg() const { return msg_; } 76 77 private: 78 int ret_; 79 80 bool use_enum_code_ = false; 81 Code code_ = Code::UNKNOWN; 82 83 std::string msg_; 84 }; 85 86 #define TRY2(CMD) \ 87 do { \ 88 ebpf::StatusTuple __stp = (CMD); \ 89 if (!__stp.ok()) { \ 90 return __stp; \ 91 } \ 92 } while (0) 93 94 namespace error { 95 96 #define DECLARE_ERROR(FN, CODE) \ 97 inline StatusTuple FN(const std::string& msg) { \ 98 return StatusTuple(::ebpf::StatusTuple::Code::CODE, msg); \ 99 } \ 100 inline bool Is##FN(const StatusTuple& status) { \ 101 return status.code() == static_cast<int>(::ebpf::StatusTuple::Code::CODE); \ 102 } 103 104 DECLARE_ERROR(Unknown, UNKNOWN) 105 DECLARE_ERROR(InvalidArgument, INVALID_ARGUMENT) 106 DECLARE_ERROR(PermissionDenied, PERMISSION_DENIED) 107 DECLARE_ERROR(System, SYSTEM) 108 109 } // namespace error 110 111 } // namespace ebpf 112