Index: libcxx/trunk/include/fstream =================================================================== --- libcxx/trunk/include/fstream +++ libcxx/trunk/include/fstream @@ -697,10 +697,9 @@ unique_ptr __h(__file_, fclose); if (sync()) __rt = 0; - if (fclose(__h.release()) == 0) - __file_ = 0; - else + if (fclose(__h.release())) __rt = 0; + __file_ = 0; setbuf(0, 0); } return __rt; Index: libcxx/trunk/test/std/input.output/file.streams/fstreams/filebuf.members/close.pass.cpp =================================================================== --- libcxx/trunk/test/std/input.output/file.streams/fstreams/filebuf.members/close.pass.cpp +++ libcxx/trunk/test/std/input.output/file.streams/fstreams/filebuf.members/close.pass.cpp @@ -0,0 +1,56 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// + +// basic_filebuf* close(); + +#include +#include +#if defined(__unix__) +#include +#include +#endif +#include "test_macros.h" +#include "platform_support.h" + +int main(int, char**) +{ + std::string temp = get_temp_file_name(); + { + std::filebuf f; + assert(!f.is_open()); + assert(f.open(temp.c_str(), std::ios_base::out) != 0); + assert(f.is_open()); + assert(f.close() != nullptr); + assert(!f.is_open()); + assert(f.close() == nullptr); + assert(!f.is_open()); + } +#if defined(__unix__) + { + std::filebuf f; + assert(!f.is_open()); + // Use open directly to get the file descriptor. + int fd = open(temp.c_str(), O_RDWR); + assert(fd >= 0); + // Use the internal method to create filebuf from the file descriptor. + assert(f.__open(fd, std::ios_base::out) != 0); + assert(f.is_open()); + // Close the file descriptor directly to force filebuf::close to fail. + assert(close(fd) == 0); + // Ensure that filebuf::close handles the failure. + assert(f.close() == nullptr); + assert(!f.is_open()); + assert(f.close() == nullptr); + } +#endif + std::remove(temp.c_str()); + + return 0; +}