2002-07-15  Ulrich Drepper  <drepper@redhat.com>

	* libio/wfileops.c (_IO_wfile_seekoff): Reposition wide pointers
	and adjust state for seek position.  [PR libc/4070]
	* libio/Makefile (tests): Add bug-rewind.
	* libio/bug-rewind.c: New file.
This commit is contained in:
Ulrich Drepper 2002-07-15 23:37:22 +00:00
parent c3da4f0cba
commit 706d1dee46
9 changed files with 163 additions and 11 deletions

View File

@ -1,3 +1,10 @@
2002-07-15 Ulrich Drepper <drepper@redhat.com>
* libio/wfileops.c (_IO_wfile_seekoff): Reposition wide pointers
and adjust state for seek position. [PR libc/4070]
* libio/Makefile (tests): Add bug-rewind.
* libio/bug-rewind.c: New file.
2002-07-12 Philip Blundell <philb@gnu.org> 2002-07-12 Philip Blundell <philb@gnu.org>
* sysdeps/generic/backtrace.c (FIRST_FRAME_POINTER): New macro. * sysdeps/generic/backtrace.c (FIRST_FRAME_POINTER): New macro.

View File

@ -50,7 +50,7 @@ tests = tst_swprintf tst_wprintf tst_swscanf tst_wscanf tst_getwc tst_putwc \
tst_wprintf2 tst-widetext test-fmemopen tst-ext tst-fopenloc \ tst_wprintf2 tst-widetext test-fmemopen tst-ext tst-fopenloc \
tst-fgetws tst-ungetwc1 tst-ungetwc2 tst-swscanf tst-sscanf \ tst-fgetws tst-ungetwc1 tst-ungetwc2 tst-swscanf tst-sscanf \
tst-mmap-setvbuf bug-ungetwc1 bug-ungetwc2 tst-atime tst-eof \ tst-mmap-setvbuf bug-ungetwc1 bug-ungetwc2 tst-atime tst-eof \
tst-freopen tst-freopen bug-rewind
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.

52
libio/bug-rewind.c Normal file
View File

@ -0,0 +1,52 @@
#include <stdio.h>
#include <wchar.h>
#define PASSED 0
#define FAILED 3
int
main (void)
{
FILE *fptr;
char arg1;
char arg2;
int ret, ret1, ret2, result, num;
ret1 = 0;
ret2 = 0;
if ((fptr = fopen ("./wrewind.dat", "w+")) == NULL)
{
printf ("Unable to open file.\n");
return 1;
}
if ((ret = fwprintf (fptr, L"cderf")) <= 0)
{
printf ("Unable to write to file with fwprintf().\n");
fclose (fptr);
return 2;
}
rewind (fptr);
ret1 = fwscanf (fptr, L"%c%c", &arg1, &arg2);
rewind (fptr);
ret2 = fwscanf (fptr, L"%c%n%c", &arg1, &num, &arg2);
if (arg2 != 'd')
{
result = FAILED;
printf ("rewind after first fwscanf failed\n");
}
else
{
printf ("Passed\n");
result = PASSED;
}
fclose (fptr);
return result;
}

View File

@ -635,6 +635,10 @@ _IO_wfile_seekoff (fp, offset, dir, mode)
#endif #endif
if (rel_offset <= fp->_IO_read_end - fp->_IO_read_base) if (rel_offset <= fp->_IO_read_end - fp->_IO_read_base)
{ {
enum __codecvt_result status;
struct _IO_codecvt *cd = fp->_codecvt;
const char *read_ptr_copy;
fp->_IO_read_ptr = fp->_IO_read_base + rel_offset; fp->_IO_read_ptr = fp->_IO_read_base + rel_offset;
_IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base); _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
@ -643,11 +647,33 @@ _IO_wfile_seekoff (fp, offset, dir, mode)
pointer is somewhere in the current external buffer pointer is somewhere in the current external buffer
this does not mean we can convert this whole buffer this does not mean we can convert this whole buffer
at once fitting in the internal buffer. */ 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 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 (0); while (read_ptr_copy != fp->_IO_read_ptr);
fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end
= 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;

View File

@ -1,3 +1,11 @@
2002-07-14 Ulrich Drepper <drepper@redhat.com>
* td_ta_map_id2thr.c: Begin fixing implementation for libpthread with
TLS support.
* td_ta_map_lwp2thr.c: Likewise.
* td_ta_thr_iter.c: Likewise.
* td_thr_get_info.c: Likewise.
2002-07-10 Ulrich Drepper <drepper@redhat.com> 2002-07-10 Ulrich Drepper <drepper@redhat.com>
* Versions [libthread_db] (GLIBC_2.3): Add td_thr_tls_get_addr. * Versions [libthread_db] (GLIBC_2.3): Add td_thr_tls_get_addr.

View File

@ -45,7 +45,19 @@ td_ta_map_id2thr (const td_thragent_t *ta, pthread_t pt, td_thrhandle_t *th)
/* Test whether this entry is in use. */ /* Test whether this entry is in use. */
if (phc.h_descr == NULL) if (phc.h_descr == NULL)
return TD_BADTH; {
if (pt % pthread_threads_max == 0)
{
/* The initial thread always exists but the thread library
might not yet be initialized. */
th->th_ta_p = (td_thragent_t *) ta;
th->th_unique = NULL;
return TD_OK;
}
return TD_BADTH;
}
/* Next test: get the descriptor to see whether this is not an old /* Next test: get the descriptor to see whether this is not an old
thread handle. */ thread handle. */

View File

@ -76,7 +76,16 @@ td_ta_map_lwp2thr (const td_thragent_t *ta, lwpid_t lwpid, td_thrhandle_t *th)
return TD_OK; return TD_OK;
} }
} }
else if (cnt == 0)
{
/* The initial thread always exists. But it might not yet be
initialized. Construct a value. */
th->th_ta_p = (td_thragent_t *) ta;
th->th_unique = NULL;
return TD_OK;
}
return TD_NOLWP; return TD_NOLWP;
} }

View File

@ -31,6 +31,37 @@ handle_descr (const td_thragent_t *ta, td_thr_iter_f *callback,
size_t sizeof_descr = ta->sizeof_descr; size_t sizeof_descr = ta->sizeof_descr;
td_thrhandle_t th; td_thrhandle_t th;
if (descr == NULL)
{
/* No descriptor (yet). */
if (cnt == 0)
{
/* This is the main thread. Create a fake descriptor. */
memset (&pds, '\0', sizeof (pds));
/* Empty thread descriptor the thread library would create. */
pds.p_header.data.self = &pds;
pds.p_nextlive = pds.p_prevlive = &pds;
pds.p_tid = PTHREAD_THREADS_MAX;
/* The init code also sets up p_lock, p_errnop, p_herrnop, and
p_userstack but this should not be necessary here. */
th.th_ta_p = (td_thragent_t *) ta;
th.th_unique = &pds;
if (callback (&th, cbdata_p) != 0)
return TD_DBERR;
/* All done successfully. */
return TD_OK;
}
else if (cnt == 1)
/* The manager is not yet started. No big deal. */
return TD_OK;
else
/* For every other thread this should not happen. */
return TD_ERR;
}
if (ps_pdread (ta->ph, descr, &pds, sizeof_descr) != PS_OK) if (ps_pdread (ta->ph, descr, &pds, sizeof_descr) != PS_OK)
return TD_ERR; /* XXX Other error value? */ return TD_ERR; /* XXX Other error value? */

View File

@ -1,5 +1,5 @@
/* Get thread information. /* Get thread information.
Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
@ -31,10 +31,17 @@ td_thr_get_info (const td_thrhandle_t *th, td_thrinfo_t *infop)
LOG ("td_thr_get_info"); LOG ("td_thr_get_info");
/* Get the thread descriptor. */ /* Handle the case when the thread library is not yet initialized. */
if (ps_pdread (th->th_ta_p->ph, th->th_unique, &pds, if (th->th_unique == NULL)
th->th_ta_p->sizeof_descr) != PS_OK) {
return TD_ERR; /* XXX Other error value? */ memset (&pds, '\0', sizeof (pds));
pds.p_tid = PTHREAD_THREADS_MAX;
}
else
/* Get the thread descriptor. */
if (ps_pdread (th->th_ta_p->ph, th->th_unique, &pds,
th->th_ta_p->sizeof_descr) != PS_OK)
return TD_ERR; /* XXX Other error value? */
/* Fill in information. Clear first to provide reproducable /* Fill in information. Clear first to provide reproducable
results for the fields we do not fill in. */ results for the fields we do not fill in. */