brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.4 KiB · 68b4ad6 Raw
82 lines · cpp
1//===-- Implementation of perror ------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "src/stdio/perror.h"10#include "src/__support/CPP/string_view.h"11#include "src/__support/File/file.h"12#include "src/__support/StringUtil/error_to_string.h"13#include "src/__support/libc_errno.h"14#include "src/__support/macros/config.h"15 16namespace LIBC_NAMESPACE_DECL {17 18static int write_out(cpp::string_view str_view, File *f) {19  if (str_view.size() > 0) {20    auto result = f->write_unlocked(str_view.data(), str_view.size());21    if (result.has_error())22      return result.error;23  }24  return 0;25}26 27// separate function so that we can return early on error but still get the28// unlock. This function sets errno and should not be called elsewhere.29static void write_sequence(cpp::string_view str_view,30                           cpp::string_view err_str) {31  int write_err;32  // TODO: this seems like there should be some sort of queue system to33  // deduplicate this code.34 35  // FORMAT:36  // if str != nullptr and doesn't start with a null byte:37  //   "[str]: [strerror(errno)]\n"38  // else39  //   "[strerror(errno)]\n"40  if (str_view.size() > 0) {41    write_err = write_out(str_view, LIBC_NAMESPACE::stderr);42    if (write_err != 0) {43      libc_errno = write_err;44      return;45    }46 47    write_err = write_out(": ", LIBC_NAMESPACE::stderr);48    if (write_err != 0) {49      libc_errno = write_err;50      return;51    }52  }53 54  write_err = write_out(err_str, LIBC_NAMESPACE::stderr);55  if (write_err != 0) {56    libc_errno = write_err;57    return;58  }59 60  write_err = write_out("\n", LIBC_NAMESPACE::stderr);61  if (write_err != 0) {62    libc_errno = write_err;63    return;64  }65}66 67LLVM_LIBC_FUNCTION(void, perror, (const char *str)) {68  const char empty_str[1] = {'\0'};69  if (str == nullptr)70    str = empty_str;71  cpp::string_view str_view(str);72 73  cpp::string_view err_str = get_error_string(libc_errno);74 75  // We need to lock the stream to ensure the newline is always appended.76  LIBC_NAMESPACE::stderr->lock();77  write_sequence(str_view, err_str);78  LIBC_NAMESPACE::stderr->unlock();79}80 81} // namespace LIBC_NAMESPACE_DECL82