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