The MSVCRT `strtoul()` function, which is called indirectly by
`libiberty_vprintf_buffer_size()`, resets `errno` to zero upon success.
On such a system, `xvasprintf()` can clobber `errno` like this:

   MINGW64 ~
   $ ld nonexistent.file
   C:\MSYS64\mingw64\bin\ld.exe: cannot find nonexistent.file: No error

This commit ensures that `errno` is preserved by a successful call to
`xvasprintf()`.

libiberty/ChangeLog:

        * xvasprintf.c (xvasprintf): Ensure same `errno` is passed to
        `libiberty_vprintf_buffer_size()` and `vsprintf()`.

Signed-off-by: LIU Hao <[email protected]>
---
 libiberty/xvasprintf.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/libiberty/xvasprintf.c b/libiberty/xvasprintf.c
index 3f022d1814bf..3d83b68d05db 100644
--- a/libiberty/xvasprintf.c
+++ b/libiberty/xvasprintf.c
@@ -27,6 +27,7 @@ Floor, Boston, MA 02110-1301, USA.  */
 # define va_copy(d,s)  __va_copy((d),(s))
 #endif
 #include <stdio.h>
+#include <errno.h>
 #ifdef HAVE_STRING_H
 #include <string.h>
 #endif
@@ -54,8 +55,10 @@ xvasprintf (const char *format,
 #endif
 {
   char *result;
+  int saved_errno = errno;
   int total_width = libiberty_vprintf_buffer_size (format, args);
   result = (char *) xmalloc (total_width);
+  errno = saved_errno;
   vsprintf (result, format, args);
   return result;
 }
--
2.53.0

From b9da7128f0254305e1d8d21e4e7735cdf9031453 Mon Sep 17 00:00:00 2001
From: LIU Hao <[email protected]>
Date: Mon, 9 Feb 2026 20:14:45 +0800
Subject: [PATCH] libiberty: Ensure same `errno` is passed to
 `libiberty_vprintf_buffer_size()` and `vsprintf()`

The MSVCRT `strtoul()` function, which is called indirectly by
`libiberty_vprintf_buffer_size()`, resets `errno` to zero upon success.
On such a system, `xvasprintf()` can clobber `errno` like this:

   MINGW64 ~
   $ ld nonexistent.file
   C:\MSYS64\mingw64\bin\ld.exe: cannot find nonexistent.file: No error

This commit ensures that `errno` is preserved by a successful call to
`xvasprintf()`.

libiberty/ChangeLog:

        * xvasprintf.c (xvasprintf): Ensure same `errno` is passed to
        `libiberty_vprintf_buffer_size()` and `vsprintf()`.

Signed-off-by: LIU Hao <[email protected]>
---
 libiberty/xvasprintf.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/libiberty/xvasprintf.c b/libiberty/xvasprintf.c
index 3f022d1814bf..3d83b68d05db 100644
--- a/libiberty/xvasprintf.c
+++ b/libiberty/xvasprintf.c
@@ -27,6 +27,7 @@ Floor, Boston, MA 02110-1301, USA.  */
 # define va_copy(d,s)  __va_copy((d),(s))
 #endif
 #include <stdio.h>
+#include <errno.h>
 #ifdef HAVE_STRING_H
 #include <string.h>
 #endif
@@ -54,8 +55,10 @@ xvasprintf (const char *format,
 #endif
 {
   char *result;
+  int saved_errno = errno;
   int total_width = libiberty_vprintf_buffer_size (format, args);
   result = (char *) xmalloc (total_width);
+  errno = saved_errno;
   vsprintf (result, format, args);
   return result;
 }
-- 
2.53.0

Attachment: OpenPGP_signature.asc
Description: OpenPGP digital signature

Reply via email to