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.)
This commit is contained in:
Florian Weimer 2019-02-18 11:49:54 +01:00
parent 6c29942cbf
commit a5406364ac
11 changed files with 65 additions and 51 deletions

View File

@ -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> 2019-02-18 Stefan Liebler <stli@linux.ibm.com>
* sysdeps/unix/sysv/linux/tst-clone3.c (do_test): * sysdeps/unix/sysv/linux/tst-clone3.c (do_test):

View File

@ -71,12 +71,7 @@ _IO_new_fclose (FILE *fp)
if (_IO_have_backup (fp)) if (_IO_have_backup (fp))
_IO_free_backup_area (fp); _IO_free_backup_area (fp);
} }
if (fp != _IO_stdin && fp != _IO_stdout && fp != _IO_stderr) _IO_deallocate_file (fp);
{
fp->_flags = 0;
free(fp);
}
return status; return status;
} }

View File

@ -87,8 +87,7 @@ _IO_fwide (FILE *fp, int mode)
mode = mode < 0 ? -1 : (mode == 0 ? 0 : 1); mode = mode < 0 ? -1 : (mode == 0 ? 0 : 1);
#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
if (__builtin_expect (&_IO_stdin_used == NULL, 0) if (__glibc_unlikely (&_IO_stdin_used == NULL) && _IO_legacy_file (fp))
&& (fp == _IO_stdin || fp == _IO_stdout || fp == _IO_stderr))
/* This is for a stream in the glibc 2.0 format. */ /* This is for a stream in the glibc 2.0 format. */
return -1; return -1;
#endif #endif

View File

@ -58,8 +58,6 @@ extern int _IO_vsscanf (const char *, const char *, __gnuc_va_list) __THROW;
== _IO_pos_BAD ? EOF : 0) == _IO_pos_BAD ? EOF : 0)
#define _IO_rewind(FILE) \ #define _IO_rewind(FILE) \
(void) _IO_seekoff_unlocked (FILE, 0, 0, _IOS_INPUT|_IOS_OUTPUT) (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) \ #define _IO_freopen(FILENAME, MODE, FP) \
(_IO_file_close_it (FP), \ (_IO_file_close_it (FP), \
_IO_file_fopen (FP, FILENAME, MODE, 1)) _IO_file_fopen (FP, FILENAME, MODE, 1))

View File

@ -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_stdin_;
extern struct _IO_FILE_plus _IO_2_1_stdout_; extern struct _IO_FILE_plus _IO_2_1_stdout_;
extern struct _IO_FILE_plus _IO_2_1_stderr_; 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; struct _IO_cookie_file;

View File

@ -817,7 +817,35 @@ extern int _IO_vscanf (const char *, va_list) __THROW;
# endif # endif
#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 #ifdef IO_DEBUG
# define CHECK_FILE(FILE, RET) do { \ # define CHECK_FILE(FILE, RET) do { \

View File

@ -109,10 +109,7 @@ _IO_old_file_init_internal (struct _IO_FILE_plus *fp)
- (int) sizeof (struct _IO_FILE_complete)); - (int) sizeof (struct _IO_FILE_complete));
fp->file._fileno = -1; fp->file._fileno = -1;
if (__builtin_expect (&_IO_stdin_used != NULL, 1) if (&_IO_stdin_used != NULL || !_IO_legacy_file ((FILE *) fp))
|| (fp != (struct _IO_FILE_plus *) _IO_stdin
&& fp != (struct _IO_FILE_plus *) _IO_stdout
&& fp != (struct _IO_FILE_plus *) _IO_stderr))
/* The object is dynamically allocated and large enough. Initialize /* The object is dynamically allocated and large enough. Initialize
the _mode element as well. */ the _mode element as well. */
((struct _IO_FILE_complete *) fp)->_mode = -1; ((struct _IO_FILE_complete *) fp)->_mode = -1;

View File

@ -58,12 +58,7 @@ _IO_old_fclose (FILE *fp)
_IO_FINISH (fp); _IO_FINISH (fp);
if (_IO_have_backup (fp)) if (_IO_have_backup (fp))
_IO_free_backup_area (fp); _IO_free_backup_area (fp);
if (fp != _IO_stdin && fp != _IO_stdout && fp != _IO_stderr) _IO_deallocate_file (fp);
{
fp->_flags = 0;
free(fp);
}
return status; return status;
} }

View File

@ -27,11 +27,8 @@
#include <shlib-compat.h> #include <shlib-compat.h>
#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
/* This file provides definitions of _IO_stdin, _IO_stdout, and _IO_stderr /* This file provides legacy definitions of _IO_stdin_, _IO_stdout_,
for C code. Compare stdstreams.cc. and _IO_stderr_. See stdfiles.c for the current definitions. */
(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.) */
#define _IO_USE_OLD_IO_FILE #define _IO_USE_OLD_IO_FILE
#include "libioP.h" #include "libioP.h"
@ -78,13 +75,12 @@ _IO_check_libio (void)
if (&_IO_stdin_used == NULL) if (&_IO_stdin_used == NULL)
{ {
/* We are using the old one. */ /* We are using the old one. */
_IO_stdin = stdin = (FILE *) &_IO_stdin_; stdin = (FILE *) &_IO_stdin_;
_IO_stdout = stdout = (FILE *) &_IO_stdout_; stdout = (FILE *) &_IO_stdout_;
_IO_stderr = stderr = (FILE *) &_IO_stderr_; stderr = (FILE *) &_IO_stderr_;
_IO_list_all = &_IO_stderr_; _IO_list_all = &_IO_stderr_;
_IO_stdin->_vtable_offset = _IO_stdout->_vtable_offset = stdin->_vtable_offset = stdout->_vtable_offset
_IO_stderr->_vtable_offset = stdin->_vtable_offset = = stderr->_vtable_offset =
stdout->_vtable_offset = stderr->_vtable_offset =
((int) sizeof (struct _IO_FILE) ((int) sizeof (struct _IO_FILE)
- (int) sizeof (struct _IO_FILE_complete)); - (int) sizeof (struct _IO_FILE_complete));
} }

View File

@ -25,11 +25,10 @@
in files containing the exception. */ in files containing the exception. */
/* This file provides definitions of _IO_stdin, _IO_stdout, and _IO_stderr /* This file provides definitions of _IO_2_1_stdin_, _IO_2_1_stdout_,
for C code. Compare stdstreams.cc. and _IO_2_1_stderr_, the default values of stdin, stdout, stderr.
(The difference is that here the vtable field is set to 0, See oldstdfiles.c for glibc 2.0 legacy definitions without wide
so the objects defined are not valid C++ objects. On the other character support. */
hand, we don't need a C++ compiler to build this file.) */
#include "libioP.h" #include "libioP.h"

View File

@ -33,14 +33,3 @@
FILE *stdin = (FILE *) &_IO_2_1_stdin_; FILE *stdin = (FILE *) &_IO_2_1_stdin_;
FILE *stdout = (FILE *) &_IO_2_1_stdout_; FILE *stdout = (FILE *) &_IO_2_1_stdout_;
FILE *stderr = (FILE *) &_IO_2_1_stderr_; 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);