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