• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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