github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/test/util/posix_error.cc (about) 1 // Copyright 2018 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include "test/util/posix_error.h" 16 17 #include <cassert> 18 #include <cerrno> 19 #include <cstring> 20 #include <string> 21 22 #include "absl/strings/str_cat.h" 23 24 namespace gvisor { 25 namespace testing { 26 27 std::string PosixError::ToString() const { 28 if (ok()) { 29 return "No Error"; 30 } 31 32 std::string ret; 33 34 char strerrno_buf[1024] = {}; 35 36 auto res = strerror_r(errno_, strerrno_buf, sizeof(strerrno_buf)); 37 38 // The GNU version of strerror_r always returns a non-null char* pointing to a 39 // buffer containing the stringified errno; the XSI version returns a positive 40 // errno which indicates the result of writing the stringified errno into the 41 // supplied buffer. The gymnastics below are needed to support both. 42 #ifndef _GNU_SOURCE 43 if (res != 0) { 44 ret = absl::StrCat("PosixError(errno=", errno_, " strerror_r FAILED(", ret, 45 "))"); 46 } else { 47 ret = absl::StrCat("PosixError(errno=", errno_, " ", strerrno_buf, ")"); 48 } 49 #else 50 ret = absl::StrCat("PosixError(errno=", errno_, " ", res, ")"); 51 #endif 52 53 if (strnlen(msg_, sizeof(msg_)) > 0) { 54 ret.append(" "); 55 ret.append(msg_); 56 } 57 58 return ret; 59 } 60 61 ::std::ostream& operator<<(::std::ostream& os, const PosixError& e) { 62 os << e.ToString(); 63 return os; 64 } 65 66 void PosixErrorIsMatcherCommonImpl::DescribeTo(std::ostream* os) const { 67 *os << "has an errno value that "; 68 code_matcher_.DescribeTo(os); 69 *os << ", and has an error message that "; 70 message_matcher_.DescribeTo(os); 71 } 72 73 void PosixErrorIsMatcherCommonImpl::DescribeNegationTo(std::ostream* os) const { 74 *os << "has an errno value that "; 75 code_matcher_.DescribeNegationTo(os); 76 *os << ", or has an error message that "; 77 message_matcher_.DescribeNegationTo(os); 78 } 79 80 bool PosixErrorIsMatcherCommonImpl::MatchAndExplain( 81 const PosixError& error, 82 ::testing::MatchResultListener* result_listener) const { 83 ::testing::StringMatchResultListener inner_listener; 84 85 inner_listener.Clear(); 86 if (!code_matcher_.MatchAndExplain(error.errno_value(), &inner_listener)) { 87 return false; 88 } 89 90 if (!message_matcher_.Matches(error.message())) { 91 return false; 92 } 93 94 return true; 95 } 96 97 } // namespace testing 98 } // namespace gvisor