about summary refs log tree commit diff
path: root/libio/wfileops.c
diff options
context:
space:
mode:
authorAndreas Schwab <schwab@redhat.com>2009-09-02 19:45:33 -0700
committerUlrich Drepper <drepper@redhat.com>2009-09-02 19:45:33 -0700
commit5d2e69766a8faba5bae37702094c36113365a6ca (patch)
tree15e0ea1f811e08c63f5feefadeb85d9a2ae66c48 /libio/wfileops.c
parent22bb992d51903bc8cd5f67a207d00e3a6aa8e1a9 (diff)
downloadglibc-5d2e69766a8faba5bae37702094c36113365a6ca.tar.gz
glibc-5d2e69766a8faba5bae37702094c36113365a6ca.tar.xz
glibc-5d2e69766a8faba5bae37702094c36113365a6ca.zip
Fix fsetpos on wide stream.
Diffstat (limited to 'libio/wfileops.c')
-rw-r--r--libio/wfileops.c49
1 files changed, 14 insertions, 35 deletions
diff --git a/libio/wfileops.c b/libio/wfileops.c
index be8ae78bfb..5bc08bedfb 100644
--- a/libio/wfileops.c
+++ b/libio/wfileops.c
@@ -631,8 +631,12 @@ _IO_wfile_seekoff (fp, offset, dir, mode)
       clen = (*cv->__codecvt_do_encoding) (cv);
 
       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
 	{
 	  int nread;
@@ -690,39 +694,11 @@ _IO_wfile_seekoff (fp, offset, dir, mode)
 		    fp->_IO_buf_base + (offset - start_offset),
 		    fp->_IO_read_end);
 	  _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
-
-	  /* Now set the pointer for the internal buffer.  This
-	     might be an iterative process.  Though the read
-	     pointer is somewhere in the current external buffer
-	     this does not mean we can convert this whole 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
-	    {
-	      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_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);
 	  _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
 	  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,
 	    fp->_IO_buf_base + count);
   _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;
   _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
   return offset;