summary refs log tree commit diff
path: root/libio
diff options
context:
space:
mode:
Diffstat (limited to 'libio')
-rw-r--r--libio/Makefile4
-rw-r--r--libio/freopen.c21
-rw-r--r--libio/iofclose.c13
-rw-r--r--libio/iolibio.h2
-rw-r--r--libio/libio.h16
-rw-r--r--libio/libioP.h3
-rw-r--r--libio/oldfileops.c14
-rw-r--r--libio/oldiofclose.c (renamed from libio/oldfreopen.c)40
-rw-r--r--libio/oldiofopen.c6
-rw-r--r--libio/oldstdfiles.c50
-rw-r--r--libio/stdfiles.c17
-rw-r--r--libio/stdio.c13
12 files changed, 137 insertions, 62 deletions
diff --git a/libio/Makefile b/libio/Makefile
index 033c959889..f3a66f32ca 100644
--- a/libio/Makefile
+++ b/libio/Makefile
@@ -43,7 +43,7 @@ all: # Make this the default target; it will be defined in Rules.
 include ../Makeconfig
 
 ifeq ($(versioning),yes)
-routines += oldiofopen oldfreopen
+routines += oldiofopen oldiofclose
 endif
 
 CPPFLAGS-.o += -DIO_DEBUG
@@ -62,7 +62,7 @@ ifeq ($(versioning),yes)
 aux	+= oldfileops oldstdfiles
 endif
 
-shared-only-routines = oldiofopen oldfreopen oldfileops oldstdfiles
+shared-only-routines = oldiofopen oldiofclose oldfileops oldstdfiles
 
 distribute := iolibio.h libioP.h strfile.h Banner
 
diff --git a/libio/freopen.c b/libio/freopen.c
index 7ab3e69845..808d8fab58 100644
--- a/libio/freopen.c
+++ b/libio/freopen.c
@@ -26,8 +26,13 @@
 #include "libioP.h"
 #include "stdio.h"
 
+#ifdef PIC
+extern void *_IO_stdin_used;
+weak_extern (_IO_stdin_used);
+#endif
+
 FILE*
-__new_freopen (filename, mode, fp)
+freopen (filename, mode, fp)
      const char* filename;
      const char* mode;
      FILE* fp;
@@ -38,9 +43,17 @@ __new_freopen (filename, mode, fp)
     return NULL;
   _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
   _IO_flockfile (fp);
-  result = _IO_freopen (filename, mode, fp);
+#ifdef PIC
+  if (&_IO_stdin_used == NULL)
+    /* If the shared C library is used by the application binary which
+       was linked against the older version of libio, we just use the
+       older one even for internal use to avoid trouble since a pointer
+       to the old libio may be passed into shared C library and wind
+       up here. */
+    result = _IO_old_freopen (filename, mode, fp);
+  else
+#endif
+    result = _IO_freopen (filename, mode, fp);
   _IO_cleanup_region_end (1);
   return result;
 }
-
-default_symbol_version (__new_freopen, freopen, GLIBC_2.1);
diff --git a/libio/iofclose.c b/libio/iofclose.c
index 35f4a8b569..35a23fa6ae 100644
--- a/libio/iofclose.c
+++ b/libio/iofclose.c
@@ -29,7 +29,7 @@
 #endif
 
 int
-_IO_fclose (fp)
+_IO_new_fclose (fp)
      _IO_FILE *fp;
 {
   int status;
@@ -53,6 +53,13 @@ _IO_fclose (fp)
   return status;
 }
 
-#ifdef weak_alias
-weak_alias (_IO_fclose, fclose)
+#ifdef DO_VERSIONING
+strong_alias (_IO_new_fclose, __new_fclose)
+default_symbol_version (_IO_new_fclose, _IO_fclose, GLIBC_2.1);
+default_symbol_version (__new_fclose, fclose, GLIBC_2.1);
+#else
+# ifdef weak_alias
+weak_alias (_IO_new_fclose, _IO_fclose)
+weak_alias (_IO_new_fclose, fclose)
+# endif
 #endif
diff --git a/libio/iolibio.h b/libio/iolibio.h
index bb5506444f..c1a9184305 100644
--- a/libio/iolibio.h
+++ b/libio/iolibio.h
@@ -53,7 +53,7 @@ extern int _IO_obstack_printf __P ((struct obstack *, const char *, ...));
 #define _IO_freopen(FILENAME, MODE, FP) \
   (_IO_file_close_it(FP), _IO_file_fopen(FP, FILENAME, MODE, 0))
 #define _IO_old_freopen(FILENAME, MODE, FP) \
-  (_IO_file_close_it(FP), _IO_old_file_fopen(FP, FILENAME, MODE))
+  (_IO_old_file_close_it (FP), _IO_old_file_fopen(FP, FILENAME, MODE))
 #define _IO_freopen64(FILENAME, MODE, FP) \
   (_IO_file_close_it(FP), _IO_file_fopen(FP, FILENAME, MODE, 1))
 #define _IO_fileno(FP) ((FP)->_fileno)
diff --git a/libio/libio.h b/libio/libio.h
index 7c91f6f6de..0c12ff0dc6 100644
--- a/libio/libio.h
+++ b/libio/libio.h
@@ -225,10 +225,18 @@ typedef struct _IO_FILE _IO_FILE;
 #endif
 
 struct _IO_FILE_complete;
-extern struct _IO_FILE_complete _IO_stdin_, _IO_stdout_, _IO_stderr_;
-#define _IO_stdin ((_IO_FILE*)(&_IO_stdin_))
-#define _IO_stdout ((_IO_FILE*)(&_IO_stdout_))
-#define _IO_stderr ((_IO_FILE*)(&_IO_stderr_))
+extern struct _IO_FILE_complete _IO_2_1_stdin_;
+extern struct _IO_FILE_complete _IO_2_1_stdout_;
+extern struct _IO_FILE_complete _IO_2_1_stderr_;
+#ifndef _LIBC
+#define _IO_stdin ((_IO_FILE*)(&_IO_2_1_stdin_))
+#define _IO_stdout ((_IO_FILE*)(&_IO_2_1_stdout_))
+#define _IO_stderr ((_IO_FILE*)(&_IO_2_1_stderr_))
+#else
+extern _IO_FILE *_IO_stdin;
+extern _IO_FILE *_IO_stdout;
+extern _IO_FILE *_IO_stderr;
+#endif
 
 
 /* Define the user-visible type, with user-friendly member names.  */
diff --git a/libio/libioP.h b/libio/libioP.h
index a90a604e53..a69d75b485 100644
--- a/libio/libioP.h
+++ b/libio/libioP.h
@@ -346,6 +346,9 @@ extern void _IO_flush_all_linebuffered __P ((void));
 #define _IO_do_flush(_f) \
   _IO_do_write(_f, (_f)->_IO_write_base, \
 	       (_f)->_IO_write_ptr-(_f)->_IO_write_base)
+#define _IO_old_do_flush(_f) \
+  _IO_old_do_write(_f, (_f)->_IO_write_base, \
+		   (_f)->_IO_write_ptr-(_f)->_IO_write_base)
 #define _IO_in_put_mode(_fp) ((_fp)->_flags & _IO_CURRENTLY_PUTTING)
 #define _IO_mask_flags(fp, f, mask) \
        ((fp)->_flags = ((fp)->_flags & ~(mask)) | ((f) & (mask)))
diff --git a/libio/oldfileops.c b/libio/oldfileops.c
index b426e88364..eec9eed670 100644
--- a/libio/oldfileops.c
+++ b/libio/oldfileops.c
@@ -130,7 +130,7 @@ _IO_old_file_close_it (fp)
   if (!_IO_file_is_open (fp))
     return EOF;
 
-  write_status = _IO_do_flush (fp);
+  write_status = _IO_old_do_flush (fp);
 
   _IO_unsave_markers(fp);
 
@@ -156,7 +156,7 @@ _IO_old_file_finish (fp, dummy)
 {
   if (_IO_file_is_open (fp))
     {
-      _IO_do_flush (fp);
+      _IO_old_do_flush (fp);
       if (!(fp->_flags & _IO_DELETE_DONT_CLOSE))
 	_IO_SYSCLOSE (fp);
     }
@@ -378,14 +378,14 @@ _IO_old_file_overflow (f, ch)
       f->_flags |= _IO_CURRENTLY_PUTTING;
     }
   if (ch == EOF)
-    return _IO_do_flush (f);
+    return _IO_old_do_flush (f);
   if (f->_IO_write_ptr == f->_IO_buf_end ) /* Buffer is really full */
-    if (_IO_do_flush (f) == EOF)
+    if (_IO_old_do_flush (f) == EOF)
       return EOF;
   *f->_IO_write_ptr++ = ch;
   if ((f->_flags & _IO_UNBUFFERED)
       || ((f->_flags & _IO_LINE_BUF) && ch == '\n'))
-    if (_IO_do_flush (f) == EOF)
+    if (_IO_old_do_flush (f) == EOF)
       return EOF;
   return (unsigned char) ch;
 }
@@ -401,7 +401,7 @@ _IO_old_file_sync (fp)
   _IO_flockfile (fp);
   /*    char* ptr = cur_ptr(); */
   if (fp->_IO_write_ptr > fp->_IO_write_base)
-    if (_IO_do_flush(fp)) return EOF;
+    if (_IO_old_do_flush(fp)) return EOF;
   delta = fp->_IO_read_ptr - fp->_IO_read_end;
   if (delta != 0)
     {
@@ -679,7 +679,7 @@ _IO_old_file_xsputn (f, data, n)
       dont_write = block_size >= 128 ? to_do % block_size : 0;
 
       count = to_do - dont_write;
-      if (_IO_do_write (f, s, count) == EOF)
+      if (_IO_old_do_write (f, s, count) == EOF)
 	return n - to_do;
       to_do = dont_write;
 
diff --git a/libio/oldfreopen.c b/libio/oldiofclose.c
index 705965c336..5eed0661ec 100644
--- a/libio/oldfreopen.c
+++ b/libio/oldiofclose.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1995, 1997 Free Software Foundation, Inc.
    This file is part of the GNU IO Library.
 
    This library is free software; you can redistribute it and/or
@@ -24,23 +24,35 @@
    General Public License.  */
 
 #include "libioP.h"
-#include "stdio.h"
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
 
-FILE*
-__old_freopen (filename, mode, fp)
-     const char* filename;
-     const char* mode;
-     FILE* fp;
+int
+_IO_old_fclose (fp)
+     _IO_FILE *fp;
 {
-  FILE *result;
-  CHECK_FILE (fp, NULL);
-  if (!(fp->_flags & _IO_IS_FILEBUF))
-    return NULL;
+  int status;
+
+  CHECK_FILE(fp, EOF);
+
   _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
   _IO_flockfile (fp);
-  result = _IO_old_freopen (filename, mode, fp);
+  if (fp->_IO_file_flags & _IO_IS_FILEBUF)
+    status = _IO_old_file_close_it (fp);
+  else
+    status = fp->_flags & _IO_ERR_SEEN ? -1 : 0;
+  _IO_FINISH (fp);
   _IO_cleanup_region_end (1);
-  return result;
+  if (fp != _IO_stdin && fp != _IO_stdout && fp != _IO_stderr)
+    {
+      fp->_IO_file_flags = 0;
+      free(fp);
+    }
+
+  return status;
 }
 
-symbol_version (__old_freopen, freopen,);
+strong_alias (_IO_old_fclose, __old_fclose)
+symbol_version (_IO_old_fclose, _IO_fclose, GLIBC_2.0);
+symbol_version (__old_fclose, fclose, GLIBC_2.0);
diff --git a/libio/oldiofopen.c b/libio/oldiofopen.c
index c37ec0309a..d0ffb02b13 100644
--- a/libio/oldiofopen.c
+++ b/libio/oldiofopen.c
@@ -49,7 +49,7 @@ _IO_old_fopen (filename, mode)
 #endif
   _IO_init (&new_f->fp.file, 0);
   _IO_JUMPS (&new_f->fp.file) = &_IO_old_file_jumps;
-  _IO_file_init (&new_f->fp.file);
+  _IO_old_file_init (&new_f->fp.file);
 #if  !_IO_UNIFIED_JUMPTABLES
   new_f->fp.vtable = NULL;
 #endif
@@ -61,5 +61,5 @@ _IO_old_fopen (filename, mode)
 }
 
 strong_alias (_IO_old_fopen, __old_fopen)
-symbol_version (_IO_old_fopen, _IO_fopen,);
-symbol_version (__old_fopen, fopen,);
+symbol_version (_IO_old_fopen, _IO_fopen, GLIBC_2.0);
+symbol_version (__old_fopen, fopen, GLIBC_2.0);
diff --git a/libio/oldstdfiles.c b/libio/oldstdfiles.c
index 3017109581..64c792f7a0 100644
--- a/libio/oldstdfiles.c
+++ b/libio/oldstdfiles.c
@@ -36,22 +36,52 @@
 #define DEF_STDFILE(INAME, NAME, FD, CHAIN, FLAGS) \
   static _IO_lock_t _IO_stdfile_##FD##_lock = _IO_lock_initializer; \
   struct _IO_FILE_plus INAME \
-    = {FILEBUF_LITERAL(CHAIN, FLAGS, FD), &_IO_old_file_jumps}; \
-  symbol_version (INAME, NAME,)
+    = {FILEBUF_LITERAL(CHAIN, FLAGS, FD), &_IO_old_file_jumps};
 #else
 #define DEF_STDFILE(INAME, NAME, FD, CHAIN, FLAGS) \
   struct _IO_FILE_plus INAME \
-    = {FILEBUF_LITERAL(CHAIN, FLAGS, FD), &_IO_old_file_jumps}; \
-  symbol_version (INAME, NAME,)
+    = {FILEBUF_LITERAL(CHAIN, FLAGS, FD), &_IO_old_file_jumps};
 #endif
 
-DEF_STDFILE(_IO_old_stdin_, _IO_stdin_, 0, 0, _IO_NO_WRITES);
-DEF_STDFILE(_IO_old_stdout_, _IO_stdout_, 1, &_IO_stdin_.plus.file,
+DEF_STDFILE(_IO_stdin_, _IO_stdin_, 0, 0, _IO_NO_WRITES);
+DEF_STDFILE(_IO_stdout_, _IO_stdout_, 1, &_IO_stdin_.file,
 	    _IO_NO_READS);
-DEF_STDFILE(_IO_old_stderr_, _IO_stderr_, 2, &_IO_stdout_.plus.file,
+DEF_STDFILE(_IO_stderr_, _IO_stderr_, 2, &_IO_stdout_.file,
             _IO_NO_READS+_IO_UNBUFFERED);
 
-#if 0
-_IO_FILE *_IO_old_list_all = &_IO_stderr_.plus.file;
-symbol_version (_IO_old_list_all, _IO_list_all,);
+#if defined __GNUC__ && __GNUC__ >= 2
+
+#include <stdio.h>
+
+extern void * _IO_stdin_used;
+weak_extern (_IO_stdin_used);
+
+#undef stdin
+#undef stdout
+#undef stderr
+
+extern FILE *stdin;
+extern FILE *stdout;
+extern FILE *stderr;
+
+extern FILE *_IO_list_all;
+
+static void _IO_check_libio __P ((void)) __attribute__ ((constructor));
+
+/* This function determines which shared C library the application
+   was linked against. We then set up the stdin/stdout/stderr and
+   _IO_list_all accordingly. */
+
+static void
+_IO_check_libio ()
+{
+  if (&_IO_stdin_used == NULL)
+    {
+      /* We are using the old one. */
+      stdin = &_IO_stdin_.file;
+      stdout = &_IO_stdout_.file;
+      stderr = _IO_list_all = &_IO_stderr_.file;
+    }
+}
+
 #endif
diff --git a/libio/stdfiles.c b/libio/stdfiles.c
index 7eb828350c..c70d47423d 100644
--- a/libio/stdfiles.c
+++ b/libio/stdfiles.c
@@ -36,22 +36,17 @@
 #define DEF_STDFILE(INAME, NAME, FD, CHAIN, FLAGS) \
   static _IO_lock_t _IO_stdfile_##FD##_lock = _IO_lock_initializer; \
   struct _IO_FILE_complete INAME \
-    = {{FILEBUF_LITERAL(CHAIN, FLAGS, FD), &_IO_file_jumps},}; \
-  default_symbol_version (INAME, NAME, GLIBC_2.1)
+    = {{FILEBUF_LITERAL(CHAIN, FLAGS, FD), &_IO_file_jumps},};
 #else
 #define DEF_STDFILE(INAME, NAME, FD, CHAIN, FLAGS) \
   struct _IO_FILE_complete INAME \
-    = {{FILEBUF_LITERAL(CHAIN, FLAGS, FD), &_IO_file_jumps},}; \
-  default_symbol_version (INAME, NAME, GLIBC_2.1)
+    = {{FILEBUF_LITERAL(CHAIN, FLAGS, FD), &_IO_file_jumps},};
 #endif
 
-DEF_STDFILE(_IO_new_stdin_, _IO_stdin_, 0, 0, _IO_NO_WRITES);
-DEF_STDFILE(_IO_new_stdout_, _IO_stdout_, 1, &_IO_stdin_.plus.file,
+DEF_STDFILE(_IO_2_1_stdin_, _IO_stdin_, 0, 0, _IO_NO_WRITES);
+DEF_STDFILE(_IO_2_1_stdout_, _IO_stdout_, 1, &_IO_2_1_stdin_.plus.file,
 	    _IO_NO_READS);
-DEF_STDFILE(_IO_new_stderr_, _IO_stderr_, 2, &_IO_stdout_.plus.file,
+DEF_STDFILE(_IO_2_1_stderr_, _IO_stderr_, 2, &_IO_2_1_stdout_.plus.file,
             _IO_NO_READS+_IO_UNBUFFERED);
 
-_IO_FILE *_IO_list_all = &_IO_stderr_.plus.file;
-#if 0
-default_symbol_version (_IO_new_list_all, _IO_list_all, GLIBC_2.1);
-#endif
+_IO_FILE *_IO_list_all = &_IO_2_1_stderr_.plus.file;
diff --git a/libio/stdio.c b/libio/stdio.c
index d38379f821..abea7f38ba 100644
--- a/libio/stdio.c
+++ b/libio/stdio.c
@@ -29,6 +29,13 @@
 #undef stdin
 #undef stdout
 #undef stderr
-FILE *stdin = &_IO_stdin_.plus.file;
-FILE *stdout = &_IO_stdout_.plus.file;
-FILE *stderr = &_IO_stderr_.plus.file;
+FILE *stdin = &_IO_2_1_stdin_.plus.file;
+FILE *stdout = &_IO_2_1_stdout_.plus.file;
+FILE *stderr = &_IO_2_1_stderr_.plus.file;
+
+#undef _IO_stdin
+#undef _IO_stdout
+#undef _IO_stderr
+strong_alias (stdin, _IO_stdin);
+strong_alias (stdout, _IO_stdout);
+strong_alias (stderr, _IO_stderr);