bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: {f,}printf-posix test failure


From: Bruno Haible
Subject: Re: {f,}printf-posix test failure
Date: Sat, 24 Apr 2010 17:22:05 +0200
User-agent: KMail/1.9.9

Hi,

Ian Beckwith wrote:
> printf-posix and fprintf-posix fail the test suite on debian stable and
> unstable, i386 and ia64.
> 
> The problem seems to be the same, test-printf-posix2 and
> test-fprintf-posix2 fail at the same place. Looking at
> test-fprintf-posix2:
> 
> gltests/test-fprintf-posix2.sh runs "test-fprintf-posix2 1"
> which fails:
> 
> (gdb) n
> 83          ret = fprintf (stdout, "%.5000000f", 1.0);
> (gdb) n
> 84          return !(ret == 5000002 || (ret < 0 && errno == ENOMEM));
> (gdb) p ret
> $1 = -1
> (gdb) p errno
> $2 = 22
> 
> (22 == EINVAL)
> 
> The problem seems to be in vasnprintf.c.
> 
> vasnprintf.c:5023 calls SNPRINTF_BUF(arg);
> 
> The expansion of SNPRINTF_BUF includes at vasnprintf.c:4919:
> 
> retcount = SNPRINTF ((TCHAR_T *) (result + length), \
>                      maxlen, buf,                   \
>                      arg, &count);                  \
> 
> which, if I'm understanding it right (USE_SNPRINTF is defined), calls
> the system's snprintf(), which returns -1.

Thanks for your report and analysis. The wrong errno was introduced in the
simplification on 2010-04-10.

This fixes it.


2010-04-24  Bruno Haible  <address@hidden>

        vasnprintf: Correct errno value in case of out-of-memory.
        * lib/vasnprintf.c (VASNPRINTF): Set errno to 0 before calling SNPRINTF
        or sprintf. Use the errno value from SNPRINTF or sprintf.
        Reported by Ian Beckwith <address@hidden>.

--- lib/vasnprintf.c.orig       Sat Apr 24 17:15:50 2010
+++ lib/vasnprintf.c    Sat Apr 24 17:14:46 2010
@@ -4953,6 +4953,7 @@
                       }
 #endif
 
+                    errno = 0;
                     switch (type)
                       {
                       case TYPE_SCHAR:
@@ -5147,15 +5148,21 @@
                     /* Attempt to handle failure.  */
                     if (count < 0)
                       {
+                        /* SNPRINTF or sprintf failed.  Save and use the errno
+                           that it has set, if any.  */
+                        int saved_errno = errno;
+
                         if (!(result == resultbuf || result == NULL))
                           free (result);
                         if (buf_malloced != NULL)
                           free (buf_malloced);
                         CLEANUP ();
                         errno =
-                          (dp->conversion == 'c' || dp->conversion == 's'
-                           ? EILSEQ
-                           : EINVAL);
+                          (saved_errno != 0
+                           ? saved_errno
+                           : (dp->conversion == 'c' || dp->conversion == 's'
+                              ? EILSEQ
+                              : EINVAL));
                         return NULL;
                       }
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]