[PATCH] libio fixes for glibc 2.1.90
Jakub Jelinek
jakub@redhat.com
Sun May 21 05:35:00 GMT 2000
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
More information about the Libc-hacker
mailing list