59 lines · cpp
1//===-- Implementation of puts --------------------------------------------===//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/puts.h"10#include "src/__support/CPP/string_view.h"11#include "src/__support/File/file.h"12 13#include "hdr/types/FILE.h"14#include "src/__support/libc_errno.h"15#include "src/__support/macros/config.h"16#include <stddef.h>17 18namespace LIBC_NAMESPACE_DECL {19 20namespace {21 22// Simple helper to unlock the file once destroyed.23struct ScopedLock {24 ScopedLock(LIBC_NAMESPACE::File *stream) : stream(stream) { stream->lock(); }25 ~ScopedLock() { stream->unlock(); }26 27private:28 LIBC_NAMESPACE::File *stream;29};30 31} // namespace32 33LLVM_LIBC_FUNCTION(int, puts, (const char *__restrict str)) {34 cpp::string_view str_view(str);35 36 // We need to lock the stream to ensure the newline is always appended.37 ScopedLock lock(LIBC_NAMESPACE::stdout);38 39 auto result = LIBC_NAMESPACE::stdout->write_unlocked(str, str_view.size());40 if (result.has_error())41 libc_errno = result.error;42 size_t written = result.value;43 if (str_view.size() != written) {44 // The stream should be in an error state in this case.45 return EOF;46 }47 result = LIBC_NAMESPACE::stdout->write_unlocked("\n", 1);48 if (result.has_error())49 libc_errno = result.error;50 written = result.value;51 if (1 != written) {52 // The stream should be in an error state in this case.53 return EOF;54 }55 return 0;56}57 58} // namespace LIBC_NAMESPACE_DECL59