diff --git a/libcxx/include/print b/libcxx/include/print --- a/libcxx/include/print +++ b/libcxx/include/print @@ -215,11 +215,15 @@ if (__write_nl) __str.push_back('\n'); + // On POSIX errno is set by fwrite. This is not required by the C standard. + errno = 0; size_t __size = fwrite(__str.data(), 1, __str.size(), __stream); if (__size < __str.size()) { + if (errno) + std::__throw_system_error(errno, "failed to write formatted output"); if (std::feof(__stream)) std::__throw_system_error(EIO, "EOF while writing the formatted output"); - std::__throw_system_error(std::ferror(__stream), "failed to write formatted output"); + std::__throw_system_error(EIO, "failed to write formatted output"); } } diff --git a/libcxx/test/std/input.output/iostream.format/print.fun/print.file.pass.cpp b/libcxx/test/std/input.output/iostream.format/print.fun/print.file.pass.cpp --- a/libcxx/test/std/input.output/iostream.format/print.fun/print.file.pass.cpp +++ b/libcxx/test/std/input.output/iostream.format/print.fun/print.file.pass.cpp @@ -75,7 +75,7 @@ TEST_VALIDATE_EXCEPTION( std::system_error, [&]([[maybe_unused]] const std::system_error& e) { - [[maybe_unused]] std::string_view what{"failed to write formatted output"}; + [[maybe_unused]] std::string_view what{"failed to write formatted output: Input/output error"}; TEST_LIBCPP_REQUIRE( e.what() == what, TEST_WRITE_CONCATENATED("\nExpected exception ", what, "\nActual exception ", e.what(), '\n')); @@ -94,7 +94,7 @@ #ifdef _AIX [[maybe_unused]] std::string_view what{"failed to write formatted output: Broken pipe"}; #else - [[maybe_unused]] std::string_view what{"failed to write formatted output: Operation not permitted"}; + [[maybe_unused]] std::string_view what{"failed to write formatted output: Bad file descriptor"}; #endif TEST_LIBCPP_REQUIRE( e.what() == what, diff --git a/libcxx/test/std/input.output/iostream.format/print.fun/println.file.pass.cpp b/libcxx/test/std/input.output/iostream.format/print.fun/println.file.pass.cpp --- a/libcxx/test/std/input.output/iostream.format/print.fun/println.file.pass.cpp +++ b/libcxx/test/std/input.output/iostream.format/print.fun/println.file.pass.cpp @@ -78,7 +78,7 @@ TEST_VALIDATE_EXCEPTION( std::system_error, [&]([[maybe_unused]] const std::system_error& e) { - [[maybe_unused]] std::string_view what{"failed to write formatted output"}; + [[maybe_unused]] std::string_view what{"failed to write formatted output: Input/output error"}; TEST_LIBCPP_REQUIRE( e.what() == what, TEST_WRITE_CONCATENATED("\nExpected exception ", what, "\nActual exception ", e.what(), '\n')); @@ -97,7 +97,7 @@ #ifdef _AIX [[maybe_unused]] std::string_view what{"failed to write formatted output: Broken pipe"}; #else - [[maybe_unused]] std::string_view what{"failed to write formatted output: Operation not permitted"}; + [[maybe_unused]] std::string_view what{"failed to write formatted output: Bad file descriptor"}; #endif TEST_LIBCPP_REQUIRE( e.what() == what, diff --git a/libcxx/test/std/input.output/iostream.format/print.fun/vprint_nonunicode.file.pass.cpp b/libcxx/test/std/input.output/iostream.format/print.fun/vprint_nonunicode.file.pass.cpp --- a/libcxx/test/std/input.output/iostream.format/print.fun/vprint_nonunicode.file.pass.cpp +++ b/libcxx/test/std/input.output/iostream.format/print.fun/vprint_nonunicode.file.pass.cpp @@ -84,7 +84,7 @@ TEST_VALIDATE_EXCEPTION( std::system_error, [&]([[maybe_unused]] const std::system_error& e) { - [[maybe_unused]] std::string_view what{"failed to write formatted output"}; + [[maybe_unused]] std::string_view what{"failed to write formatted output: Input/output error"}; TEST_LIBCPP_REQUIRE( e.what() == what, TEST_WRITE_CONCATENATED("\nExpected exception ", what, "\nActual exception ", e.what(), '\n')); @@ -103,7 +103,7 @@ #ifdef _AIX [[maybe_unused]] std::string_view what{"failed to write formatted output: Broken pipe"}; #else - [[maybe_unused]] std::string_view what{"failed to write formatted output: Operation not permitted"}; + [[maybe_unused]] std::string_view what{"failed to write formatted output: Bad file descriptor"}; #endif TEST_LIBCPP_REQUIRE( e.what() == what, diff --git a/libcxx/test/std/input.output/iostream.format/print.fun/vprint_unicode.file.pass.cpp b/libcxx/test/std/input.output/iostream.format/print.fun/vprint_unicode.file.pass.cpp --- a/libcxx/test/std/input.output/iostream.format/print.fun/vprint_unicode.file.pass.cpp +++ b/libcxx/test/std/input.output/iostream.format/print.fun/vprint_unicode.file.pass.cpp @@ -91,7 +91,7 @@ TEST_VALIDATE_EXCEPTION( std::system_error, [&]([[maybe_unused]] const std::system_error& e) { - [[maybe_unused]] std::string_view what{"failed to write formatted output"}; + [[maybe_unused]] std::string_view what{"failed to write formatted output: Input/output error"}; TEST_LIBCPP_REQUIRE( e.what() == what, TEST_WRITE_CONCATENATED("\nExpected exception ", what, "\nActual exception ", e.what(), '\n')); @@ -110,7 +110,7 @@ #ifdef _AIX [[maybe_unused]] std::string_view what{"failed to write formatted output: Broken pipe"}; #else - [[maybe_unused]] std::string_view what{"failed to write formatted output: Operation not permitted"}; + [[maybe_unused]] std::string_view what{"failed to write formatted output: Bad file descriptor"}; #endif TEST_LIBCPP_REQUIRE( e.what() == what,