summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2019-02-18 11:49:54 +0100
committerFlorian Weimer <fweimer@redhat.com>2019-02-18 16:37:00 +0100
commita5406364ac949f91867352cb2ae867629f083c5b (patch)
tree0aeeedc3748d3b21cf8e8ea2e670670df1e441db
parent6c29942cbf059aca47fd4bbd852ea42c9d46b71f (diff)
downloadglibc-a5406364ac949f91867352cb2ae867629f083c5b.tar.gz
libio: Eliminate _IO_stdin, _IO_stdout, _IO_stderr
These variables are only used to determine if a stdio stream is a pre-allocated stream, but it is possible to do so by comparing a FILE * to all pre-allocated stream objects. As a result, it is not necessary to keep those pointers in separate variables. Behavior with symbol interposition is unchanged because _IO_stdin_, _IO_stdout_, _IO_stderr_ are exported, and refer to objects outside of libc if symbol interposition or copy relocations are involved. (The removed variables _IO_stdin, _IO_stdout, _IO_stderr were not exported, of course.)
-rw-r--r--ChangeLog21
-rw-r--r--libio/iofclose.c7
-rw-r--r--libio/iofwide.c3
-rw-r--r--libio/iolibio.h2
-rw-r--r--libio/libio.h3
-rw-r--r--libio/libioP.h30
-rw-r--r--libio/oldfileops.c5
-rw-r--r--libio/oldiofclose.c7
-rw-r--r--libio/oldstdfiles.c18
-rw-r--r--libio/stdfiles.c9
-rw-r--r--libio/stdio.c11
11 files changed, 65 insertions, 51 deletions
diff --git a/ChangeLog b/ChangeLog
index 269c7569c9..a359b0631b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2019-02-18 Florian Weimer <fweimer@redhat.com>
+
+ * libio/libio.h (_IO_stdin, _IO_stdout, _IO_stderr): Remove
+ declaration.
+ * libio/stdio.c (AL, AL2, _IO_stdin, _IO_stdout, _IO_stderr):
+ Remove definitions.
+ * libio/stdfiles.c: Update comment.
+ * libio/oldstdfiles.c (_IO_check_libio): Update comment. Do not
+ set _IO_stdin, _IO_stdout, _IO_stderr.
+ * libio/libioP.h (_IO_fake_stdiobuf): Remove unused declaration.
+ [SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)] (_IO_legacy_file): New
+ inline function.
+ (_IO_deallocate_file): New inline function.
+ * libio/iolibio.h (_IO_vprintf): Remove definition.
+ * libio/iofclose.c (_IO_new_fclose): Use _IO_deallocate_file.
+ * libio/oldiofclose.c (_IO_old_fclose): Likewise.
+ * libio/iofwide.c (_IO_fwide): Use __glibc_unlikely and
+ _IO_legacy_file.
+ * libio/oldfileops.c (_IO_old_file_init_internal): Remove
+ __builtin_expect. Use _IO_legacy_file.
+
2019-02-18 Stefan Liebler <stli@linux.ibm.com>
* sysdeps/unix/sysv/linux/tst-clone3.c (do_test):
diff --git a/libio/iofclose.c b/libio/iofclose.c
index 9b39a6cc4e..8a80dd0b78 100644
--- a/libio/iofclose.c
+++ b/libio/iofclose.c
@@ -71,12 +71,7 @@ _IO_new_fclose (FILE *fp)
if (_IO_have_backup (fp))
_IO_free_backup_area (fp);
}
- if (fp != _IO_stdin && fp != _IO_stdout && fp != _IO_stderr)
- {
- fp->_flags = 0;
- free(fp);
- }
-
+ _IO_deallocate_file (fp);
return status;
}
diff --git a/libio/iofwide.c b/libio/iofwide.c
index 6676ad5e53..247cfde3d0 100644
--- a/libio/iofwide.c
+++ b/libio/iofwide.c
@@ -87,8 +87,7 @@ _IO_fwide (FILE *fp, int mode)
mode = mode < 0 ? -1 : (mode == 0 ? 0 : 1);
#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
- if (__builtin_expect (&_IO_stdin_used == NULL, 0)
- && (fp == _IO_stdin || fp == _IO_stdout || fp == _IO_stderr))
+ if (__glibc_unlikely (&_IO_stdin_used == NULL) && _IO_legacy_file (fp))
/* This is for a stream in the glibc 2.0 format. */
return -1;
#endif
diff --git a/libio/iolibio.h b/libio/iolibio.h
index 2642d71e4f..9561833655 100644
--- a/libio/iolibio.h
+++ b/libio/iolibio.h
@@ -58,8 +58,6 @@ extern int _IO_vsscanf (const char *, const char *, __gnuc_va_list) __THROW;
== _IO_pos_BAD ? EOF : 0)
#define _IO_rewind(FILE) \
(void) _IO_seekoff_unlocked (FILE, 0, 0, _IOS_INPUT|_IOS_OUTPUT)
-#define _IO_vprintf(FORMAT, ARGS) \
- _IO_vfprintf (_IO_stdout, FORMAT, ARGS)
#define _IO_freopen(FILENAME, MODE, FP) \
(_IO_file_close_it (FP), \
_IO_file_fopen (FP, FILENAME, MODE, 1))
diff --git a/libio/libio.h b/libio/libio.h
index 9c08c7eba1..c38095ff77 100644
--- a/libio/libio.h
+++ b/libio/libio.h
@@ -185,9 +185,6 @@ struct _IO_FILE_plus;
extern struct _IO_FILE_plus _IO_2_1_stdin_;
extern struct _IO_FILE_plus _IO_2_1_stdout_;
extern struct _IO_FILE_plus _IO_2_1_stderr_;
-extern FILE *_IO_stdin attribute_hidden;
-extern FILE *_IO_stdout attribute_hidden;
-extern FILE *_IO_stderr attribute_hidden;
struct _IO_cookie_file;
diff --git a/libio/libioP.h b/libio/libioP.h
index 8c75f15167..1c434ec3a1 100644
--- a/libio/libioP.h
+++ b/libio/libioP.h
@@ -817,7 +817,35 @@ extern int _IO_vscanf (const char *, va_list) __THROW;
# endif
#endif
-extern struct _IO_fake_stdiobuf _IO_stdin_buf, _IO_stdout_buf, _IO_stderr_buf;
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
+/* See oldstdfiles.c. These are the old stream variables. */
+extern struct _IO_FILE_plus _IO_stdin_;
+extern struct _IO_FILE_plus _IO_stdout_;
+extern struct _IO_FILE_plus _IO_stderr_;
+
+static inline bool
+_IO_legacy_file (FILE *fp)
+{
+ return fp == (FILE *) &_IO_stdin_ || fp == (FILE *) &_IO_stdout_
+ || fp == (FILE *) &_IO_stderr_;
+}
+#endif
+
+/* Deallocate a stream if it is heap-allocated. Preallocated
+ stdin/stdout/stderr streams are not deallocated. */
+static inline void
+_IO_deallocate_file (FILE *fp)
+{
+ /* The current stream variables. */
+ if (fp == (FILE *) &_IO_2_1_stdin_ || fp == (FILE *) &_IO_2_1_stdout_
+ || fp == (FILE *) &_IO_2_1_stderr_)
+ return;
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
+ if (_IO_legacy_file (fp))
+ return;
+#endif
+ free (fp);
+}
#ifdef IO_DEBUG
# define CHECK_FILE(FILE, RET) do { \
diff --git a/libio/oldfileops.c b/libio/oldfileops.c
index 4d6c5e3fe7..5c319beacd 100644
--- a/libio/oldfileops.c
+++ b/libio/oldfileops.c
@@ -109,10 +109,7 @@ _IO_old_file_init_internal (struct _IO_FILE_plus *fp)
- (int) sizeof (struct _IO_FILE_complete));
fp->file._fileno = -1;
- if (__builtin_expect (&_IO_stdin_used != NULL, 1)
- || (fp != (struct _IO_FILE_plus *) _IO_stdin
- && fp != (struct _IO_FILE_plus *) _IO_stdout
- && fp != (struct _IO_FILE_plus *) _IO_stderr))
+ if (&_IO_stdin_used != NULL || !_IO_legacy_file ((FILE *) fp))
/* The object is dynamically allocated and large enough. Initialize
the _mode element as well. */
((struct _IO_FILE_complete *) fp)->_mode = -1;
diff --git a/libio/oldiofclose.c b/libio/oldiofclose.c
index e4cbf88566..be5044c3bd 100644
--- a/libio/oldiofclose.c
+++ b/libio/oldiofclose.c
@@ -58,12 +58,7 @@ _IO_old_fclose (FILE *fp)
_IO_FINISH (fp);
if (_IO_have_backup (fp))
_IO_free_backup_area (fp);
- if (fp != _IO_stdin && fp != _IO_stdout && fp != _IO_stderr)
- {
- fp->_flags = 0;
- free(fp);
- }
-
+ _IO_deallocate_file (fp);
return status;
}
diff --git a/libio/oldstdfiles.c b/libio/oldstdfiles.c
index 524e260b7e..2b861cd754 100644
--- a/libio/oldstdfiles.c
+++ b/libio/oldstdfiles.c
@@ -27,11 +27,8 @@
#include <shlib-compat.h>
#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
-/* This file provides definitions of _IO_stdin, _IO_stdout, and _IO_stderr
- for C code. Compare stdstreams.cc.
- (The difference is that here the vtable field is set to 0,
- so the objects defined are not valid C++ objects. On the other
- hand, we don't need a C++ compiler to build this file.) */
+/* This file provides legacy definitions of _IO_stdin_, _IO_stdout_,
+ and _IO_stderr_. See stdfiles.c for the current definitions. */
#define _IO_USE_OLD_IO_FILE
#include "libioP.h"
@@ -78,13 +75,12 @@ _IO_check_libio (void)
if (&_IO_stdin_used == NULL)
{
/* We are using the old one. */
- _IO_stdin = stdin = (FILE *) &_IO_stdin_;
- _IO_stdout = stdout = (FILE *) &_IO_stdout_;
- _IO_stderr = stderr = (FILE *) &_IO_stderr_;
+ stdin = (FILE *) &_IO_stdin_;
+ stdout = (FILE *) &_IO_stdout_;
+ stderr = (FILE *) &_IO_stderr_;
_IO_list_all = &_IO_stderr_;
- _IO_stdin->_vtable_offset = _IO_stdout->_vtable_offset =
- _IO_stderr->_vtable_offset = stdin->_vtable_offset =
- stdout->_vtable_offset = stderr->_vtable_offset =
+ stdin->_vtable_offset = stdout->_vtable_offset
+ = stderr->_vtable_offset =
((int) sizeof (struct _IO_FILE)
- (int) sizeof (struct _IO_FILE_complete));
}
diff --git a/libio/stdfiles.c b/libio/stdfiles.c
index 605e006474..9c779b47eb 100644
--- a/libio/stdfiles.c
+++ b/libio/stdfiles.c
@@ -25,11 +25,10 @@
in files containing the exception. */
-/* This file provides definitions of _IO_stdin, _IO_stdout, and _IO_stderr
- for C code. Compare stdstreams.cc.
- (The difference is that here the vtable field is set to 0,
- so the objects defined are not valid C++ objects. On the other
- hand, we don't need a C++ compiler to build this file.) */
+/* This file provides definitions of _IO_2_1_stdin_, _IO_2_1_stdout_,
+ and _IO_2_1_stderr_, the default values of stdin, stdout, stderr.
+ See oldstdfiles.c for glibc 2.0 legacy definitions without wide
+ character support. */
#include "libioP.h"
diff --git a/libio/stdio.c b/libio/stdio.c
index 1294d2842e..522de44a27 100644
--- a/libio/stdio.c
+++ b/libio/stdio.c
@@ -33,14 +33,3 @@
FILE *stdin = (FILE *) &_IO_2_1_stdin_;
FILE *stdout = (FILE *) &_IO_2_1_stdout_;
FILE *stderr = (FILE *) &_IO_2_1_stderr_;
-
-#undef _IO_stdin
-#undef _IO_stdout
-#undef _IO_stderr
-#define AL(name) AL2 (name, _IO_##name)
-#define AL2(name, al) \
- extern __typeof (name) al __attribute__ ((alias (#name), \
- visibility ("hidden")))
-AL(stdin);
-AL(stdout);
-AL(stderr);