1d2024bbcSJoseph Huber //===-- Implementation of puts --------------------------------------------===// 2d2024bbcSJoseph Huber // 3d2024bbcSJoseph Huber // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4d2024bbcSJoseph Huber // See https://llvm.org/LICENSE.txt for license information. 5d2024bbcSJoseph Huber // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6d2024bbcSJoseph Huber // 7d2024bbcSJoseph Huber //===----------------------------------------------------------------------===// 8d2024bbcSJoseph Huber 9d2024bbcSJoseph Huber #include "src/stdio/puts.h" 10d2024bbcSJoseph Huber #include "src/__support/CPP/string_view.h" 11d2024bbcSJoseph Huber #include "src/__support/File/file.h" 12d2024bbcSJoseph Huber 135aed6d67SMichael Jones #include "hdr/types/FILE.h" 14*5ff3ff33SPetr Hosek #include "src/__support/macros/config.h" 15d2024bbcSJoseph Huber #include "src/errno/libc_errno.h" 165aed6d67SMichael Jones #include <stddef.h> 17d2024bbcSJoseph Huber 18*5ff3ff33SPetr Hosek namespace LIBC_NAMESPACE_DECL { 19d2024bbcSJoseph Huber 201bb85fa9SJoseph Huber namespace { 211bb85fa9SJoseph Huber 221bb85fa9SJoseph Huber // Simple helper to unlock the file once destroyed. 231bb85fa9SJoseph Huber struct ScopedLock { 241bb85fa9SJoseph Huber ScopedLock(LIBC_NAMESPACE::File *stream) : stream(stream) { stream->lock(); } 251bb85fa9SJoseph Huber ~ScopedLock() { stream->unlock(); } 261bb85fa9SJoseph Huber 271bb85fa9SJoseph Huber private: 281bb85fa9SJoseph Huber LIBC_NAMESPACE::File *stream; 291bb85fa9SJoseph Huber }; 301bb85fa9SJoseph Huber 311bb85fa9SJoseph Huber } // namespace 321bb85fa9SJoseph Huber 33d2024bbcSJoseph Huber LLVM_LIBC_FUNCTION(int, puts, (const char *__restrict str)) { 34d2024bbcSJoseph Huber cpp::string_view str_view(str); 351bb85fa9SJoseph Huber 361bb85fa9SJoseph Huber // We need to lock the stream to ensure the newline is always appended. 371bb85fa9SJoseph Huber ScopedLock lock(LIBC_NAMESPACE::stdout); 381bb85fa9SJoseph Huber 391bb85fa9SJoseph Huber auto result = LIBC_NAMESPACE::stdout->write_unlocked(str, str_view.size()); 40d2024bbcSJoseph Huber if (result.has_error()) 41d2024bbcSJoseph Huber libc_errno = result.error; 42d2024bbcSJoseph Huber size_t written = result.value; 43d2024bbcSJoseph Huber if (str_view.size() != written) { 44d2024bbcSJoseph Huber // The stream should be in an error state in this case. 45d2024bbcSJoseph Huber return EOF; 46d2024bbcSJoseph Huber } 471bb85fa9SJoseph Huber result = LIBC_NAMESPACE::stdout->write_unlocked("\n", 1); 48d2024bbcSJoseph Huber if (result.has_error()) 49d2024bbcSJoseph Huber libc_errno = result.error; 50d2024bbcSJoseph Huber written = result.value; 51d2024bbcSJoseph Huber if (1 != written) { 52d2024bbcSJoseph Huber // The stream should be in an error state in this case. 53d2024bbcSJoseph Huber return EOF; 54d2024bbcSJoseph Huber } 55d2024bbcSJoseph Huber return 0; 56d2024bbcSJoseph Huber } 57d2024bbcSJoseph Huber 58*5ff3ff33SPetr Hosek } // namespace LIBC_NAMESPACE_DECL 59