2018-01-01 08:32:25 +08:00
|
|
|
/* Copyright (C) 1993-2018 Free Software Foundation, Inc.
|
2001-07-06 12:58:11 +08:00
|
|
|
This file is part of the GNU C Library.
|
1997-12-15 06:24:57 +08:00
|
|
|
|
2001-07-06 12:58:11 +08:00
|
|
|
The GNU C Library is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU Lesser General Public
|
|
|
|
License as published by the Free Software Foundation; either
|
|
|
|
version 2.1 of the License, or (at your option) any later version.
|
1997-12-15 06:24:57 +08:00
|
|
|
|
2001-07-06 12:58:11 +08:00
|
|
|
The GNU C Library is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
1997-12-15 06:24:57 +08:00
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
2001-07-06 12:58:11 +08:00
|
|
|
Lesser General Public License for more details.
|
1997-12-15 06:24:57 +08:00
|
|
|
|
2001-07-06 12:58:11 +08:00
|
|
|
You should have received a copy of the GNU Lesser General Public
|
2012-02-10 07:18:22 +08:00
|
|
|
License along with the GNU C Library; if not, see
|
|
|
|
<http://www.gnu.org/licenses/>.
|
1997-12-15 06:24:57 +08:00
|
|
|
|
2001-07-06 12:58:11 +08:00
|
|
|
As a special exception, if you link the code in this file with
|
|
|
|
files compiled with a GNU compiler to produce an executable,
|
|
|
|
that does not cause the resulting executable to be covered by
|
|
|
|
the GNU Lesser General Public License. This exception does not
|
|
|
|
however invalidate any other reasons why the executable file
|
|
|
|
might be covered by the GNU Lesser General Public License.
|
|
|
|
This exception applies to code released by its copyright holders
|
|
|
|
in files containing the exception. */
|
1997-12-15 06:24:57 +08:00
|
|
|
|
2000-03-27 13:18:47 +08:00
|
|
|
#include <shlib-compat.h>
|
|
|
|
#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
|
|
|
|
|
1997-12-15 06:24:57 +08:00
|
|
|
#define _IO_USE_OLD_IO_FILE
|
2012-01-31 05:20:32 +08:00
|
|
|
#include <stdlib.h>
|
1997-12-15 06:24:57 +08:00
|
|
|
#include "libioP.h"
|
|
|
|
#include <fcntl.h>
|
|
|
|
|
2018-02-08 07:42:04 +08:00
|
|
|
FILE *
|
2004-03-10 17:29:17 +08:00
|
|
|
attribute_compat_text_section
|
2015-10-17 04:21:49 +08:00
|
|
|
_IO_old_fdopen (int fd, const char *mode)
|
1997-12-15 06:24:57 +08:00
|
|
|
{
|
|
|
|
int read_write;
|
|
|
|
int posix_mode = 0;
|
|
|
|
struct locked_FILE
|
|
|
|
{
|
2003-11-04 17:58:57 +08:00
|
|
|
struct _IO_FILE_complete_plus fp;
|
1997-12-15 06:24:57 +08:00
|
|
|
#ifdef _IO_MTSAFE_IO
|
|
|
|
_IO_lock_t lock;
|
|
|
|
#endif
|
|
|
|
} *new_f;
|
|
|
|
int fd_flags;
|
|
|
|
|
|
|
|
switch (*mode++)
|
|
|
|
{
|
|
|
|
case 'r':
|
|
|
|
read_write = _IO_NO_WRITES;
|
|
|
|
break;
|
|
|
|
case 'w':
|
|
|
|
read_write = _IO_NO_READS;
|
|
|
|
break;
|
|
|
|
case 'a':
|
|
|
|
posix_mode = O_APPEND;
|
|
|
|
read_write = _IO_NO_READS|_IO_IS_APPENDING;
|
|
|
|
break;
|
|
|
|
default:
|
Remove miscellaneous debris from libio.
This patch eliminates a number of #if 0 and #ifdef TODO blocks, macros
that are never used, macros that provide portability to substrates that
lack basic things like EINVAL and off_t, and other such debris.
I preserved IO_DEBUG and CHECK_FILE, even though as far as I can tell
IO_DEBUG is never defined and therefore CHECK_FILE never does
anything, because it seems like we might actually want to turn it _on_.
Installed stripped libraries and executables are unchanged, except,
again, that the line number of an assertion changes (this time it's
somewhere in fileops.c).
* libio/libio.h (_IO_pos_BAD, _IO_pos_0, _IO_pos_adjust):
Define here, unconditionally.
* libio/iolibio.h (_IO_pos_BAD): Don't define here.
* libio/libioP.h: Remove #if 0 blocks.
(_IO_pos_BAD, _IO_pos_0, _IO_pos_adjust): Don't define here.
(_IO_va_start, COERCE_FILE, MAYBE_SET_EINVAL): Don't define.
(CHECK_FILE): Don't use MAYBE_SET_EINVAL or COERCE_FILE. Fix style.
* libio/clearerr.c, libio/fputc.c, libio/getchar.c:
Assume weak_alias is always defined.
* libio/fileops.c, libio/genops.c, libio/oldfileops.c
* libio/oldpclose.c, libio/pclose.c, libio/wfileops.c:
Remove #if 0 and #ifdef TODO blocks.
Assume text_set_element is always defined.
* libio/iofdopen.c, libio/iogetdelim.c, libio/oldiofdopen.c
Use __set_errno (EINVAL) instead of MAYBE_SET_EINVAL.
* libio/tst-mmap-eofsync.c: Make #if 1 block unconditional.
2018-02-22 03:38:24 +08:00
|
|
|
__set_errno (EINVAL);
|
1997-12-15 06:24:57 +08:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
if (mode[0] == '+' || (mode[0] == 'b' && mode[1] == '+'))
|
|
|
|
read_write &= _IO_IS_APPENDING;
|
2017-08-31 20:07:23 +08:00
|
|
|
fd_flags = __fcntl (fd, F_GETFL);
|
1997-12-15 06:24:57 +08:00
|
|
|
if (fd_flags == -1
|
|
|
|
|| ((fd_flags & O_ACCMODE) == O_RDONLY && !(read_write & _IO_NO_WRITES))
|
|
|
|
|| ((fd_flags & O_ACCMODE) == O_WRONLY && !(read_write & _IO_NO_READS)))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
/* The May 93 draft of P1003.4/D14.1 (redesignated as 1003.1b)
|
|
|
|
[System Application Program Interface (API) Amendment 1:
|
|
|
|
Realtime Extensions], Rationale B.8.3.3
|
|
|
|
Open a Stream on a File Descriptor says:
|
|
|
|
|
|
|
|
Although not explicitly required by POSIX.1, a good
|
|
|
|
implementation of append ("a") mode would cause the
|
|
|
|
O_APPEND flag to be set.
|
|
|
|
|
|
|
|
(Historical implementations [such as Solaris2] do a one-time
|
|
|
|
seek in fdopen.)
|
|
|
|
|
|
|
|
However, we do not turn O_APPEND off if the mode is "w" (even
|
|
|
|
though that would seem consistent) because that would be more
|
|
|
|
likely to break historical programs.
|
|
|
|
*/
|
|
|
|
if ((posix_mode & O_APPEND) && !(fd_flags & O_APPEND))
|
|
|
|
{
|
2017-08-31 20:07:23 +08:00
|
|
|
if (__fcntl (fd, F_SETFL, fd_flags | O_APPEND) == -1)
|
1997-12-15 06:24:57 +08:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE));
|
|
|
|
if (new_f == NULL)
|
|
|
|
return NULL;
|
|
|
|
#ifdef _IO_MTSAFE_IO
|
2003-11-04 17:58:57 +08:00
|
|
|
new_f->fp.file._file._lock = &new_f->lock;
|
1997-12-15 06:24:57 +08:00
|
|
|
#endif
|
2003-11-04 17:58:57 +08:00
|
|
|
_IO_old_init (&new_f->fp.file._file, 0);
|
2015-05-18 19:58:54 +08:00
|
|
|
_IO_JUMPS_FILE_plus (&new_f->fp) = &_IO_old_file_jumps;
|
libio: Implement vtable verification [BZ #20191]
This commit puts all libio vtables in a dedicated, read-only ELF
section, so that they are consecutive in memory. Before any indirect
jump, the vtable pointer is checked against the section boundaries,
and the process is terminated if the vtable pointer does not fall into
the special ELF section.
To enable backwards compatibility, a special flag variable
(_IO_accept_foreign_vtables), protected by the pointer guard, avoids
process termination if libio stream object constructor functions have
been called earlier. Such constructor functions are called by the GCC
2.95 libstdc++ library, and this mechanism ensures compatibility with
old binaries. Existing callers inside glibc of these functions are
adjusted to call the original functions, not the wrappers which enable
vtable compatiblity.
The compatibility mechanism is used to enable passing FILE * objects
across a static dlopen boundary, too.
2016-06-24 02:01:40 +08:00
|
|
|
_IO_old_file_init_internal ((struct _IO_FILE_plus *) &new_f->fp);
|
2003-11-04 17:58:57 +08:00
|
|
|
if (_IO_old_file_attach (&new_f->fp.file._file, fd) == NULL)
|
1997-12-15 06:24:57 +08:00
|
|
|
{
|
2012-05-23 19:33:15 +08:00
|
|
|
_IO_un_link ((struct _IO_FILE_plus *) &new_f->fp);
|
1997-12-15 06:24:57 +08:00
|
|
|
free (new_f);
|
|
|
|
return NULL;
|
|
|
|
}
|
2003-11-04 17:58:57 +08:00
|
|
|
new_f->fp.file._file._flags &= ~_IO_DELETE_DONT_CLOSE;
|
1997-12-15 06:24:57 +08:00
|
|
|
|
2010-07-18 20:51:45 +08:00
|
|
|
_IO_mask_flags (&new_f->fp.file._file, read_write,
|
|
|
|
_IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING);
|
1997-12-15 06:24:57 +08:00
|
|
|
|
2018-02-08 07:42:04 +08:00
|
|
|
return (FILE *) &new_f->fp;
|
1997-12-15 06:24:57 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
strong_alias (_IO_old_fdopen, __old_fdopen)
|
2000-03-27 13:18:47 +08:00
|
|
|
compat_symbol (libc, _IO_old_fdopen, _IO_fdopen, GLIBC_2_0);
|
|
|
|
compat_symbol (libc, __old_fdopen, fdopen, GLIBC_2_0);
|
|
|
|
|
|
|
|
#endif
|