xref: /aosp_15_r20/external/llvm-libc/src/stdio/generic/puts.cpp (revision 71db0c75aadcf003ffe3238005f61d7618a3fead)
1*71db0c75SAndroid Build Coastguard Worker //===-- Implementation of puts --------------------------------------------===//
2*71db0c75SAndroid Build Coastguard Worker //
3*71db0c75SAndroid Build Coastguard Worker // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*71db0c75SAndroid Build Coastguard Worker // See https://llvm.org/LICENSE.txt for license information.
5*71db0c75SAndroid Build Coastguard Worker // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*71db0c75SAndroid Build Coastguard Worker //
7*71db0c75SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
8*71db0c75SAndroid Build Coastguard Worker 
9*71db0c75SAndroid Build Coastguard Worker #include "src/stdio/puts.h"
10*71db0c75SAndroid Build Coastguard Worker #include "src/__support/CPP/string_view.h"
11*71db0c75SAndroid Build Coastguard Worker #include "src/__support/File/file.h"
12*71db0c75SAndroid Build Coastguard Worker 
13*71db0c75SAndroid Build Coastguard Worker #include "hdr/types/FILE.h"
14*71db0c75SAndroid Build Coastguard Worker #include "src/__support/macros/config.h"
15*71db0c75SAndroid Build Coastguard Worker #include "src/errno/libc_errno.h"
16*71db0c75SAndroid Build Coastguard Worker #include <stddef.h>
17*71db0c75SAndroid Build Coastguard Worker 
18*71db0c75SAndroid Build Coastguard Worker namespace LIBC_NAMESPACE_DECL {
19*71db0c75SAndroid Build Coastguard Worker 
20*71db0c75SAndroid Build Coastguard Worker namespace {
21*71db0c75SAndroid Build Coastguard Worker 
22*71db0c75SAndroid Build Coastguard Worker // Simple helper to unlock the file once destroyed.
23*71db0c75SAndroid Build Coastguard Worker struct ScopedLock {
ScopedLockLIBC_NAMESPACE_DECL::__anon5123db2a0111::ScopedLock24*71db0c75SAndroid Build Coastguard Worker   ScopedLock(LIBC_NAMESPACE::File *stream) : stream(stream) { stream->lock(); }
~ScopedLockLIBC_NAMESPACE_DECL::__anon5123db2a0111::ScopedLock25*71db0c75SAndroid Build Coastguard Worker   ~ScopedLock() { stream->unlock(); }
26*71db0c75SAndroid Build Coastguard Worker 
27*71db0c75SAndroid Build Coastguard Worker private:
28*71db0c75SAndroid Build Coastguard Worker   LIBC_NAMESPACE::File *stream;
29*71db0c75SAndroid Build Coastguard Worker };
30*71db0c75SAndroid Build Coastguard Worker 
31*71db0c75SAndroid Build Coastguard Worker } // namespace
32*71db0c75SAndroid Build Coastguard Worker 
33*71db0c75SAndroid Build Coastguard Worker LLVM_LIBC_FUNCTION(int, puts, (const char *__restrict str)) {
34*71db0c75SAndroid Build Coastguard Worker   cpp::string_view str_view(str);
35*71db0c75SAndroid Build Coastguard Worker 
36*71db0c75SAndroid Build Coastguard Worker   // We need to lock the stream to ensure the newline is always appended.
37*71db0c75SAndroid Build Coastguard Worker   ScopedLock lock(LIBC_NAMESPACE::stdout);
38*71db0c75SAndroid Build Coastguard Worker 
39*71db0c75SAndroid Build Coastguard Worker   auto result = LIBC_NAMESPACE::stdout->write_unlocked(str, str_view.size());
40*71db0c75SAndroid Build Coastguard Worker   if (result.has_error())
41*71db0c75SAndroid Build Coastguard Worker     libc_errno = result.error;
42*71db0c75SAndroid Build Coastguard Worker   size_t written = result.value;
43*71db0c75SAndroid Build Coastguard Worker   if (str_view.size() != written) {
44*71db0c75SAndroid Build Coastguard Worker     // The stream should be in an error state in this case.
45*71db0c75SAndroid Build Coastguard Worker     return EOF;
46*71db0c75SAndroid Build Coastguard Worker   }
47*71db0c75SAndroid Build Coastguard Worker   result = LIBC_NAMESPACE::stdout->write_unlocked("\n", 1);
48*71db0c75SAndroid Build Coastguard Worker   if (result.has_error())
49*71db0c75SAndroid Build Coastguard Worker     libc_errno = result.error;
50*71db0c75SAndroid Build Coastguard Worker   written = result.value;
51*71db0c75SAndroid Build Coastguard Worker   if (1 != written) {
52*71db0c75SAndroid Build Coastguard Worker     // The stream should be in an error state in this case.
53*71db0c75SAndroid Build Coastguard Worker     return EOF;
54*71db0c75SAndroid Build Coastguard Worker   }
55*71db0c75SAndroid Build Coastguard Worker   return 0;
56*71db0c75SAndroid Build Coastguard Worker }
57*71db0c75SAndroid Build Coastguard Worker 
58*71db0c75SAndroid Build Coastguard Worker } // namespace LIBC_NAMESPACE_DECL
59