mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-21 12:30:06 +00:00
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:
parent
6c29942cbf
commit
a5406364ac
21
ChangeLog
21
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>
|
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):
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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))
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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 { \
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
|
@ -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"
|
||||||
|
|
||||||
|
@ -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);
|
|
||||||
|
Loading…
Reference in New Issue
Block a user