Fix fsetpos on wide stream.
This commit is contained in:
parent
22bb992d51
commit
5d2e69766a
|
@ -1,3 +1,10 @@
|
||||||
|
2009-09-02 Andreas Schwab <schwab@redhat.com>
|
||||||
|
|
||||||
|
* libio/wfileops.c (_IO_wfile_seekoff): Account for readahead in
|
||||||
|
external buffer. Always discard readahead in internal buffer.
|
||||||
|
* libio/Makefile (tests): Add bug-wsetpos.
|
||||||
|
* libio/bug-wsetpos.c: New file.
|
||||||
|
|
||||||
2009-09-02 Jakub Jelinek <jakub@redhat.com>
|
2009-09-02 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
* sysdeps/x86_64/multiarch/strstr-c.c (__strstr_sse42, __strstr_sse2):
|
* sysdeps/x86_64/multiarch/strstr-c.c (__strstr_sse42, __strstr_sse2):
|
||||||
|
|
|
@ -58,7 +58,7 @@ tests = tst_swprintf tst_wprintf tst_swscanf tst_wscanf tst_getwc tst_putwc \
|
||||||
tst-memstream1 tst-memstream2 \
|
tst-memstream1 tst-memstream2 \
|
||||||
tst-wmemstream1 tst-wmemstream2 \
|
tst-wmemstream1 tst-wmemstream2 \
|
||||||
bug-memstream1 bug-wmemstream1 \
|
bug-memstream1 bug-wmemstream1 \
|
||||||
tst-setvbuf1 tst-popen1 tst-fgetwc
|
tst-setvbuf1 tst-popen1 tst-fgetwc bug-wsetpos
|
||||||
test-srcs = test-freopen
|
test-srcs = test-freopen
|
||||||
|
|
||||||
all: # Make this the default target; it will be defined in Rules.
|
all: # Make this the default target; it will be defined in Rules.
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
/* Test program for fsetpos on a wide character stream. */
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
|
||||||
|
static void do_prepare (void);
|
||||||
|
#define PREPARE(argc, argv) do_prepare ()
|
||||||
|
static int do_test (void);
|
||||||
|
#define TEST_FUNCTION do_test ()
|
||||||
|
#include <test-skeleton.c>
|
||||||
|
|
||||||
|
static const char pattern[] = "12345";
|
||||||
|
static char *temp_file;
|
||||||
|
|
||||||
|
static void
|
||||||
|
do_prepare (void)
|
||||||
|
{
|
||||||
|
int fd = create_temp_file ("bug-wsetpos.", &temp_file);
|
||||||
|
if (fd == -1)
|
||||||
|
{
|
||||||
|
printf ("cannot create temporary file: %m\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
write (fd, pattern, sizeof (pattern));
|
||||||
|
close (fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
do_test (void)
|
||||||
|
{
|
||||||
|
FILE *fp = fopen (temp_file, "r");
|
||||||
|
fpos_t pos;
|
||||||
|
wchar_t c;
|
||||||
|
|
||||||
|
if (fp == NULL)
|
||||||
|
{
|
||||||
|
printf ("fdopen: %m\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
c = fgetwc (fp); assert (c == L'1');
|
||||||
|
c = fgetwc (fp); assert (c == L'2');
|
||||||
|
|
||||||
|
if (fgetpos (fp, &pos) == EOF)
|
||||||
|
{
|
||||||
|
printf ("fgetpos: %m\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
rewind (fp);
|
||||||
|
if (ferror (fp))
|
||||||
|
{
|
||||||
|
printf ("rewind: %m\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
c = fgetwc (fp); assert (c == L'1');
|
||||||
|
|
||||||
|
if (fsetpos (fp, &pos) == EOF)
|
||||||
|
{
|
||||||
|
printf ("fsetpos: %m\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
c = fgetwc (fp);
|
||||||
|
if (c != L'3')
|
||||||
|
{
|
||||||
|
puts ("fsetpos failed");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
puts ("Test succeeded.");
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -631,8 +631,12 @@ _IO_wfile_seekoff (fp, offset, dir, mode)
|
||||||
clen = (*cv->__codecvt_do_encoding) (cv);
|
clen = (*cv->__codecvt_do_encoding) (cv);
|
||||||
|
|
||||||
if (clen > 0)
|
if (clen > 0)
|
||||||
offset -= (fp->_wide_data->_IO_read_end
|
{
|
||||||
- fp->_wide_data->_IO_read_ptr) * clen;
|
offset -= (fp->_wide_data->_IO_read_end
|
||||||
|
- fp->_wide_data->_IO_read_ptr) * clen;
|
||||||
|
/* Adjust by readahead in external buffer. */
|
||||||
|
offset -= fp->_IO_read_end - fp->_IO_read_ptr;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int nread;
|
int nread;
|
||||||
|
@ -690,39 +694,11 @@ _IO_wfile_seekoff (fp, offset, dir, mode)
|
||||||
fp->_IO_buf_base + (offset - start_offset),
|
fp->_IO_buf_base + (offset - start_offset),
|
||||||
fp->_IO_read_end);
|
fp->_IO_read_end);
|
||||||
_IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
|
_IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
|
||||||
|
_IO_wsetg (fp, fp->_wide_data->_IO_buf_base,
|
||||||
/* Now set the pointer for the internal buffer. This
|
fp->_wide_data->_IO_buf_base,
|
||||||
might be an iterative process. Though the read
|
fp->_wide_data->_IO_buf_base);
|
||||||
pointer is somewhere in the current external buffer
|
_IO_wsetp (fp, fp->_wide_data->_IO_buf_base,
|
||||||
this does not mean we can convert this whole buffer
|
fp->_wide_data->_IO_buf_base);
|
||||||
at once fitting in the internal buffer. */
|
|
||||||
fp->_wide_data->_IO_state = fp->_wide_data->_IO_last_state;
|
|
||||||
read_ptr_copy = fp->_IO_read_base;
|
|
||||||
fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_base;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
wchar_t buffer[1024];
|
|
||||||
wchar_t *ignore;
|
|
||||||
status = (*cd->__codecvt_do_in) (cd,
|
|
||||||
&fp->_wide_data->_IO_state,
|
|
||||||
read_ptr_copy,
|
|
||||||
fp->_IO_read_ptr,
|
|
||||||
&read_ptr_copy,
|
|
||||||
buffer,
|
|
||||||
buffer
|
|
||||||
+ (sizeof (buffer)
|
|
||||||
/ sizeof (buffer[0])),
|
|
||||||
&ignore);
|
|
||||||
if (status != __codecvt_ok && status != __codecvt_partial)
|
|
||||||
{
|
|
||||||
fp->_flags |= _IO_ERR_SEEN;
|
|
||||||
goto dumb;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (read_ptr_copy != fp->_IO_read_ptr);
|
|
||||||
|
|
||||||
fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_base;
|
|
||||||
|
|
||||||
_IO_mask_flags (fp, 0, _IO_EOF_SEEN);
|
_IO_mask_flags (fp, 0, _IO_EOF_SEEN);
|
||||||
goto resync;
|
goto resync;
|
||||||
}
|
}
|
||||||
|
@ -760,6 +736,9 @@ _IO_wfile_seekoff (fp, offset, dir, mode)
|
||||||
_IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + delta,
|
_IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + delta,
|
||||||
fp->_IO_buf_base + count);
|
fp->_IO_buf_base + count);
|
||||||
_IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
|
_IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
|
||||||
|
_IO_wsetg (fp, fp->_wide_data->_IO_buf_base,
|
||||||
|
fp->_wide_data->_IO_buf_base, fp->_wide_data->_IO_buf_base);
|
||||||
|
_IO_wsetp (fp, fp->_wide_data->_IO_buf_base, fp->_wide_data->_IO_buf_base);
|
||||||
fp->_offset = result + count;
|
fp->_offset = result + count;
|
||||||
_IO_mask_flags (fp, 0, _IO_EOF_SEEN);
|
_IO_mask_flags (fp, 0, _IO_EOF_SEEN);
|
||||||
return offset;
|
return offset;
|
||||||
|
|
Loading…
Reference in New Issue