* stdio-common/vfscanf.c (_IO_vfscanf): Add additional test for EOF

in loop to look for conversion specifier to avoid testing of
	wrong errno value.
	* stdio-common/Makefile (tests): Add bug18, bug18a, bug19, bug19a.
	* stdio-common/bug18a.c: New file.
	* stdio-common/bug19.c: New file.
	* stdio-common/bug19a.c: New file.
This commit is contained in:
Ulrich Drepper 2007-07-08 04:41:34 +00:00
parent e9055017f6
commit 0923a2c896
7 changed files with 86 additions and 27 deletions

View File

@ -1,15 +1,14 @@
2007-07-07 Ulrich Drepper <drepper@redhat.com>
* libio/wstrops.c (_IO_wstr_underflow): Clear errno before
returning WEOF.
* stdio-common/Makefile (tests): Add bug18a.
* stdio-common/bug18a.c: New file.
[BZ #4745]
* libio/strops.c (_IO_str_underflow): Clear errno before returning
EOF.
* stdio-common/Makefile (tests): Add bug18.
* stdio-common/vfscanf.c (_IO_vfscanf): Add additional test for EOF
in loop to look for conversion specifier to avoid testing of
wrong errno value.
* stdio-common/Makefile (tests): Add bug18, bug18a, bug19, bug19a.
* stdio-common/bug18.c: New file.
* stdio-common/bug18a.c: New file.
* stdio-common/bug19.c: New file.
* stdio-common/bug19a.c: New file.
2007-07-05 Mike Frysinger <vapier@gentoo.org>

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1993, 1997-2004, 2006, 2007 Free Software Foundation, Inc.
/* Copyright (C) 1993, 1997-2003, 2004, 2006 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@ -166,12 +166,7 @@ _IO_str_underflow (fp)
if (fp->_IO_read_ptr < fp->_IO_read_end)
return *((unsigned char *) fp->_IO_read_ptr);
else
{
/* We have to reset errno since callers check for errno being
EINTR and there has been no such problem here. */
__set_errno (0);
return EOF;
}
return EOF;
}
INTDEF(_IO_str_underflow)

View File

@ -1,5 +1,4 @@
/* Copyright (C) 1993,1997-1999,2001-2004,2006,2007
Free Software Foundation, Inc.
/* Copyright (C) 1993,1997-1999,2001-2004, 2006 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@ -155,12 +154,7 @@ _IO_wstr_underflow (fp)
if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end)
return *fp->_wide_data->_IO_read_ptr;
else
{
/* We have to reset errno since callers check for errno being
EINTR and there has been no such problem here. */
__set_errno (0);
return WEOF;
}
return WEOF;
}

View File

@ -54,7 +54,8 @@ tests := tstscanf test_rdwr test-popen tstgetln test-fseek \
tst-swprintf tst-fseek tst-fmemopen test-vfprintf tst-gets \
tst-perror tst-sprintf tst-rndseek tst-fdopen tst-fphex bug14 bug15 \
tst-popen tst-unlockedio tst-fmemopen2 tst-put-error tst-fgets \
tst-fwrite bug16 bug17 tst-swscanf tst-sprintf2 bug18 bug18a
tst-fwrite bug16 bug17 tst-swscanf tst-sprintf2 bug18 bug18a \
bug19 bug19a
test-srcs = tst-unbputc tst-printf

58
stdio-common/bug19.c Normal file
View File

@ -0,0 +1,58 @@
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#ifndef CHAR
# define CHAR char
# define L(str) str
# define FPUTS fputs
# define FSCANF fscanf
#endif
static int
do_test (void)
{
FILE *fp = tmpfile ();
if (fp == NULL)
{
puts ("cannot open file");
return 1;
}
FPUTS (L("7-11"), fp);
rewind (fp);
printf("setting errno to EINTR\n");
errno = EINTR;
printf("checking sscanf\n");
int i, j, n;
i = j = n = 0;
FSCANF (fp, L(" %i - %i %n"), &i, &j, &n);
printf ("found %i-%i (length=%i)\n", i, j, n);
int result = 0;
if (i != 7)
{
printf ("i is %d, expected 7\n", i);
result = 1;
}
if (j != 11)
{
printf ("j is %d, expected 11\n", j);
result = 1;
}
if (n != 4)
{
printf ("n is %d, expected 4\n", j);
result = 1;
}
return result;
}
#define TEST_FUNCTION do_test ()
#include "../test-skeleton.c"

7
stdio-common/bug19a.c Normal file
View File

@ -0,0 +1,7 @@
#include <wchar.h>
#define CHAR wchar_t
#define L(str) L##str
#define FPUTS fputws
#define FSCANF fwscanf
#include "bug19.c"

View File

@ -530,12 +530,17 @@ _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
{
/* Eat whitespace. */
int save_errno = errno;
errno = 0;
__set_errno (0);
do
if (__builtin_expect (inchar () == EOF && errno == EINTR, 0))
/* We add the additional test for EOF here since otherwise
inchar will restore the old errno value which might be
EINTR but does not indicate an interrupt since nothing
was read at this time. */
if (__builtin_expect ((c == EOF || inchar () == EOF)
&& errno == EINTR, 0))
input_error ();
while (ISSPACE (c));
errno = save_errno;
__set_errno (save_errno);
ungetc (c, s);
skip_space = 0;
}