[glibc/f18] - Update fseek fix (#854337)
Jeffrey Law
law at fedoraproject.org
Thu Sep 6 04:36:23 UTC 2012
commit e063906d5574797e71f67819f728b6a89414f0ca
Author: Jeff Law <law at redhat.com>
Date: Wed Sep 5 22:35:57 2012 -0600
- Update fseek fix (#854337)
glibc-rh854337.patch | 209 ++++++++++++++++---------------------------------
glibc.spec | 5 +-
2 files changed, 72 insertions(+), 142 deletions(-)
---
diff --git a/glibc-rh854337.patch b/glibc-rh854337.patch
index 551b698..d6e6ed3 100644
--- a/glibc-rh854337.patch
+++ b/glibc-rh854337.patch
@@ -1,78 +1,7 @@
-From libc-alpha-return-32469-listarch-libc-alpha=sources dot redhat dot com at sourceware dot org Tue Sep 04 16:35:13 2012
-Return-Path: <libc-alpha-return-32469-listarch-libc-alpha=sources dot redhat dot com at sourceware dot org>
-Delivered-To: listarch-libc-alpha at sources dot redhat dot com
-Received: (qmail 31908 invoked by alias); 4 Sep 2012 16:35:07 -0000
-Received: (qmail 31178 invoked by uid 22791); 4 Sep 2012 16:35:03 -0000
-X-SWARE-Spam-Status: No, hits=-6.8 required=5.0
- tests=AWL,BAYES_00,KHOP_RCVD_UNTRUST,RCVD_IN_DNSWL_HI,RCVD_IN_HOSTKARMA_W,RP_MATCHES_RCVD,SPF_HELO_PASS,TW_SW,TW_TV,TW_TW,TW_VB
-X-Spam-Check-By: sourceware.org
-Date: Tue, 4 Sep 2012 22:03:55 +0530
-From: Siddhesh Poyarekar <siddhesh at redhat dot com>
-To: libc-alpha at sourceware dot org
-Subject: [PATCH][BZ #14543] Fix fseek behaviour when called in wide mode
-Message-ID: <20120904220355.5ef5d279 at spoyarek>
-Mime-Version: 1.0
-Content-Type: multipart/mixed; boundary="MP_/nT+8opq/57jsIpH2GwJ_t+V"
-Mailing-List: contact libc-alpha-help at sourceware dot org; run by ezmlm
-Precedence: bulk
-List-Id: <libc-alpha.sourceware.org>
-List-Subscribe: <mailto:libc-alpha-subscribe at sourceware dot org>
-List-Archive: <http://sourceware.org/ml/libc-alpha/>
-List-Post: <mailto:libc-alpha at sourceware dot org>
-List-Help: <mailto:libc-alpha-help at sourceware dot org>, <http://sourceware dot org/ml/#faqs>
-Sender: libc-alpha-owner at sourceware dot org
-Delivered-To: mailing list libc-alpha at sourceware dot org
-
---MP_/nT+8opq/57jsIpH2GwJ_t+V
-Content-Type: text/plain; charset=US-ASCII
-Content-Transfer-Encoding: 7bit
-Content-Disposition: inline
-
-Hi,
-
-This is a patch to fix the problem Jeff Law had posted about in July:
-
-http://sourceware.org/ml/libc-alpha/2012-07/msg00179.html
-
-When fseek is called in wide mode, i.e. when the locale uses a
-multibyte character set, it does not set the internal buffer state
-correctly due to which, an ftell following it returns an invalid file
-offset. This can be reproduced reliably with the reproducer program in
-the bugzilla.
-
-The attached patch sets the internal buffer state correctly whenever
-the external buffer state is modified by fseek. This involves either
-computing the current _IO_read_ptr/end for the internal buffer based on
-the new _IO_read_ptr in the external buffer or converting the content
-read into the external buffer, up to the extent of the requested fseek
-offset.
-
-The patch also includes a test case that verifies the fix. I have
-verified that the patch does not cause a regression in the testsuite on
-my F16 x86_64.
-
-Regards,
-Siddhesh
-
-ChangeLog:
-
- * libio/Makefile (tests): New test case tst-fseek.
- * libio/tst-fseek.c: New test case to verify that fseek/ftell
- combination works in wide mode.
- * libio/wfileops.c (_IO_wfile_seekoff): Adjust internal buffer
- state when the external buffer state changes.
-
-
---MP_/nT+8opq/57jsIpH2GwJ_t+V
-Content-Type: text/x-patch
-Content-Transfer-Encoding: 7bit
-Content-Disposition: attachment; filename=wide-fseek.patch
-
-diff --git a/libio/Makefile b/libio/Makefile
-index c555dd0..e760ddc 100644
---- a/libio/Makefile
-+++ b/libio/Makefile
-@@ -57,7 +57,7 @@ tests = tst_swprintf tst_wprintf tst_swscanf tst_wscanf tst_getwc tst_putwc \
+diff -Nrup a/libio/Makefile b/libio/Makefile
+--- a/libio/Makefile 2012-06-30 13:12:34.000000000 -0600
++++ b/libio/Makefile 2012-09-05 22:26:34.675086743 -0600
+@@ -57,7 +57,7 @@ tests = tst_swprintf tst_wprintf tst_sws
tst-memstream1 tst-memstream2 \
tst-wmemstream1 tst-wmemstream2 \
bug-memstream1 bug-wmemstream1 \
@@ -81,12 +10,10 @@ index c555dd0..e760ddc 100644
test-srcs = test-freopen
all: # Make this the default target; it will be defined in Rules.
-diff --git a/libio/tst-fseek.c b/libio/tst-fseek.c
-new file mode 100644
-index 0000000..e7984b0
---- /dev/null
-+++ b/libio/tst-fseek.c
-@@ -0,0 +1,152 @@
+diff -Nrup a/libio/tst-fseek.c b/libio/tst-fseek.c
+--- a/libio/tst-fseek.c 1969-12-31 17:00:00.000000000 -0700
++++ b/libio/tst-fseek.c 2012-09-05 22:26:11.237181749 -0600
+@@ -0,0 +1,153 @@
+/* Verify that fseek/ftell combination works for wide chars.
+
+ Copyright (C) 2012 Free Software Foundation, Inc.
@@ -112,6 +39,7 @@ index 0000000..e7984b0
+#include <errno.h>
+#include <wchar.h>
+#include <unistd.h>
++#include <string.h>
+
+/* Defined in test-skeleton.c. */
+static int create_temp_file (const char *base, char **filename);
@@ -239,85 +167,84 @@ index 0000000..e7984b0
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
-diff --git a/libio/wfileops.c b/libio/wfileops.c
-index 3f628bf..96debc6 100644
---- a/libio/wfileops.c
-+++ b/libio/wfileops.c
-@@ -684,13 +684,25 @@ _IO_wfile_seekoff (fp, offset, dir, mode)
- - (fp->_IO_read_end - fp->_IO_buf_base));
- if (offset >= start_offset && offset < fp->_offset)
- {
-+ struct _IO_codecvt *cv = fp->_codecvt;
-+ _IO_off64_t off;
-+
- _IO_setg (fp, fp->_IO_buf_base,
- fp->_IO_buf_base + (offset - start_offset),
- fp->_IO_read_end);
- _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
-+
-+ /* Get corresponding offset for the _wide_data. */
-+ fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state;
-+ off = (*cv->__codecvt_do_length) (cv, &fp->_wide_data->_IO_state,
-+ fp->_IO_read_base, fp->_IO_read_ptr,
-+ (fp->_wide_data->_IO_buf_end
-+ - fp->_wide_data->_IO_buf_base));
-+
- _IO_wsetg (fp, fp->_wide_data->_IO_buf_base,
-- fp->_wide_data->_IO_buf_base,
-- fp->_wide_data->_IO_buf_base);
-+ fp->_wide_data->_IO_buf_base + off,
-+ fp->_wide_data->_IO_buf_base + off);
+diff -Nrup a/libio/wfileops.c b/libio/wfileops.c
+--- a/libio/wfileops.c 2012-06-30 13:12:34.000000000 -0600
++++ b/libio/wfileops.c 2012-09-05 22:26:11.540180521 -0600
+@@ -545,6 +545,55 @@ _IO_wfile_sync (fp)
+ }
+ libc_hidden_def (_IO_wfile_sync)
+
++/* Adjust the internal buffer pointers to reflect the state in the external
++ buffer. The content between fp->_IO_read_base and fp->_IO_read_ptr is
++ assumed to be converted and available in the range
++ fp->_wide_data->_IO_read_base and fp->_wide_data->_IO_read_end. */
++static inline int
++adjust_wide_data (_IO_FILE *fp, bool do_convert)
++{
++ struct _IO_codecvt *cv = fp->_codecvt;
+
- _IO_wsetp (fp, fp->_wide_data->_IO_buf_base,
- fp->_wide_data->_IO_buf_base);
- _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
-@@ -727,11 +739,43 @@ _IO_wfile_seekoff (fp, offset, dir, mode)
- goto dumb;
- }
- }
-- _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);
++ int clen = (*cv->__codecvt_do_encoding) (cv);
+
-+ /* Convert up to the location we're seeking to. */
-+ enum __codecvt_result status;
-+ _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base,
-+ fp->_IO_buf_base + delta);
- _IO_wsetg (fp, fp->_wide_data->_IO_buf_base,
- fp->_wide_data->_IO_buf_base, fp->_wide_data->_IO_buf_base);
++ /* Take the easy way out for constant length encodings if we don't need to
++ convert. */
++ if (!do_convert && clen > 0)
++ {
++ fp->_wide_data->_IO_read_end += ((fp->_IO_read_ptr - fp->_IO_read_base)
++ / clen);
++ goto done;
++ }
+
++ enum __codecvt_result status;
++ const char *read_stop = (const char *) fp->_IO_read_base;
+ do
+ {
-+ struct _IO_codecvt *cv = fp->_codecvt;
-+ const char *read_stop = (const char *) fp->_IO_read_ptr;
+
+ fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state;
+ status = (*cv->__codecvt_do_in) (cv, &fp->_wide_data->_IO_state,
-+ fp->_IO_read_ptr, fp->_IO_read_end,
++ fp->_IO_read_base, fp->_IO_read_ptr,
+ &read_stop,
-+ fp->_wide_data->_IO_read_ptr,
++ fp->_wide_data->_IO_read_base,
+ fp->_wide_data->_IO_buf_end,
+ &fp->_wide_data->_IO_read_end);
+
-+ /* Should we return EILSEQ instead? */
++ /* Should we return EILSEQ? */
+ if (__builtin_expect (status == __codecvt_error, 0))
-+ goto dumb;
-+
-+ fp->_IO_read_ptr = (char *) read_stop;
++ {
++ fp->_flags |= _IO_ERR_SEEN;
++ return -1;
++ }
+ }
+ while (__builtin_expect (status == __codecvt_partial, 0));
+
-+ /* Now seek to the location in the _wide data buffer. */
++done:
++ /* Now seek to the end of the read buffer. */
+ fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end;
+
-+ /* Finally, set _IO_read_end to reflect how much we have actually read in
-+ from the file. */
-+ fp->_IO_read_end = fp->_IO_buf_base + count;
++ return 0;
++}
++
+ _IO_off64_t
+ _IO_wfile_seekoff (fp, offset, dir, mode)
+ _IO_FILE *fp;
+@@ -693,6 +742,10 @@ _IO_wfile_seekoff (fp, offset, dir, mode
+ fp->_wide_data->_IO_buf_base);
+ _IO_wsetp (fp, fp->_wide_data->_IO_buf_base,
+ fp->_wide_data->_IO_buf_base);
++
++ if (adjust_wide_data (fp, false))
++ goto dumb;
+
-+ _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
+ _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
+ goto resync;
+ }
+@@ -733,6 +786,10 @@ _IO_wfile_seekoff (fp, offset, dir, mode
+ _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);
++
++ if (adjust_wide_data (fp, true))
++ goto dumb;
++
fp->_offset = result + count;
_IO_mask_flags (fp, 0, _IO_EOF_SEEN);
-
---MP_/nT+8opq/57jsIpH2GwJ_t+V--
-
+ return offset;
diff --git a/glibc.spec b/glibc.spec
index 51d7902..4db5d58 100644
--- a/glibc.spec
+++ b/glibc.spec
@@ -28,7 +28,7 @@
Summary: The GNU libc libraries
Name: glibc
Version: %{glibcversion}
-Release: 12%{?dist}
+Release: 13%{?dist}
# GPLv2+ is used in a bunch of programs, LGPLv2+ is used for libraries.
# Things that are linked directly into dynamically linked programs
# and shared libraries (e.g. crt files, lib*_nonshared.a) have an additional
@@ -1317,6 +1317,9 @@ rm -f *.filelist*
%endif
%changelog
+* Tue Sep 4 2012 Jeff Law <law at redhat.com> - 2.16-13
+ - Update fseek fix (#854337)
+
* Tue Sep 4 2012 Jeff Law <law at redhat.com> - 2.16-12
- Incorporate ppc64p7 arch changes (#854250)
- Fix fseek in wide mode (#854337)
More information about the scm-commits
mailing list