This is the mail archive of the libc-hacker@sourceware.cygnus.com mailing list for the glibc project.

Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[PATCH] libio fixes for glibc 2.1.90


Hi!

The following patch makes groff and a bunch of other programs work with
glibc 2.1.90.
The issue is that libstdc++'s libio declares its own stdin/stdout/stderr
which lacks the _wide_data stuff and several pieces of glibc just trustfully
dereference _wide_data member of _IO_FILE.
IMHO even if libstdc++'s libio is changed so that for *-libc6.2-* libstdc++
(or always) puts the _wide_data stuff in, we need to maintain backward
compatibility with older libstdc++'s.
The following patch attempts to do so, by checking if _wide_data is non-NULL
on entry to each routine which accesses _wide_data and it is not yet clear
whether _wide_data is actually non-NULL (e.g. if a routine is always called
from some wide jump table, _wide_data must be non-NULL, which means most
routines should be safe).

Besides this, I've changed _IO_setbuffer/_IO_setvbuf to call _IO_WSETBUF
even for _mode 1. If there is some reason why it is called for _mode 0 only,
then please let me know and revert those two hunks.

man now works just fine with this.

2000-05-21  Jakub Jelinek  <jakub@redhat.com>

	* libio/libioP.h (_IO_CHECK_WIDE): Define.
	* libio/iosetbuffer.c (_IO_setbuffer): Use it.
	Call _IO_WSETBUF even for _mode 1.
	* libio/iosetvbuf.c (_IO_setvbuf): Likewise.
	* libio/wgenops.c (_IO_sputbackwc): If _IO_CHECK_WIDE fails,
	return WEOF.
	* libio/getwc.c (_IO_getwc): Likewise.
	* libio/putwc.c (putwc): Likewise.
	* libio/fputwc.c (fputwc): Likewise.
	* libio/getwc_u.c: Include wchar.h.
	(__getwc_unlocked): If _IO_CHECK_WIDE fails, return WEOF.
	* libio/fputwc_u.c (fputwc_unlocked): Check whether _IO_fwide really
	succeeded in setting to wide mode.
	* libio/fileops.c (_IO_new_file_fopen): Return NULL if
	_IO_CHECK_WIDE fails.
	* libio/iofwide.c (_IO_fwide): Don't change the mode if
	_IO_CHECK_WIDE fails.
	* libio/iogetwline (_IO_getwline_info): If _IO_CHECK_WIDE fails,
	return 0 and WEOF if eof != NULL.

--- libc/libio/bits/stdio.h.jj	Tue Jan  4 17:11:50 2000
+++ libc/libio/bits/stdio.h	Sun May 21 06:16:03 2000
@@ -1,5 +1,5 @@
 /* Optimizing macros and inline functions for stdio functions.
-   Copyright (C) 198 Free Software Foundation, Inc.
+   Copyright (C) 1998 Free Software Foundation, Inc.
 
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public License as
--- libc/libio/iosetbuffer.c.jj	Tue Jan  4 17:11:50 2000
+++ libc/libio/iosetbuffer.c	Sun May 21 13:44:43 2000
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 95, 96, 97, 98, 99 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 95, 96, 97, 98, 99, 2000 Free Software Foundation, Inc.
    This file is part of the GNU IO Library.
 
    This library is free software; you can redistribute it and/or
@@ -38,7 +38,7 @@ _IO_setbuffer (fp, buf, size)
   if (!buf)
     size = 0;
   (void) _IO_SETBUF (fp, buf, size);
-  if (fp->_vtable_offset == 0 && fp->_mode == 0)
+  if (fp->_vtable_offset == 0 && fp->_mode >= 0 && ! _IO_CHECK_WIDE (fp))
     /* We also have to set the buffer using the wide char function.  */
     (void) _IO_WSETBUF (fp, buf, size);
   _IO_funlockfile (fp);
--- libc/libio/wgenops.c.jj	Tue Jan  4 17:11:50 2000
+++ libc/libio/wgenops.c	Sun May 21 13:47:56 2000
@@ -1,4 +1,5 @@
-/* Copyright (C) 1993, 1995, 1997, 1998, 1999 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1995, 1997, 1998, 1999, 2000
+   Free Software Foundation, Inc.
    This file is part of the GNU IO Library.
    Written by Ulrich Drepper <drepper@cygnus.com>.
    Based on the single byte version by Per Bothner <bothner@cygnus.com>.
@@ -607,6 +608,9 @@ _IO_sputbackwc (fp, c)
 {
   wint_t result;
 
+  if (_IO_CHECK_WIDE (fp))
+    return WEOF;
+
   if (fp->_wide_data->_IO_read_ptr > fp->_wide_data->_IO_read_base
       && (wchar_t)fp->_wide_data->_IO_read_ptr[-1] == (wchar_t) c)
     {
--- libc/libio/iosetvbuf.c.jj	Tue Jan  4 17:11:50 2000
+++ libc/libio/iosetvbuf.c	Sun May 21 13:45:35 2000
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+/* Copyright (C) 1993,1996,1997,1998,1999,2000 Free Software Foundation, Inc.
    This file is part of the GNU IO Library.
 
    This library is free software; you can redistribute it and/or
@@ -90,7 +90,8 @@ _IO_setvbuf (fp, buf, mode, size)
       goto unlock_return;
     }
   result = _IO_SETBUF (fp, buf, size) == NULL ? EOF : 0;
-  if (result == 0 && fp->_vtable_offset == 0 && fp->_mode == 0)
+  if (result == 0 && fp->_vtable_offset == 0 && fp->_mode >= 0
+      && ! _IO_CHECK_WIDE (fp))
     /* We also have to set the buffer using the wide char function.  */
     result = _IO_WSETBUF (fp, buf, size) == NULL ? EOF : 0;
 
--- libc/libio/getwc.c.jj	Tue Jan  4 17:11:50 2000
+++ libc/libio/getwc.c	Sun May 21 13:39:12 2000
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 95, 96, 97, 98, 99 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 95, 96, 97, 98, 99, 2000 Free Software Foundation, Inc.
    This file is part of the GNU IO Library.
 
    This library is free software; you can redistribute it and/or
@@ -34,6 +34,8 @@ _IO_getwc (fp)
 {
   wint_t result;
   CHECK_FILE (fp, WEOF);
+  if (_IO_CHECK_WIDE (fp))
+    return WEOF;
   _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
   _IO_flockfile (fp);
   result = _IO_getwc_unlocked (fp);
--- libc/libio/fileops.c.jj	Wed Mar 22 22:36:05 2000
+++ libc/libio/fileops.c	Sun May 21 13:37:53 2000
@@ -278,9 +278,9 @@ _IO_new_file_fopen (fp, filename, mode, 
       /* Yep.  Load the appropriate conversions and set the orientation
 	 to wide.  */
 	struct gconv_fcts fcts;
-	struct _IO_codecvt *cc = &fp->_wide_data->_codecvt;
+	struct _IO_codecvt *cc;
 
-	if (__wcsmbs_named_conv (&fcts, cs + 5) != 0)
+	if (_IO_CHECK_WIDE(fp) || __wcsmbs_named_conv (&fcts, cs + 5) != 0)
 	  {
 	    /* Something went wrong, we cannot load the conversion modules.
 	       This means we cannot proceed since the user explicitly asked
@@ -288,6 +288,8 @@ _IO_new_file_fopen (fp, filename, mode, 
 	    _IO_new_fclose (result);
 	    return NULL;
 	  }
+
+	cc = &fp->_wide_data->_codecvt;
 
 	/* The functions are always the same.  */
 	*cc = __libio_codecvt;
--- libc/libio/iofwide.c.jj	Thu Apr 13 10:57:48 2000
+++ libc/libio/iofwide.c	Sun May 21 13:40:13 2000
@@ -86,7 +86,7 @@ _IO_fwide (fp, mode)
   /* Normalize the value.  */
   mode = mode < 0 ? -1 : (mode == 0 ? 0 : 1);
 
-  if (mode == 0 || fp->_mode != 0)
+  if (mode == 0 || fp->_mode != 0 || _IO_CHECK_WIDE (fp))
     /* The caller simply wants to know about the current orientation
        or the orientation already has been determined.  */
     return fp->_mode;
--- libc/libio/getwc_u.c.jj	Tue Jan  4 17:11:50 2000
+++ libc/libio/getwc_u.c	Sun May 21 13:39:41 2000
@@ -1,4 +1,5 @@
-/* Copyright (C) 1993, 1995, 1996, 1997, 1999 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1995, 1996, 1997, 1999, 2000
+   Free Software Foundation, Inc.
    This file is part of the GNU IO Library.
 
    This library is free software; you can redistribute it and/or
@@ -25,6 +26,7 @@
 
 #include "libioP.h"
 #include "stdio.h"
+#include <wchar.h>
 
 #undef getwc_unlocked
 
@@ -32,6 +34,8 @@ wint_t
 __getwc_unlocked (FILE *fp)
 {
   CHECK_FILE (fp, EOF);
+  if (_IO_CHECK_WIDE (fp))
+    return WEOF;
   return _IO_getwc_unlocked (fp);
 }
 
--- libc/libio/iogetwline.c.jj	Tue Jan  4 17:11:50 2000
+++ libc/libio/iogetwline.c	Sun May 21 13:41:01 2000
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1997, 1998, 1999 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
    This file is part of the GNU IO Library.
 
    This library is free software; you can redistribute it and/or
@@ -60,6 +60,12 @@ _IO_getwline_info (fp, buf, n, delim, ex
   wchar_t *ptr = buf;
   if (eof != NULL)
     *eof = 0;
+  if (_IO_CHECK_WIDE (fp))
+    {
+      if (eof != NULL)
+	*eof = WEOF;
+      return 0;
+    }
   while (n != 0)
     {
       _IO_ssize_t len = (fp->_wide_data->_IO_read_end
--- libc/libio/fputwc.c.jj	Tue Jan  4 17:11:50 2000
+++ libc/libio/fputwc.c	Sun May 21 13:38:20 2000
@@ -1,4 +1,5 @@
-/* Copyright (C) 1993, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1996, 1997, 1998, 1999, 2000
+   Free Software Foundation, Inc.
    This file is part of the GNU IO Library.
 
    This library is free software; you can redistribute it and/or
@@ -33,6 +34,8 @@ fputwc (wc, fp)
 {
   int result;
   CHECK_FILE (fp, EOF);
+  if (_IO_CHECK_WIDE (fp))
+    return WEOF;
   _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
   _IO_flockfile (fp);
   if (_IO_fwide (fp, 1) < 0)
--- libc/libio/fputwc_u.c.jj	Tue Jan  4 17:11:50 2000
+++ libc/libio/fputwc_u.c	Sun May 21 13:38:37 2000
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1996, 1997, 1999 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1996, 1997, 1999, 2000 Free Software Foundation, Inc.
    This file is part of the GNU IO Library.
 
    This library is free software; you can redistribute it and/or
@@ -34,7 +34,7 @@ fputwc_unlocked (wc, fp)
      _IO_FILE *fp;
 {
   CHECK_FILE (fp, EOF);
-  if (_IO_fwide (fp, 1) < 0)
+  if (_IO_fwide (fp, 1) != 1)
     return WEOF;
   return _IO_putwc_unlocked (wc, fp);
 }
--- libc/libio/putwc.c.jj	Tue Jan  4 17:11:50 2000
+++ libc/libio/putwc.c	Sun May 21 13:46:33 2000
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 95, 96, 97, 98, 99 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 95, 96, 97, 98, 99, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -26,6 +26,8 @@ putwc (wc, fp)
 {
   wint_t result;
   CHECK_FILE (fp, WEOF);
+  if (_IO_CHECK_WIDE (fp))
+    return WEOF;
   _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
   _IO_flockfile (fp);
   result = _IO_putwc_unlocked (wc, fp);
--- libc/libio/libioP.h.jj	Wed Mar 22 22:36:05 2000
+++ libc/libio/libioP.h	Sun May 21 13:37:00 2000
@@ -71,6 +71,9 @@ extern "C" {
 
 #define _IO_JUMPS(THIS) ((struct _IO_FILE_plus *) (THIS))->vtable
 #define _IO_WIDE_JUMPS(THIS) ((struct _IO_FILE *) (THIS))->_wide_data->_wide_vtable
+
+#define _IO_CHECK_WIDE(THIS) (((struct _IO_FILE *) (THIS))->_wide_data == NULL)
+
 #if _IO_JUMPS_OFFSET
 # define _IO_JUMPS_FUNC(THIS) \
  (*(struct _IO_jump_t **) ((void *) &((struct _IO_FILE_plus *) (THIS))->vtable\

	Jakub

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]