[libc-commits] [libc] [libc] fwrite_unlocked: only return errno if an actual error occurred. (PR #167350)
via libc-commits
libc-commits at lists.llvm.org
Mon Nov 10 10:22:30 PST 2025
https://github.com/Sterling-Augustine updated https://github.com/llvm/llvm-project/pull/167350
>From 2ccd1267a37cec3a7b92d5edf92cadfa9aef897d Mon Sep 17 00:00:00 2001
From: Sterling Augustine <saugustine at google.com>
Date: Mon, 10 Nov 2025 09:37:37 -0800
Subject: [PATCH 1/2] [libc] fwrite_unlocked: only return errno if an actual
error occurred.
fwrite and friends don't modify errno if no error occurred. Therefore
frite_unlocked's return value shouldn't be constructed from errno
without checking if an error actually occurred.
---
libc/src/stdio/printf_core/vfprintf_internal.h | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/libc/src/stdio/printf_core/vfprintf_internal.h b/libc/src/stdio/printf_core/vfprintf_internal.h
index 564441d3bf51a..a14ddee5f62fd 100644
--- a/libc/src/stdio/printf_core/vfprintf_internal.h
+++ b/libc/src/stdio/printf_core/vfprintf_internal.h
@@ -51,8 +51,14 @@ LIBC_INLINE void funlockfile(::FILE *f) { ::funlockfile(f); }
LIBC_INLINE FileIOResult fwrite_unlocked(const void *ptr, size_t size,
size_t nmemb, ::FILE *f) {
// Need to use system errno in this case, as system write will set this errno
- // which we need to propagate back into our code.
- return {::fwrite_unlocked(ptr, size, nmemb, f), errno};
+ // which we need to propagate back into our code. fwrite only modifies errno
+ // if there was an error, and errno may have previously been nonzero. Only
+ // return errno if there was an error.
+ auto bytes = ::fwrite_unlocked(ptr, size, nmemb, f);
+ if (bytes == nmemb * size)
+ return bytes;
+ else
+ return errno;
}
#endif // LIBC_COPT_STDIO_USE_SYSTEM_FILE
} // namespace internal
>From ccb1b257cfde77abea9a81d9e1acbc3126ca6a95 Mon Sep 17 00:00:00 2001
From: Sterling Augustine <saugustine at google.com>
Date: Mon, 10 Nov 2025 10:21:33 -0800
Subject: [PATCH 2/2] FileIOResult is not a std::expected or similar. Don't
treat it that way.
---
libc/src/stdio/printf_core/vfprintf_internal.h | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/libc/src/stdio/printf_core/vfprintf_internal.h b/libc/src/stdio/printf_core/vfprintf_internal.h
index a14ddee5f62fd..ac7c167217b7f 100644
--- a/libc/src/stdio/printf_core/vfprintf_internal.h
+++ b/libc/src/stdio/printf_core/vfprintf_internal.h
@@ -55,10 +55,7 @@ LIBC_INLINE FileIOResult fwrite_unlocked(const void *ptr, size_t size,
// if there was an error, and errno may have previously been nonzero. Only
// return errno if there was an error.
auto bytes = ::fwrite_unlocked(ptr, size, nmemb, f);
- if (bytes == nmemb * size)
- return bytes;
- else
- return errno;
+ return {bytes, bytes == nmemb * size ? 0 : errno};
}
#endif // LIBC_COPT_STDIO_USE_SYSTEM_FILE
} // namespace internal
More information about the libc-commits
mailing list