[Top][All Lists]
[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;
}