github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/test/util/logging.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/logging.h"
    16  
    17  #include <errno.h>
    18  #include <stdint.h>
    19  #include <stdlib.h>
    20  #include <unistd.h>
    21  
    22  namespace gvisor {
    23  namespace testing {
    24  
    25  namespace {
    26  
    27  // We implement this here instead of using test_util to avoid cyclic
    28  // dependencies.
    29  int Write(int fd, const char* buf, size_t size) {
    30    size_t written = 0;
    31    while (written < size) {
    32      int res = write(fd, buf + written, size - written);
    33      if (res < 0 && errno == EINTR) {
    34        continue;
    35      } else if (res <= 0) {
    36        break;
    37      }
    38  
    39      written += res;
    40    }
    41    return static_cast<int>(written);
    42  }
    43  
    44  // Write 32-bit decimal number to fd.
    45  int WriteNumber(int fd, uint32_t val) {
    46    constexpr char kDigits[] = "0123456789";
    47    constexpr int kBase = 10;
    48  
    49    // 10 chars for 32-bit number in decimal, 1 char for the NUL-terminator.
    50    constexpr int kBufferSize = 11;
    51    char buf[kBufferSize];
    52  
    53    // Convert the number to string.
    54    char* s = buf + sizeof(buf) - 1;
    55    size_t size = 0;
    56  
    57    *s = '\0';
    58    do {
    59      s--;
    60      size++;
    61  
    62      *s = kDigits[val % kBase];
    63      val /= kBase;
    64    } while (val);
    65  
    66    return Write(fd, s, size);
    67  }
    68  
    69  }  // namespace
    70  
    71  void CheckFailure(const char* cond, size_t cond_size, const char* msg,
    72                    size_t msg_size, int errno_value) {
    73    constexpr char kCheckFailure[] = "Check failed: ";
    74    Write(2, kCheckFailure, sizeof(kCheckFailure) - 1);
    75    Write(2, cond, cond_size);
    76  
    77    if (msg != nullptr) {
    78      Write(2, ": ", 2);
    79      Write(2, msg, msg_size);
    80    }
    81  
    82    if (errno_value != 0) {
    83      constexpr char kErrnoMessage[] = " (errno ";
    84      Write(2, kErrnoMessage, sizeof(kErrnoMessage) - 1);
    85      WriteNumber(2, errno_value);
    86      Write(2, ")", 1);
    87    }
    88  
    89    Write(2, "\n", 1);
    90  
    91    abort();
    92  }
    93  
    94  }  // namespace testing
    95  }  // namespace gvisor