| //===-- Implementation of fflush ------------------------------------------===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "src/stdio/fflush.h" |
| #include "src/__support/File/file.h" |
| #include "src/stdio/stderr.h" |
| #include "src/stdio/stdin.h" |
| #include "src/stdio/stdout.h" |
| |
| #include "hdr/types/FILE.h" |
| #include "src/__support/libc_errno.h" |
| #include "src/__support/macros/config.h" |
| |
| namespace LIBC_NAMESPACE_DECL { |
| |
| LLVM_LIBC_FUNCTION(int, fflush, (::FILE * stream)) { |
| // If a non-null stream is specified, we only flush that single stream. |
| if (stream != nullptr) { |
| int result = reinterpret_cast<File *>(stream)->flush(); |
| if (result != 0) { |
| libc_errno = result; |
| return EOF; |
| } |
| return 0; |
| } |
| |
| // If the stream is null, we flush all open streams as per C and POSIX |
| // requirements. |
| int total_error = 0; |
| |
| // We explicitly flush the standard streams as they may not be part of the |
| // global file list if they are statically initialized. |
| File *std_streams[] = {reinterpret_cast<File *>(stdin), |
| reinterpret_cast<File *>(stdout), |
| reinterpret_cast<File *>(stderr)}; |
| for (auto *s : std_streams) { |
| if (s != nullptr) { |
| int result = s->flush(); |
| if (result != 0) |
| total_error = result; |
| } |
| } |
| |
| // We iterate over the global list of all open File objects to flush any |
| // other streams that were opened via fopen. |
| File::lock_list(); |
| for (File *f = File::get_first_file(); f != nullptr; f = f->get_next()) { |
| int result = f->flush(); |
| if (result != 0) |
| total_error = result; |
| } |
| File::unlock_list(); |
| |
| if (total_error != 0) { |
| libc_errno = total_error; |
| return EOF; |
| } |
| return 0; |
| } |
| |
| } // namespace LIBC_NAMESPACE_DECL |