about summary refs log tree commit diff
path: root/libio/wfileops.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2001-08-09 08:50:50 +0000
committerUlrich Drepper <drepper@redhat.com>2001-08-09 08:50:50 +0000
commit40a982a9e1b825b175be7bc7c7199c6bdf363e4b (patch)
tree7523a21da3e35bed6e56133efbe1d16dadb6e6da /libio/wfileops.c
parent0f78390bd799fc0b0394240a9a704591481ac8c6 (diff)
downloadglibc-40a982a9e1b825b175be7bc7c7199c6bdf363e4b.tar.gz
glibc-40a982a9e1b825b175be7bc7c7199c6bdf363e4b.tar.xz
glibc-40a982a9e1b825b175be7bc7c7199c6bdf363e4b.zip
Update.
2001-08-09  Ulrich Drepper  <drepper@redhat.com>

	* libio/wfileops.c (_IO_wfile_seekoff): Don't even try to handle
	seeking with backup buffer present.
	Correct determining of internal buffer position.
	Reset also wide buffers if we reset the internal buffers.
	* libio/iofwide.c (_IO_fwide): Always determine file offset for wide
	streams.
	* libio/ioseekoff.c: Catch one unimplemented case.
	* libio/ftello.c: Don't abort if the wide stream has backup buffer.
	* libio/ftello64.c: Likewise.
	* libio/iofgetpos.c: Likewise.
	* libio/iofgetpos64.c: Likewise.
	* libio/ftell.c: Likewise.
	* libio/Makefile (tests): Add tst-ungetwc2.
	* libio/tst-ungetwc2.c: New file.
Diffstat (limited to 'libio/wfileops.c')
-rw-r--r--libio/wfileops.c32
1 files changed, 29 insertions, 3 deletions
diff --git a/libio/wfileops.c b/libio/wfileops.c
index e88c0654e5..92d1a08190 100644
--- a/libio/wfileops.c
+++ b/libio/wfileops.c
@@ -458,7 +458,28 @@ _IO_wfile_seekoff (fp, offset, dir, mode)
 			   == fp->_wide_data->_IO_write_ptr));
 
   if (mode == 0)
-    dir = _IO_seek_cur, offset = 0; /* Don't move any pointers. */
+    {
+      /* XXX For wide stream with backup store it is not very
+	 reasonable to determine the offset.  The pushed-back
+	 character might require a state change and we need not be
+	 able to compute the initial state by reverse transformation
+	 since there is no guarantee of symmetry.  So we don't even
+	 try and return an error.  */
+      if (_IO_in_backup (fp))
+	{
+	  if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end)
+	    {
+	      __set_errno (EINVAL);
+	      return -1;
+	    }
+
+	  /* There is no more data in the backup buffer.  We can
+	     switch back.  */
+	  _IO_switch_to_main_wget_area (fp);
+	}
+
+      dir = _IO_seek_cur, offset = 0; /* Don't move any pointers. */
+    }
 
   /* Flush unwritten characters.
      (This may do an unneeded write if we seek within the buffer.
@@ -466,7 +487,7 @@ _IO_wfile_seekoff (fp, offset, dir, mode)
      egptr to ptr.  That can't be done in the current design,
      which assumes file_ptr() is eGptr.  Anyway, since we probably
      end up flushing when we close(), it doesn't make much difference.)
-     FIXME: simulate mem-papped files. */
+     FIXME: simulate mem-mapped files. */
 
   if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_write_base
       || _IO_in_put_mode (fp))
@@ -509,12 +530,13 @@ _IO_wfile_seekoff (fp, offset, dir, mode)
 	{
 	  int nread;
 
-	  delta = fp->_wide_data->_IO_read_ptr - fp->_wide_data->_IO_read_end;
+	  delta = fp->_wide_data->_IO_read_ptr - fp->_wide_data->_IO_read_base;
 	  fp->_wide_data->_IO_state = fp->_wide_data->_IO_last_state;
 	  nread = (*cv->__codecvt_do_length) (cv, &fp->_wide_data->_IO_state,
 					      fp->_IO_read_base,
 					      fp->_IO_read_end, delta);
 	  fp->_IO_read_ptr = fp->_IO_read_base + nread;
+	  fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_read_ptr;
 	  offset -= fp->_IO_read_end - fp->_IO_read_base - nread;
 	}
 
@@ -651,6 +673,10 @@ _IO_wfile_seekoff (fp, offset, dir, mode)
       fp->_offset = result;
       _IO_setg (fp, fp->_IO_buf_base, 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);
     }
   return result;