diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2018-12-27 19:01:57 +0000 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2018-12-27 19:01:57 +0000 |
commit | cab56836b146bc129f1ad43f0393d95a9deca63a (patch) | |
tree | 4f4e655319bbac78fca170da05275c127429b460 /libio | |
parent | 04ac1241a4cd004872282c2c82ec37fa33925292 (diff) | |
parent | 82dd75a7f436a19047325d62182590c9f9e23a78 (diff) |
Merge branch 't/tls' into refs/top-bases/t/tls-threadvar
Diffstat (limited to 'libio')
182 files changed, 3776 insertions, 3127 deletions
diff --git a/libio/Makefile b/libio/Makefile index 4189bc4ad0..cab0eae946 100644 --- a/libio/Makefile +++ b/libio/Makefile @@ -1,4 +1,4 @@ -# Copyright (C) 1995-2016 Free Software Foundation, Inc. +# Copyright (C) 1995-2018 Free Software Foundation, Inc. # This file is part of the GNU C Library. # The GNU C Library is free software; you can redistribute it and/or @@ -22,8 +22,11 @@ subdir := libio include ../Makeconfig -headers := stdio.h libio.h _G_config.h bits/stdio.h \ - bits/sys_errlist.h bits/stdio2.h bits/stdio-ldbl.h bits/libio-ldbl.h +headers := stdio.h \ + bits/stdio.h bits/stdio2.h bits/sys_errlist.h bits/stdio-ldbl.h \ + bits/types/FILE.h bits/types/__FILE.h bits/types/struct_FILE.h \ + bits/types/__fpos_t.h bits/types/__fpos64_t.h \ + bits/types/cookie_io_functions_t.h routines := \ filedoalloc iofclose iofdopen iofflush iofgetpos iofgets iofopen \ @@ -46,7 +49,7 @@ routines := \ __fbufsize __freading __fwriting __freadable __fwritable __flbf \ __fpurge __fpending __fsetlocking \ \ - libc_fatal fmemopen oldfmemopen + libc_fatal fmemopen oldfmemopen vtables readline tests = tst_swprintf tst_wprintf tst_swscanf tst_wscanf tst_getwc tst_putwc \ tst_wprintf2 tst-widetext test-fmemopen tst-ext tst-ext2 \ @@ -56,12 +59,15 @@ tests = tst_swprintf tst_wprintf tst_swscanf tst_wscanf tst_getwc tst_putwc \ tst-mmap-eofsync tst-mmap-fflushsync bug-mmap-fflush \ tst-mmap2-eofsync tst-mmap-offend bug-fopena+ bug-wfflush \ bug-ungetc2 bug-ftell bug-ungetc3 bug-ungetc4 tst-fopenloc2 \ - tst-memstream1 tst-memstream2 \ - tst-wmemstream1 tst-wmemstream2 \ + tst-memstream1 tst-memstream2 tst-memstream3 \ + tst-wmemstream1 tst-wmemstream2 tst-wmemstream3 \ bug-memstream1 bug-wmemstream1 \ tst-setvbuf1 tst-popen1 tst-fgetwc bug-wsetpos tst-fseek \ tst-fwrite-error tst-ftell-partial-wide tst-ftell-active-handler \ - tst-ftell-append tst-fputws + tst-ftell-append tst-fputws tst-bz22415 tst-fgetc-after-eof + +tests-internal = tst-vtables tst-vtables-interposed tst-readline + ifeq (yes,$(build-shared)) # Add test-fopenloc only if shared library is enabled since it depends on # shared localedata objects. @@ -84,75 +90,77 @@ endif CPPFLAGS += $(libio-mtsafe) # Support for exception handling. -CFLAGS-fileops.c = -fexceptions -CFLAGS-fputc.c = -fexceptions -CFLAGS-fputwc.c = -fexceptions -CFLAGS-freopen64.c = -fexceptions -CFLAGS-freopen.c = -fexceptions -CFLAGS-fseek.c = -fexceptions -CFLAGS-fseeko64.c = -fexceptions -CFLAGS-fseeko.c = -fexceptions -CFLAGS-ftello64.c = -fexceptions -CFLAGS-ftello.c = -fexceptions -CFLAGS-fwide.c = -fexceptions -CFLAGS-genops.c = -fexceptions -CFLAGS-getc.c = -fexceptions -CFLAGS-getchar.c = -fexceptions -CFLAGS-getwc.c = -fexceptions -CFLAGS-getwchar.c = -fexceptions -CFLAGS-iofclose.c = -fexceptions -CFLAGS-iofflush.c = -fexceptions -CFLAGS-iofgetpos64.c = -fexceptions -CFLAGS-iofgetpos.c = -fexceptions -CFLAGS-iofgets.c = -fexceptions -CFLAGS-iofgetws.c = -fexceptions -CFLAGS-iofputs.c = -fexceptions -CFLAGS-iofputws.c = -fexceptions -CFLAGS-iofread.c = -fexceptions -CFLAGS-iofsetpos64.c = -fexceptions -CFLAGS-iofsetpos.c = -fexceptions -CFLAGS-ioftell.c = -fexceptions -CFLAGS-iofwrite.c = -fexceptions -CFLAGS-iogetdelim.c = -fexceptions -CFLAGS-iogetline.c = -fexceptions -CFLAGS-iogets.c = -fexceptions -CFLAGS-iogetwline.c = -fexceptions -CFLAGS-ioputs.c = -fexceptions -CFLAGS-ioseekoff.c = -fexceptions -CFLAGS-ioseekpos.c = -fexceptions -CFLAGS-iosetbuffer.c = -fexceptions -CFLAGS-iosetvbuf.c = -fexceptions -CFLAGS-ioungetc.c = -fexceptions -CFLAGS-ioungetwc.c = -fexceptions -CFLAGS-oldfileops.c = -fexceptions -CFLAGS-oldiofclose.c = -fexceptions -CFLAGS-oldiofgetpos64.c = -fexceptions -CFLAGS-oldiofgetpos.c = -fexceptions -CFLAGS-oldiofsetpos64.c = -fexceptions -CFLAGS-oldiofsetpos.c = -fexceptions -CFLAGS-peekc.c = -fexceptions -CFLAGS-putc.c = -fexceptions -CFLAGS-putchar.c = -fexceptions -CFLAGS-putwc.c = -fexceptions -CFLAGS-putwchar.c = -fexceptions -CFLAGS-rewind.c = -fexceptions -CFLAGS-wfileops.c = -fexceptions -CFLAGS-wgenops.c = -fexceptions -CFLAGS-oldiofopen.c = -fexceptions -CFLAGS-iofopen.c = -fexceptions -CFLAGS-iofopen64.c = -fexceptions -CFLAGS-oldtmpfile.c = -fexceptions +CFLAGS-fileops.c += -fexceptions +CFLAGS-fputc.c += -fexceptions +CFLAGS-fputwc.c += -fexceptions +CFLAGS-freopen64.c += -fexceptions +CFLAGS-freopen.c += -fexceptions +CFLAGS-fseek.c += -fexceptions +CFLAGS-fseeko64.c += -fexceptions +CFLAGS-fseeko.c += -fexceptions +CFLAGS-ftello64.c += -fexceptions +CFLAGS-ftello.c += -fexceptions +CFLAGS-fwide.c += -fexceptions +CFLAGS-genops.c += -fexceptions +CFLAGS-getc.c += -fexceptions +CFLAGS-getchar.c += -fexceptions +CFLAGS-getwc.c += -fexceptions +CFLAGS-getwchar.c += -fexceptions +CFLAGS-iofclose.c += -fexceptions +CFLAGS-iofflush.c += -fexceptions +CFLAGS-iofgetpos64.c += -fexceptions +CFLAGS-iofgetpos.c += -fexceptions +CFLAGS-iofgets.c += -fexceptions +CFLAGS-iofgetws.c += -fexceptions +CFLAGS-iofputs.c += -fexceptions +CFLAGS-iofputws.c += -fexceptions +CFLAGS-iofread.c += -fexceptions +CFLAGS-iofsetpos64.c += -fexceptions +CFLAGS-iofsetpos.c += -fexceptions +CFLAGS-ioftell.c += -fexceptions +CFLAGS-iofwrite.c += -fexceptions +CFLAGS-iogetdelim.c += -fexceptions +CFLAGS-iogetline.c += -fexceptions +CFLAGS-iogets.c += -fexceptions +CFLAGS-iogetwline.c += -fexceptions +CFLAGS-ioputs.c += -fexceptions +CFLAGS-ioseekoff.c += -fexceptions +CFLAGS-ioseekpos.c += -fexceptions +CFLAGS-iosetbuffer.c += -fexceptions +CFLAGS-iosetvbuf.c += -fexceptions +CFLAGS-ioungetc.c += -fexceptions +CFLAGS-ioungetwc.c += -fexceptions +CFLAGS-oldfileops.c += -fexceptions +CFLAGS-oldiofclose.c += -fexceptions +CFLAGS-oldiofgetpos64.c += -fexceptions +CFLAGS-oldiofgetpos.c += -fexceptions +CFLAGS-oldiofsetpos64.c += -fexceptions +CFLAGS-oldiofsetpos.c += -fexceptions +CFLAGS-peekc.c += -fexceptions +CFLAGS-putc.c += -fexceptions +CFLAGS-putchar.c += -fexceptions +CFLAGS-putwc.c += -fexceptions +CFLAGS-putwchar.c += -fexceptions +CFLAGS-rewind.c += -fexceptions +CFLAGS-wfileops.c += -fexceptions +CFLAGS-wgenops.c += -fexceptions +CFLAGS-oldiofopen.c += -fexceptions +CFLAGS-iofopen.c += -fexceptions +CFLAGS-iofopen64.c += -fexceptions +CFLAGS-oldtmpfile.c += -fexceptions # XXX Do we need filedoalloc and wfiledoalloc? Others? -CFLAGS-tst_putwc.c = -DOBJPFX=\"$(objpfx)\" +CFLAGS-tst_putwc.c += -DOBJPFX=\"$(objpfx)\" tst_wprintf2-ARGS = "Some Text" test-fmemopen-ENV = MALLOC_TRACE=$(objpfx)test-fmemopen.mtrace tst-fopenloc-ENV = MALLOC_TRACE=$(objpfx)tst-fopenloc.mtrace +tst-bz22415-ENV = MALLOC_TRACE=$(objpfx)tst-bz22415.mtrace generated += test-fmemopen.mtrace test-fmemopen.check generated += tst-fopenloc.mtrace tst-fopenloc.check +generated += tst-bz22415.mtrace tst-bz22415.check aux := fileops genops stdfiles stdio strops @@ -166,7 +174,8 @@ shared-only-routines = oldiofopen oldiofdopen oldiofclose oldfileops \ oldiofsetpos64 ifeq ($(run-built-tests),yes) -tests-special += $(objpfx)test-freopen.out $(objpfx)test-fmemopen-mem.out +tests-special += $(objpfx)test-freopen.out $(objpfx)test-fmemopen-mem.out \ + $(objpfx)tst-bz22415-mem.out ifeq (yes,$(build-shared)) # Run tst-fopenloc-cmp.out and tst-openloc-mem.out only if shared # library is enabled since they depend on tst-fopenloc.out. @@ -202,7 +211,7 @@ endif $(objpfx)test-freopen.out: test-freopen.sh $(objpfx)test-freopen $(SHELL) $< $(common-objpfx) '$(test-program-prefix)' \ - $(common-objpfx)libio/; \ + $(common-objpfx)libio/ > $@; \ $(evaluate-test) $(objpfx)tst-fopenloc-cmp.out: ../iconvdata/testdata/ISO-8859-1..UTF8 \ @@ -217,3 +226,7 @@ $(objpfx)test-fmemopen-mem.out: $(objpfx)test-fmemopen.out $(objpfx)tst-fopenloc-mem.out: $(objpfx)tst-fopenloc.out $(common-objpfx)malloc/mtrace $(objpfx)tst-fopenloc.mtrace > $@; \ $(evaluate-test) + +$(objpfx)tst-bz22415-mem.out: $(objpfx)tst-bz22415.out + $(common-objpfx)malloc/mtrace $(objpfx)tst-bz22415.mtrace > $@; \ + $(evaluate-test) diff --git a/libio/Versions b/libio/Versions index 2a1d6e6c85..acb896afa9 100644 --- a/libio/Versions +++ b/libio/Versions @@ -155,5 +155,12 @@ libc { GLIBC_PRIVATE { # Used by NPTL and librt __libc_fatal; + + # Used by NPTL + _IO_enable_locks; + + __fseeko64; + __ftello64; + __libc_readline_unlocked; } } diff --git a/libio/__fbufsize.c b/libio/__fbufsize.c index 9acbf244bc..e4e53f6abc 100644 --- a/libio/__fbufsize.c +++ b/libio/__fbufsize.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2016 Free Software Foundation, Inc. +/* Copyright (C) 2000-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/libio/__flbf.c b/libio/__flbf.c index dcb7eaa0d1..e2f386bee6 100644 --- a/libio/__flbf.c +++ b/libio/__flbf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2016 Free Software Foundation, Inc. +/* Copyright (C) 2000-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/libio/__fpending.c b/libio/__fpending.c index 0dc6915d18..17039c10bf 100644 --- a/libio/__fpending.c +++ b/libio/__fpending.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2016 Free Software Foundation, Inc. +/* Copyright (C) 2000-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/libio/__fpurge.c b/libio/__fpurge.c index 901890f662..b104448571 100644 --- a/libio/__fpurge.c +++ b/libio/__fpurge.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2016 Free Software Foundation, Inc. +/* Copyright (C) 2000-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/libio/__freadable.c b/libio/__freadable.c index 41a7168bb8..93022c3626 100644 --- a/libio/__freadable.c +++ b/libio/__freadable.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2016 Free Software Foundation, Inc. +/* Copyright (C) 2000-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/libio/__freading.c b/libio/__freading.c index bc573b1caa..c4b9a4dac1 100644 --- a/libio/__freading.c +++ b/libio/__freading.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2016 Free Software Foundation, Inc. +/* Copyright (C) 2000-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/libio/__fsetlocking.c b/libio/__fsetlocking.c index e3122d5589..39f6dba561 100644 --- a/libio/__fsetlocking.c +++ b/libio/__fsetlocking.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2016 Free Software Foundation, Inc. +/* Copyright (C) 2000-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/libio/__fwritable.c b/libio/__fwritable.c index 6ad28a5f6a..dc34ae9801 100644 --- a/libio/__fwritable.c +++ b/libio/__fwritable.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2016 Free Software Foundation, Inc. +/* Copyright (C) 2000-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/libio/__fwriting.c b/libio/__fwriting.c index ec0cfd3119..e84881515f 100644 --- a/libio/__fwriting.c +++ b/libio/__fwriting.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2016 Free Software Foundation, Inc. +/* Copyright (C) 2000-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/libio/bits/stdio-ldbl.h b/libio/bits/stdio-ldbl.h index d19415ffde..99d9bcc233 100644 --- a/libio/bits/stdio-ldbl.h +++ b/libio/bits/stdio-ldbl.h @@ -1,5 +1,5 @@ /* -mlong-double-64 compatibility mode for stdio functions. - Copyright (C) 2006-2016 Free Software Foundation, Inc. + Copyright (C) 2006-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -20,7 +20,6 @@ # error "Never include <bits/stdio-ldbl.h> directly; use <stdio.h> instead." #endif -__BEGIN_NAMESPACE_STD __LDBL_REDIR_DECL (fprintf) __LDBL_REDIR_DECL (printf) __LDBL_REDIR_DECL (sprintf) @@ -38,17 +37,13 @@ __LDBL_REDIR_DECL (fscanf) __LDBL_REDIR_DECL (scanf) __LDBL_REDIR_DECL (sscanf) #endif -__END_NAMESPACE_STD #if defined __USE_ISOC99 || defined __USE_UNIX98 -__BEGIN_NAMESPACE_C99 __LDBL_REDIR_DECL (snprintf) __LDBL_REDIR_DECL (vsnprintf) -__END_NAMESPACE_C99 #endif #ifdef __USE_ISOC99 -__BEGIN_NAMESPACE_C99 # if !defined __USE_GNU && !defined __REDIRECT \ && (defined __STRICT_ANSI__ || defined __USE_XOPEN2K) __LDBL_REDIR1_DECL (vfscanf, __nldbl___isoc99_vfscanf) @@ -59,7 +54,6 @@ __LDBL_REDIR_DECL (vfscanf) __LDBL_REDIR_DECL (vsscanf) __LDBL_REDIR_DECL (vscanf) # endif -__END_NAMESPACE_C99 #endif #ifdef __USE_XOPEN2K8 diff --git a/libio/bits/stdio.h b/libio/bits/stdio.h index df57e7c69b..4ab919031f 100644 --- a/libio/bits/stdio.h +++ b/libio/bits/stdio.h @@ -1,5 +1,5 @@ /* Optimizing macros and inline functions for stdio functions. - Copyright (C) 1998-2016 Free Software Foundation, Inc. + Copyright (C) 1998-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -16,6 +16,9 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ +#ifndef _BITS_STDIO_H +#define _BITS_STDIO_H 1 + #ifndef _STDIO_H # error "Never include <bits/stdio.h> directly; use <stdio.h> instead." #endif @@ -33,7 +36,7 @@ # if !(__USE_FORTIFY_LEVEL > 0 && defined __fortify_function) /* Write formatted output to stdout from argument list ARG. */ __STDIO_INLINE int -vprintf (const char *__restrict __fmt, _G_va_list __arg) +vprintf (const char *__restrict __fmt, __gnuc_va_list __arg) { return vfprintf (stdout, __fmt, __arg); } @@ -43,7 +46,7 @@ vprintf (const char *__restrict __fmt, _G_va_list __arg) __STDIO_INLINE int getchar (void) { - return _IO_getc (stdin); + return getc (stdin); } @@ -52,7 +55,7 @@ getchar (void) __STDIO_INLINE int fgetc_unlocked (FILE *__fp) { - return _IO_getc_unlocked (__fp); + return __getc_unlocked_body (__fp); } # endif /* misc */ @@ -62,14 +65,14 @@ fgetc_unlocked (FILE *__fp) __STDIO_INLINE int getc_unlocked (FILE *__fp) { - return _IO_getc_unlocked (__fp); + return __getc_unlocked_body (__fp); } /* This is defined in POSIX.1:1996. */ __STDIO_INLINE int getchar_unlocked (void) { - return _IO_getc_unlocked (stdin); + return __getc_unlocked_body (stdin); } # endif /* POSIX */ @@ -78,7 +81,7 @@ getchar_unlocked (void) __STDIO_INLINE int putchar (int __c) { - return _IO_putc (__c, stdout); + return putc (__c, stdout); } @@ -87,7 +90,7 @@ putchar (int __c) __STDIO_INLINE int fputc_unlocked (int __c, FILE *__stream) { - return _IO_putc_unlocked (__c, __stream); + return __putc_unlocked_body (__c, __stream); } # endif /* misc */ @@ -97,21 +100,21 @@ fputc_unlocked (int __c, FILE *__stream) __STDIO_INLINE int putc_unlocked (int __c, FILE *__stream) { - return _IO_putc_unlocked (__c, __stream); + return __putc_unlocked_body (__c, __stream); } /* This is defined in POSIX.1:1996. */ __STDIO_INLINE int putchar_unlocked (int __c) { - return _IO_putc_unlocked (__c, stdout); + return __putc_unlocked_body (__c, stdout); } # endif /* POSIX */ # ifdef __USE_GNU /* Like `getdelim', but reads up to a newline. */ -__STDIO_INLINE _IO_ssize_t +__STDIO_INLINE __ssize_t getline (char **__lineptr, size_t *__n, FILE *__stream) { return __getdelim (__lineptr, __n, '\n', __stream); @@ -124,14 +127,14 @@ getline (char **__lineptr, size_t *__n, FILE *__stream) __STDIO_INLINE int __NTH (feof_unlocked (FILE *__stream)) { - return _IO_feof_unlocked (__stream); + return __feof_unlocked_body (__stream); } /* Faster versions when locking is not required. */ __STDIO_INLINE int __NTH (ferror_unlocked (FILE *__stream)) { - return _IO_ferror_unlocked (__stream); + return __ferror_unlocked_body (__stream); } # endif /* misc */ @@ -151,7 +154,7 @@ __NTH (ferror_unlocked (FILE *__stream)) for (__cnt = (size_t) (size) * (size_t) (n); \ __cnt > 0; --__cnt) \ { \ - int __c = _IO_getc_unlocked (__stream); \ + int __c = getc_unlocked (__stream); \ if (__c == EOF) \ break; \ *__ptr++ = __c; \ @@ -174,7 +177,7 @@ __NTH (ferror_unlocked (FILE *__stream)) size_t __cnt; \ for (__cnt = (size_t) (size) * (size_t) (n); \ __cnt > 0; --__cnt) \ - if (_IO_putc_unlocked (*__ptr++, __stream) == EOF) \ + if (putc_unlocked (*__ptr++, __stream) == EOF) \ break; \ ((size_t) (size) * (size_t) (n) - __cnt) \ / (size_t) (size); }) \ @@ -188,3 +191,5 @@ __NTH (ferror_unlocked (FILE *__stream)) /* Define helper macro. */ #undef __STDIO_INLINE + +#endif /* bits/stdio.h. */ diff --git a/libio/bits/stdio2.h b/libio/bits/stdio2.h index fa3be79a66..11651506a6 100644 --- a/libio/bits/stdio2.h +++ b/libio/bits/stdio2.h @@ -1,5 +1,5 @@ /* Checking macros for stdio functions. - Copyright (C) 2004-2016 Free Software Foundation, Inc. + Copyright (C) 2004-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -16,6 +16,9 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ +#ifndef _BITS_STDIO2_H +#define _BITS_STDIO2_H 1 + #ifndef _STDIO_H # error "Never include <bits/stdio2.h> directly; use <stdio.h> instead." #endif @@ -24,7 +27,7 @@ extern int __sprintf_chk (char *__restrict __s, int __flag, size_t __slen, const char *__restrict __format, ...) __THROW; extern int __vsprintf_chk (char *__restrict __s, int __flag, size_t __slen, const char *__restrict __format, - _G_va_list __ap) __THROW; + __gnuc_va_list __ap) __THROW; #ifdef __va_arg_pack __fortify_function int @@ -41,7 +44,7 @@ __NTH (sprintf (char *__restrict __s, const char *__restrict __fmt, ...)) __fortify_function int __NTH (vsprintf (char *__restrict __s, const char *__restrict __fmt, - _G_va_list __ap)) + __gnuc_va_list __ap)) { return __builtin___vsprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, __bos (__s), __fmt, __ap); @@ -54,7 +57,7 @@ extern int __snprintf_chk (char *__restrict __s, size_t __n, int __flag, ...) __THROW; extern int __vsnprintf_chk (char *__restrict __s, size_t __n, int __flag, size_t __slen, const char *__restrict __format, - _G_va_list __ap) __THROW; + __gnuc_va_list __ap) __THROW; # ifdef __va_arg_pack __fortify_function int @@ -72,7 +75,7 @@ __NTH (snprintf (char *__restrict __s, size_t __n, __fortify_function int __NTH (vsnprintf (char *__restrict __s, size_t __n, - const char *__restrict __fmt, _G_va_list __ap)) + const char *__restrict __fmt, __gnuc_va_list __ap)) { return __builtin___vsnprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1, __bos (__s), __fmt, __ap); @@ -86,9 +89,9 @@ extern int __fprintf_chk (FILE *__restrict __stream, int __flag, const char *__restrict __format, ...); extern int __printf_chk (int __flag, const char *__restrict __format, ...); extern int __vfprintf_chk (FILE *__restrict __stream, int __flag, - const char *__restrict __format, _G_va_list __ap); + const char *__restrict __format, __gnuc_va_list __ap); extern int __vprintf_chk (int __flag, const char *__restrict __format, - _G_va_list __ap); + __gnuc_va_list __ap); # ifdef __va_arg_pack __fortify_function int @@ -111,7 +114,7 @@ printf (const char *__restrict __fmt, ...) # endif __fortify_function int -vprintf (const char *__restrict __fmt, _G_va_list __ap) +vprintf (const char *__restrict __fmt, __gnuc_va_list __ap) { #ifdef __USE_EXTERN_INLINES return __vfprintf_chk (stdout, __USE_FORTIFY_LEVEL - 1, __fmt, __ap); @@ -122,7 +125,7 @@ vprintf (const char *__restrict __fmt, _G_va_list __ap) __fortify_function int vfprintf (FILE *__restrict __stream, - const char *__restrict __fmt, _G_va_list __ap) + const char *__restrict __fmt, __gnuc_va_list __ap) { return __vfprintf_chk (__stream, __USE_FORTIFY_LEVEL - 1, __fmt, __ap); } @@ -131,7 +134,7 @@ vfprintf (FILE *__restrict __stream, extern int __dprintf_chk (int __fd, int __flag, const char *__restrict __fmt, ...) __attribute__ ((__format__ (__printf__, 3, 4))); extern int __vdprintf_chk (int __fd, int __flag, - const char *__restrict __fmt, _G_va_list __arg) + const char *__restrict __fmt, __gnuc_va_list __arg) __attribute__ ((__format__ (__printf__, 3, 0))); # ifdef __va_arg_pack @@ -147,7 +150,7 @@ dprintf (int __fd, const char *__restrict __fmt, ...) # endif __fortify_function int -vdprintf (int __fd, const char *__restrict __fmt, _G_va_list __ap) +vdprintf (int __fd, const char *__restrict __fmt, __gnuc_va_list __ap) { return __vdprintf_chk (__fd, __USE_FORTIFY_LEVEL - 1, __fmt, __ap); } @@ -159,7 +162,7 @@ extern int __asprintf_chk (char **__restrict __ptr, int __flag, const char *__restrict __fmt, ...) __THROW __attribute__ ((__format__ (__printf__, 3, 4))) __wur; extern int __vasprintf_chk (char **__restrict __ptr, int __flag, - const char *__restrict __fmt, _G_va_list __arg) + const char *__restrict __fmt, __gnuc_va_list __arg) __THROW __attribute__ ((__format__ (__printf__, 3, 0))) __wur; extern int __obstack_printf_chk (struct obstack *__restrict __obstack, int __flag, const char *__restrict __format, @@ -168,7 +171,7 @@ extern int __obstack_printf_chk (struct obstack *__restrict __obstack, extern int __obstack_vprintf_chk (struct obstack *__restrict __obstack, int __flag, const char *__restrict __format, - _G_va_list __args) + __gnuc_va_list __args) __THROW __attribute__ ((__format__ (__printf__, 3, 0))); # ifdef __va_arg_pack @@ -205,14 +208,14 @@ __NTH (obstack_printf (struct obstack *__restrict __obstack, __fortify_function int __NTH (vasprintf (char **__restrict __ptr, const char *__restrict __fmt, - _G_va_list __ap)) + __gnuc_va_list __ap)) { return __vasprintf_chk (__ptr, __USE_FORTIFY_LEVEL - 1, __fmt, __ap); } __fortify_function int __NTH (obstack_vprintf (struct obstack *__restrict __obstack, - const char *__restrict __fmt, _G_va_list __ap)) + const char *__restrict __fmt, __gnuc_va_list __ap)) { return __obstack_vprintf_chk (__obstack, __USE_FORTIFY_LEVEL - 1, __fmt, __ap); @@ -222,8 +225,7 @@ __NTH (obstack_vprintf (struct obstack *__restrict __obstack, #endif -#if !defined __USE_ISOC11 \ - || (defined __cplusplus && __cplusplus <= 201103L && !defined __USE_GNU) +#if __GLIBC_USE (DEPRECATED_GETS) extern char *__gets_chk (char *__str, size_t) __wur; extern char *__REDIRECT (__gets_warn, (char *__str), gets) __wur __warnattr ("please use fgets or getline instead, gets can't " @@ -369,7 +371,7 @@ fread_unlocked (void *__restrict __ptr, size_t __size, size_t __n, for (; __cnt > 0; --__cnt) { - int __c = _IO_getc_unlocked (__stream); + int __c = getc_unlocked (__stream); if (__c == EOF) break; *__cptr++ = __c; @@ -380,3 +382,5 @@ fread_unlocked (void *__restrict __ptr, size_t __size, size_t __n, return __fread_unlocked_alias (__ptr, __size, __n, __stream); } #endif + +#endif /* bits/stdio2.h. */ diff --git a/libio/bits/types/FILE.h b/libio/bits/types/FILE.h new file mode 100644 index 0000000000..f268263209 --- /dev/null +++ b/libio/bits/types/FILE.h @@ -0,0 +1,9 @@ +#ifndef __FILE_defined +#define __FILE_defined 1 + +struct _IO_FILE; + +/* The opaque type of streams. This is the definition used elsewhere. */ +typedef struct _IO_FILE FILE; + +#endif diff --git a/libio/bits/types/__FILE.h b/libio/bits/types/__FILE.h new file mode 100644 index 0000000000..06dd79bc83 --- /dev/null +++ b/libio/bits/types/__FILE.h @@ -0,0 +1,7 @@ +#ifndef ____FILE_defined +#define ____FILE_defined 1 + +struct _IO_FILE; +typedef struct _IO_FILE __FILE; + +#endif diff --git a/libio/bits/types/__fpos64_t.h b/libio/bits/types/__fpos64_t.h new file mode 100644 index 0000000000..06a6891154 --- /dev/null +++ b/libio/bits/types/__fpos64_t.h @@ -0,0 +1,16 @@ +#ifndef _____fpos64_t_defined +#define _____fpos64_t_defined 1 + +#include <bits/types.h> +#include <bits/types/__mbstate_t.h> + +/* The tag name of this struct is _G_fpos64_t to preserve historic + C++ mangled names for functions taking fpos_t and/or fpos64_t + arguments. That name should not be used in new code. */ +typedef struct _G_fpos64_t +{ + __off64_t __pos; + __mbstate_t __state; +} __fpos64_t; + +#endif diff --git a/libio/bits/types/__fpos_t.h b/libio/bits/types/__fpos_t.h new file mode 100644 index 0000000000..bb04576651 --- /dev/null +++ b/libio/bits/types/__fpos_t.h @@ -0,0 +1,16 @@ +#ifndef _____fpos_t_defined +#define _____fpos_t_defined 1 + +#include <bits/types.h> +#include <bits/types/__mbstate_t.h> + +/* The tag name of this struct is _G_fpos_t to preserve historic + C++ mangled names for functions taking fpos_t arguments. + That name should not be used in new code. */ +typedef struct _G_fpos_t +{ + __off_t __pos; + __mbstate_t __state; +} __fpos_t; + +#endif diff --git a/libio/bits/types/cookie_io_functions_t.h b/libio/bits/types/cookie_io_functions_t.h new file mode 100644 index 0000000000..a6d9d39a47 --- /dev/null +++ b/libio/bits/types/cookie_io_functions_t.h @@ -0,0 +1,63 @@ +/* Copyright (C) 1991-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef __cookie_io_functions_t_defined +#define __cookie_io_functions_t_defined 1 + +#include <bits/types.h> + +/* Functions to do I/O and file management for a stream. */ + +/* Read NBYTES bytes from COOKIE into a buffer pointed to by BUF. + Return number of bytes read. */ +typedef __ssize_t cookie_read_function_t (void *__cookie, char *__buf, + size_t __nbytes); + +/* Write NBYTES bytes pointed to by BUF to COOKIE. Write all NBYTES bytes + unless there is an error. Return number of bytes written. If + there is an error, return 0 and do not write anything. If the file + has been opened for append (__mode.__append set), then set the file + pointer to the end of the file and then do the write; if not, just + write at the current file pointer. */ +typedef __ssize_t cookie_write_function_t (void *__cookie, const char *__buf, + size_t __nbytes); + +/* Move COOKIE's file position to *POS bytes from the + beginning of the file (if W is SEEK_SET), + the current position (if W is SEEK_CUR), + or the end of the file (if W is SEEK_END). + Set *POS to the new file position. + Returns zero if successful, nonzero if not. */ +typedef int cookie_seek_function_t (void *__cookie, __off64_t *__pos, int __w); + +/* Close COOKIE. */ +typedef int cookie_close_function_t (void *__cookie); + +/* The structure with the cookie function pointers. + The tag name of this struct is _IO_cookie_io_functions_t to + preserve historic C++ mangled names for functions taking + cookie_io_functions_t arguments. That name should not be used in + new code. */ +typedef struct _IO_cookie_io_functions_t +{ + cookie_read_function_t *read; /* Read bytes. */ + cookie_write_function_t *write; /* Write bytes. */ + cookie_seek_function_t *seek; /* Seek/tell file position. */ + cookie_close_function_t *close; /* Close file. */ +} cookie_io_functions_t; + +#endif diff --git a/libio/bits/types/struct_FILE.h b/libio/bits/types/struct_FILE.h new file mode 100644 index 0000000000..359f949453 --- /dev/null +++ b/libio/bits/types/struct_FILE.h @@ -0,0 +1,120 @@ +/* Copyright (C) 1991-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef __struct_FILE_defined +#define __struct_FILE_defined 1 + +/* Caution: The contents of this file are not part of the official + stdio.h API. However, much of it is part of the official *binary* + interface, and therefore cannot be changed. */ + +#if defined _IO_USE_OLD_IO_FILE && !defined _LIBC +# error "_IO_USE_OLD_IO_FILE should only be defined when building libc itself" +#endif + +#if defined _IO_lock_t_defined && !defined _LIBC +# error "_IO_lock_t_defined should only be defined when building libc itself" +#endif + +#include <bits/types.h> + +struct _IO_FILE; +struct _IO_marker; +struct _IO_codecvt; +struct _IO_wide_data; + +/* During the build of glibc itself, _IO_lock_t will already have been + defined by internal headers. */ +#ifndef _IO_lock_t_defined +typedef void _IO_lock_t; +#endif + +/* The tag name of this struct is _IO_FILE to preserve historic + C++ mangled names for functions taking FILE* arguments. + That name should not be used in new code. */ +struct _IO_FILE +{ + int _flags; /* High-order word is _IO_MAGIC; rest is flags. */ + + /* The following pointers correspond to the C++ streambuf protocol. */ + char *_IO_read_ptr; /* Current read pointer */ + char *_IO_read_end; /* End of get area. */ + char *_IO_read_base; /* Start of putback+get area. */ + char *_IO_write_base; /* Start of put area. */ + char *_IO_write_ptr; /* Current put pointer. */ + char *_IO_write_end; /* End of put area. */ + char *_IO_buf_base; /* Start of reserve area. */ + char *_IO_buf_end; /* End of reserve area. */ + + /* The following fields are used to support backing up and undo. */ + char *_IO_save_base; /* Pointer to start of non-current get area. */ + char *_IO_backup_base; /* Pointer to first valid character of backup area */ + char *_IO_save_end; /* Pointer to end of non-current get area. */ + + struct _IO_marker *_markers; + + struct _IO_FILE *_chain; + + int _fileno; + int _flags2; + __off_t _old_offset; /* This used to be _offset but it's too small. */ + + /* 1+column number of pbase(); 0 is unknown. */ + unsigned short _cur_column; + signed char _vtable_offset; + char _shortbuf[1]; + + _IO_lock_t *_lock; +#ifdef _IO_USE_OLD_IO_FILE +}; + +struct _IO_FILE_complete +{ + struct _IO_FILE _file; +#endif + __off64_t _offset; + /* Wide character stream stuff. */ + struct _IO_codecvt *_codecvt; + struct _IO_wide_data *_wide_data; + struct _IO_FILE *_freeres_list; + void *_freeres_buf; + size_t __pad5; + int _mode; + /* Make sure we don't get into trouble again. */ + char _unused2[15 * sizeof (int) - 4 * sizeof (void *) - sizeof (size_t)]; +}; + +/* These macros are used by bits/stdio.h and internal headers. */ +#define __getc_unlocked_body(_fp) \ + (__glibc_unlikely ((_fp)->_IO_read_ptr >= (_fp)->_IO_read_end) \ + ? __uflow (_fp) : *(unsigned char *) (_fp)->_IO_read_ptr++) + +#define __putc_unlocked_body(_ch, _fp) \ + (__glibc_unlikely ((_fp)->_IO_write_ptr >= (_fp)->_IO_write_end) \ + ? __overflow (_fp, (unsigned char) (_ch)) \ + : (unsigned char) (*(_fp)->_IO_write_ptr++ = (_ch))) + +#define _IO_EOF_SEEN 0x0010 +#define __feof_unlocked_body(_fp) (((_fp)->_flags & _IO_EOF_SEEN) != 0) + +#define _IO_ERR_SEEN 0x0020 +#define __ferror_unlocked_body(_fp) (((_fp)->_flags & _IO_ERR_SEEN) != 0) + +#define _IO_USER_LOCK 0x8000 +/* Many more flag bits are defined internally. */ + +#endif diff --git a/libio/bug-memstream1.c b/libio/bug-memstream1.c index 8af36fee2d..d1ecc79564 100644 --- a/libio/bug-memstream1.c +++ b/libio/bug-memstream1.c @@ -1,5 +1,6 @@ #include <stdio.h> #include <string.h> +#include <stdlib.h> static int diff --git a/libio/bug-ungetc4.c b/libio/bug-ungetc4.c index 2492734f79..9fbad11f26 100644 --- a/libio/bug-ungetc4.c +++ b/libio/bug-ungetc4.c @@ -1,5 +1,5 @@ /* Test program for ungetc/fseekpos interaction. - Copyright (C) 2004-2016 Free Software Foundation, Inc. + Copyright (C) 2004-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Jakub Jelinek <jakub@redhat.com>, 2004. diff --git a/libio/bug-wmemstream1.c b/libio/bug-wmemstream1.c index 22d67f71e9..709a3c6d66 100644 --- a/libio/bug-wmemstream1.c +++ b/libio/bug-wmemstream1.c @@ -1,4 +1,5 @@ #include <stdio.h> +#include <stdlib.h> #include <string.h> #include <wchar.h> diff --git a/libio/clearerr.c b/libio/clearerr.c index c0fad6d330..77ac552fac 100644 --- a/libio/clearerr.c +++ b/libio/clearerr.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1995-2016 Free Software Foundation, Inc. +/* Copyright (C) 1995-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -27,6 +27,6 @@ clearerr (FILE *fp) _IO_funlockfile (fp); } -#if defined weak_alias && !defined _IO_MTSAFE_IO +#ifndef _IO_MTSAFE_IO weak_alias (clearerr, clearerr_unlocked) #endif diff --git a/libio/clearerr_u.c b/libio/clearerr_u.c index 624ff7a3dc..0b696b97f7 100644 --- a/libio/clearerr_u.c +++ b/libio/clearerr_u.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1995-2016 Free Software Foundation, Inc. +/* Copyright (C) 1995-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/libio/fcloseall.c b/libio/fcloseall.c index 1eff772605..4a3fd94cf7 100644 --- a/libio/fcloseall.c +++ b/libio/fcloseall.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -34,6 +34,4 @@ __fcloseall (void) return _IO_cleanup (); } -#ifdef weak_alias weak_alias (__fcloseall, fcloseall) -#endif diff --git a/libio/feof.c b/libio/feof.c index 8de54e6495..cf9b7eee42 100644 --- a/libio/feof.c +++ b/libio/feof.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -28,21 +28,21 @@ #include "stdio.h" int -_IO_feof (_IO_FILE *fp) +_IO_feof (FILE *fp) { int result; CHECK_FILE (fp, EOF); + if (!_IO_need_lock (fp)) + return _IO_feof_unlocked (fp); _IO_flockfile (fp); result = _IO_feof_unlocked (fp); _IO_funlockfile (fp); return result; } -#ifdef weak_alias weak_alias (_IO_feof, feof) #ifndef _IO_MTSAFE_IO #undef feof_unlocked weak_alias (_IO_feof, feof_unlocked) #endif -#endif diff --git a/libio/feof_u.c b/libio/feof_u.c index 9d656e9cf0..3033efb064 100644 --- a/libio/feof_u.c +++ b/libio/feof_u.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -30,8 +30,10 @@ #undef feof_unlocked int -feof_unlocked (_IO_FILE *fp) +__feof_unlocked (FILE *fp) { CHECK_FILE (fp, EOF); return _IO_feof_unlocked (fp); } +weak_alias (__feof_unlocked, feof_unlocked) +libc_hidden_weak (feof_unlocked) diff --git a/libio/ferror.c b/libio/ferror.c index daf02f85f4..4b5122b6af 100644 --- a/libio/ferror.c +++ b/libio/ferror.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -28,21 +28,21 @@ #include "stdio.h" int -_IO_ferror (_IO_FILE *fp) +_IO_ferror (FILE *fp) { int result; CHECK_FILE (fp, EOF); + if (!_IO_need_lock (fp)) + return _IO_ferror_unlocked (fp); _IO_flockfile (fp); result = _IO_ferror_unlocked (fp); _IO_funlockfile (fp); return result; } -#ifdef weak_alias weak_alias (_IO_ferror, ferror) #ifndef _IO_MTSAFE_IO #undef ferror_unlocked weak_alias (_IO_ferror, ferror_unlocked) #endif -#endif diff --git a/libio/ferror_u.c b/libio/ferror_u.c index 7939116c5b..fddf505438 100644 --- a/libio/ferror_u.c +++ b/libio/ferror_u.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -30,8 +30,10 @@ #undef ferror_unlocked int -ferror_unlocked (_IO_FILE *fp) +__ferror_unlocked (FILE *fp) { CHECK_FILE (fp, EOF); return _IO_ferror_unlocked (fp); } +weak_alias (__ferror_unlocked, ferror_unlocked) +libc_hidden_weak (ferror_unlocked) diff --git a/libio/filedoalloc.c b/libio/filedoalloc.c index b51e910131..190c009172 100644 --- a/libio/filedoalloc.c +++ b/libio/filedoalloc.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -55,58 +55,32 @@ /* Modified for GNU iostream by Per Bothner 1991, 1992. */ -#ifndef _POSIX_SOURCE -# define _POSIX_SOURCE -#endif #include "libioP.h" -#include <sys/types.h> +#include <device-nrs.h> #include <sys/stat.h> #include <stdlib.h> #include <unistd.h> -#ifdef _LIBC -# undef isatty -# define isatty(Fd) __isatty (Fd) - -# include <device-nrs.h> -#endif - - +/* Return the result of isatty, without changing errno. */ static int local_isatty (int fd) { int save_errno = errno; - int res = isatty (fd); + int res = __isatty (fd); __set_errno (save_errno); return res; } - -/* - * Allocate a file buffer, or switch to unbuffered I/O. - * Per the ANSI C standard, ALL tty devices default to line buffered. - * - * As a side effect, we set __SOPT or __SNPT (en/dis-able fseek - * optimisation) right after the _fstat() that finds the buffer size. - */ - +/* Allocate a file buffer, or switch to unbuffered I/O. Streams for + TTY devices default to line buffered. */ int -_IO_file_doallocate (_IO_FILE *fp) +_IO_file_doallocate (FILE *fp) { - _IO_size_t size; + size_t size; char *p; struct stat64 st; -#ifndef _LIBC - /* If _IO_cleanup_registration_needed is non-zero, we should call the - function it points to. This is to make sure _IO_cleanup gets called - on exit. We call it from _IO_file_doallocate, since that is likely - to get called by any program that does buffered I/O. */ - if (__glibc_unlikely (_IO_cleanup_registration_needed != NULL)) - (*_IO_cleanup_registration_needed) (); -#endif - - size = _IO_BUFSIZ; + size = BUFSIZ; if (fp->_fileno >= 0 && __builtin_expect (_IO_SYSSTAT (fp, &st), 0) >= 0) { if (S_ISCHR (st.st_mode)) @@ -119,8 +93,8 @@ _IO_file_doallocate (_IO_FILE *fp) local_isatty (fp->_fileno)) fp->_flags |= _IO_LINE_BUF; } -#if _IO_HAVE_ST_BLKSIZE - if (st.st_blksize > 0) +#if defined _STATBUF_ST_BLKSIZE + if (st.st_blksize > 0 && st.st_blksize < BUFSIZ) size = st.st_blksize; #endif } diff --git a/libio/fileno.c b/libio/fileno.c index 4a8e91b4b6..f49c588a96 100644 --- a/libio/fileno.c +++ b/libio/fileno.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -28,7 +28,7 @@ #include <stdio.h> int -__fileno (_IO_FILE *fp) +__fileno (FILE *fp) { CHECK_FILE (fp, EOF); @@ -44,10 +44,8 @@ libc_hidden_def (__fileno) weak_alias (__fileno, fileno) libc_hidden_weak (fileno) -#ifdef weak_alias /* The fileno implementation for libio does not require locking because it only accesses once a single variable and this is already atomic (at least at thread level). Therefore we don't test _IO_MTSAFE_IO here. */ weak_alias (__fileno, fileno_unlocked) -#endif diff --git a/libio/fileops.c b/libio/fileops.c index 8e83b1cd7b..c9c5cbcc3c 100644 --- a/libio/fileops.c +++ b/libio/fileops.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Written by Per Bothner <bothner@cygnus.com>. @@ -26,9 +26,6 @@ in files containing the exception. */ -#ifndef _POSIX_SOURCE -# define _POSIX_SOURCE -#endif #include "libioP.h" #include <assert.h> #include <fcntl.h> @@ -40,48 +37,14 @@ #include <errno.h> #include <unistd.h> #include <stdlib.h> -#if _LIBC -# include "../wcsmbs/wcsmbsload.h" -# include "../iconv/gconv_charset.h" -# include "../iconv/gconv_int.h" -# include <shlib-compat.h> -# include <not-cancel.h> -# include <kernel-features.h> -#endif -#ifndef errno -extern int errno; -#endif -#ifndef __set_errno -# define __set_errno(Val) errno = (Val) -#endif +#include "../wcsmbs/wcsmbsload.h" +#include "../iconv/gconv_charset.h" +#include "../iconv/gconv_int.h" +#include <shlib-compat.h> +#include <not-cancel.h> +#include <kernel-features.h> - -#ifdef _LIBC -# define open(Name, Flags, Prot) __open (Name, Flags, Prot) -# define lseek(FD, Offset, Whence) __lseek (FD, Offset, Whence) -# define read(FD, Buf, NBytes) __read (FD, Buf, NBytes) -# define write(FD, Buf, NBytes) __write (FD, Buf, NBytes) -#else -# define _IO_new_do_write _IO_do_write -# define _IO_new_file_attach _IO_file_attach -# define _IO_new_file_close_it _IO_file_close_it -# define _IO_new_file_finish _IO_file_finish -# define _IO_new_file_fopen _IO_file_fopen -# define _IO_new_file_init _IO_file_init -# define _IO_new_file_setbuf _IO_file_setbuf -# define _IO_new_file_sync _IO_file_sync -# define _IO_new_file_overflow _IO_file_overflow -# define _IO_new_file_seekoff _IO_file_seekoff -# define _IO_new_file_underflow _IO_file_underflow -# define _IO_new_file_write _IO_file_write -# define _IO_new_file_xsputn _IO_file_xsputn -#endif - - -#ifdef _LIBC extern struct __gconv_trans_data __libio_translit attribute_hidden; -#endif - /* An fstream can be in at most one of put mode, get mode, or putback mode. Putback mode is a variant of get mode. @@ -140,21 +103,29 @@ extern struct __gconv_trans_data __libio_translit attribute_hidden; void -_IO_new_file_init (struct _IO_FILE_plus *fp) +_IO_new_file_init_internal (struct _IO_FILE_plus *fp) { /* POSIX.1 allows another file handle to be used to change the position of our file descriptor. Hence we actually don't know the actual position before we do the first fseek (and until a following fflush). */ fp->file._offset = _IO_pos_BAD; - fp->file._IO_file_flags |= CLOSED_FILEBUF_FLAGS; + fp->file._flags |= CLOSED_FILEBUF_FLAGS; _IO_link_in (fp); fp->file._fileno = -1; } -libc_hidden_ver (_IO_new_file_init, _IO_file_init) + +/* External version of _IO_new_file_init_internal which switches off + vtable validation. */ +void +_IO_new_file_init (struct _IO_FILE_plus *fp) +{ + IO_set_accept_foreign_vtables (&_IO_vtable_check); + _IO_new_file_init_internal (fp); +} int -_IO_new_file_close_it (_IO_FILE *fp) +_IO_new_file_close_it (FILE *fp) { int write_status; if (!_IO_file_is_open (fp)) @@ -172,7 +143,6 @@ _IO_new_file_close_it (_IO_FILE *fp) ? _IO_SYSCLOSE (fp) : 0); /* Free buffer. */ -#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T if (fp->_mode > 0) { if (_IO_have_wbackup (fp)) @@ -181,7 +151,6 @@ _IO_new_file_close_it (_IO_FILE *fp) _IO_wsetg (fp, NULL, NULL, NULL); _IO_wsetp (fp, NULL, NULL); } -#endif _IO_setb (fp, NULL, NULL, 0); _IO_setg (fp, NULL, NULL, NULL); _IO_setp (fp, NULL, NULL); @@ -196,7 +165,7 @@ _IO_new_file_close_it (_IO_FILE *fp) libc_hidden_ver (_IO_new_file_close_it, _IO_file_close_it) void -_IO_new_file_finish (_IO_FILE *fp, int dummy) +_IO_new_file_finish (FILE *fp, int dummy) { if (_IO_file_is_open (fp)) { @@ -208,20 +177,16 @@ _IO_new_file_finish (_IO_FILE *fp, int dummy) } libc_hidden_ver (_IO_new_file_finish, _IO_file_finish) -_IO_FILE * -_IO_file_open (_IO_FILE *fp, const char *filename, int posix_mode, int prot, +FILE * +_IO_file_open (FILE *fp, const char *filename, int posix_mode, int prot, int read_write, int is32not64) { int fdesc; -#ifdef _LIBC if (__glibc_unlikely (fp->_flags2 & _IO_FLAGS2_NOTCANCEL)) - fdesc = open_not_cancel (filename, + fdesc = __open_nocancel (filename, posix_mode | (is32not64 ? 0 : O_LARGEFILE), prot); else - fdesc = open (filename, posix_mode | (is32not64 ? 0 : O_LARGEFILE), prot); -#else - fdesc = open (filename, posix_mode, prot); -#endif + fdesc = __open (filename, posix_mode | (is32not64 ? 0 : O_LARGEFILE), prot); if (fdesc < 0) return NULL; fp->_fileno = fdesc; @@ -231,10 +196,10 @@ _IO_file_open (_IO_FILE *fp, const char *filename, int posix_mode, int prot, if ((read_write & (_IO_IS_APPENDING | _IO_NO_READS)) == (_IO_IS_APPENDING | _IO_NO_READS)) { - _IO_off64_t new_pos = _IO_SYSSEEK (fp, 0, _IO_seek_end); + off64_t new_pos = _IO_SYSSEEK (fp, 0, _IO_seek_end); if (new_pos == _IO_pos_BAD && errno != ESPIPE) { - close_not_cancel (fdesc); + __close_nocancel (fdesc); return NULL; } } @@ -243,19 +208,17 @@ _IO_file_open (_IO_FILE *fp, const char *filename, int posix_mode, int prot, } libc_hidden_def (_IO_file_open) -_IO_FILE * -_IO_new_file_fopen (_IO_FILE *fp, const char *filename, const char *mode, +FILE * +_IO_new_file_fopen (FILE *fp, const char *filename, const char *mode, int is32not64) { int oflags = 0, omode; int read_write; int oprot = 0666; int i; - _IO_FILE *result; -#ifdef _LIBC + FILE *result; const char *cs; const char *last_recognized; -#endif if (_IO_file_is_open (fp)) return 0; @@ -279,9 +242,7 @@ _IO_new_file_fopen (_IO_FILE *fp, const char *filename, const char *mode, __set_errno (EINVAL); return NULL; } -#ifdef _LIBC last_recognized = mode; -#endif for (i = 1; i < 7; ++i) { switch (*++mode) @@ -291,20 +252,14 @@ _IO_new_file_fopen (_IO_FILE *fp, const char *filename, const char *mode, case '+': omode = O_RDWR; read_write &= _IO_IS_APPENDING; -#ifdef _LIBC last_recognized = mode; -#endif continue; case 'x': oflags |= O_EXCL; -#ifdef _LIBC last_recognized = mode; -#endif continue; case 'b': -#ifdef _LIBC last_recognized = mode; -#endif continue; case 'm': fp->_flags2 |= _IO_FLAGS2_MMAP; @@ -313,9 +268,7 @@ _IO_new_file_fopen (_IO_FILE *fp, const char *filename, const char *mode, fp->_flags2 |= _IO_FLAGS2_NOTCANCEL; continue; case 'e': -#ifdef O_CLOEXEC oflags |= O_CLOEXEC; -#endif fp->_flags2 |= _IO_FLAGS2_CLOEXEC; continue; default: @@ -330,20 +283,6 @@ _IO_new_file_fopen (_IO_FILE *fp, const char *filename, const char *mode, if (result != NULL) { -#ifndef __ASSUME_O_CLOEXEC - if ((fp->_flags2 & _IO_FLAGS2_CLOEXEC) != 0 && __have_o_cloexec <= 0) - { - int fd = _IO_fileno (fp); - if (__have_o_cloexec == 0) - { - int flags = __fcntl (fd, F_GETFD); - __have_o_cloexec = (flags & FD_CLOEXEC) == 0 ? -1 : 1; - } - if (__have_o_cloexec < 0) - __fcntl (fd, F_SETFD, FD_CLOEXEC); - } -#endif - /* Test whether the mode string specifies the conversion. */ cs = strstr (last_recognized + 1, ",ccs="); if (cs != NULL) @@ -425,8 +364,8 @@ _IO_new_file_fopen (_IO_FILE *fp, const char *filename, const char *mode, } libc_hidden_ver (_IO_new_file_fopen, _IO_file_fopen) -_IO_FILE * -_IO_new_file_attach (_IO_FILE *fp, int fd) +FILE * +_IO_new_file_attach (FILE *fp, int fd) { if (_IO_file_is_open (fp)) return NULL; @@ -437,7 +376,7 @@ _IO_new_file_attach (_IO_FILE *fp, int fd) /* We have to do that since that may be junk. */ fp->_offset = _IO_pos_BAD; int save_errno = errno; - if (_IO_SEEKOFF (fp, (_IO_off64_t)0, _IO_seek_cur, _IOS_INPUT|_IOS_OUTPUT) + if (_IO_SEEKOFF (fp, (off64_t)0, _IO_seek_cur, _IOS_INPUT|_IOS_OUTPUT) == _IO_pos_BAD && errno != ESPIPE) return NULL; __set_errno (save_errno); @@ -445,8 +384,8 @@ _IO_new_file_attach (_IO_FILE *fp, int fd) } libc_hidden_ver (_IO_new_file_attach, _IO_file_attach) -_IO_FILE * -_IO_new_file_setbuf (_IO_FILE *fp, char *p, _IO_ssize_t len) +FILE * +_IO_new_file_setbuf (FILE *fp, char *p, ssize_t len) { if (_IO_default_setbuf (fp, p, len) == NULL) return NULL; @@ -460,10 +399,10 @@ _IO_new_file_setbuf (_IO_FILE *fp, char *p, _IO_ssize_t len) libc_hidden_ver (_IO_new_file_setbuf, _IO_file_setbuf) -_IO_FILE * -_IO_file_setbuf_mmap (_IO_FILE *fp, char *p, _IO_ssize_t len) +FILE * +_IO_file_setbuf_mmap (FILE *fp, char *p, ssize_t len) { - _IO_FILE *result; + FILE *result; /* Change the function table. */ _IO_JUMPS_FILE_plus (fp) = &_IO_file_jumps; @@ -482,24 +421,23 @@ _IO_file_setbuf_mmap (_IO_FILE *fp, char *p, _IO_ssize_t len) return result; } -static _IO_size_t new_do_write (_IO_FILE *, const char *, _IO_size_t); +static size_t new_do_write (FILE *, const char *, size_t); /* Write TO_DO bytes from DATA to FP. Then mark FP as having empty buffers. */ int -_IO_new_do_write (_IO_FILE *fp, const char *data, _IO_size_t to_do) +_IO_new_do_write (FILE *fp, const char *data, size_t to_do) { return (to_do == 0 - || (_IO_size_t) new_do_write (fp, data, to_do) == to_do) ? 0 : EOF; + || (size_t) new_do_write (fp, data, to_do) == to_do) ? 0 : EOF; } libc_hidden_ver (_IO_new_do_write, _IO_do_write) -static -_IO_size_t -new_do_write (_IO_FILE *fp, const char *data, _IO_size_t to_do) +static size_t +new_do_write (FILE *fp, const char *data, size_t to_do) { - _IO_size_t count; + size_t count; if (fp->_flags & _IO_IS_APPENDING) /* On a system without a proper O_APPEND implementation, you would need to sys_seek(0, SEEK_END) here, but is @@ -509,7 +447,7 @@ new_do_write (_IO_FILE *fp, const char *data, _IO_size_t to_do) fp->_offset = _IO_pos_BAD; else if (fp->_IO_read_end != fp->_IO_write_base) { - _IO_off64_t new_pos + off64_t new_pos = _IO_SYSSEEK (fp, fp->_IO_write_base - fp->_IO_read_end, 1); if (new_pos == _IO_pos_BAD) return 0; @@ -527,14 +465,13 @@ new_do_write (_IO_FILE *fp, const char *data, _IO_size_t to_do) } int -_IO_new_file_underflow (_IO_FILE *fp) +_IO_new_file_underflow (FILE *fp) { - _IO_ssize_t count; -#if 0 - /* SysV does not make this test; take it out for compatibility */ + ssize_t count; + + /* C99 requires EOF to be "sticky". */ if (fp->_flags & _IO_EOF_SEEN) - return (EOF); -#endif + return EOF; if (fp->_flags & _IO_NO_READS) { @@ -556,13 +493,9 @@ _IO_new_file_underflow (_IO_FILE *fp) _IO_doallocbuf (fp); } - /* Flush all line buffered files before reading. */ /* FIXME This can/should be moved to genops ?? */ if (fp->_flags & (_IO_LINE_BUF|_IO_UNBUFFERED)) { -#if 0 - _IO_flush_all_linebuffered (); -#else /* We used to flush all line-buffered stream. This really isn't required by any standard. My recollection is that traditional Unix systems did this for stdout. stderr better @@ -575,7 +508,6 @@ _IO_new_file_underflow (_IO_FILE *fp) _IO_OVERFLOW (_IO_stdout, EOF); _IO_release_lock (_IO_stdout); -#endif } _IO_switch_to_get_mode (fp); @@ -618,7 +550,7 @@ libc_hidden_ver (_IO_new_file_underflow, _IO_file_underflow) If the file is no longer eligible for mmap, its jump tables are reset to the vanilla ones and we return nonzero. */ static int -mmap_remap_check (_IO_FILE *fp) +mmap_remap_check (FILE *fp) { struct stat64 st; @@ -643,7 +575,7 @@ mmap_remap_check (_IO_FILE *fp) { /* The file added some pages. We need to remap it. */ void *p; -#ifdef _G_HAVE_MREMAP +#if _G_HAVE_MREMAP p = __mremap (fp->_IO_buf_base, ROUNDED (fp->_IO_buf_end - fp->_IO_buf_base), ROUNDED (st.st_size), MREMAP_MAYMOVE); @@ -714,7 +646,7 @@ mmap_remap_check (_IO_FILE *fp) /* Special callback replacing the underflow callbacks if we mmap the file. */ int -_IO_file_underflow_mmap (_IO_FILE *fp) +_IO_file_underflow_mmap (FILE *fp) { if (fp->_IO_read_ptr < fp->_IO_read_end) return *(unsigned char *) fp->_IO_read_ptr; @@ -731,7 +663,7 @@ _IO_file_underflow_mmap (_IO_FILE *fp) } static void -decide_maybe_mmap (_IO_FILE *fp) +decide_maybe_mmap (FILE *fp) { /* We use the file in read-only mode. This could mean we can mmap the file and use it without any copying. But not all @@ -793,7 +725,7 @@ decide_maybe_mmap (_IO_FILE *fp) } int -_IO_file_underflow_maybe_mmap (_IO_FILE *fp) +_IO_file_underflow_maybe_mmap (FILE *fp) { /* This is the first read attempt. Choose mmap or vanilla operations and then punt to the chosen underflow routine. */ @@ -803,7 +735,7 @@ _IO_file_underflow_maybe_mmap (_IO_FILE *fp) int -_IO_new_file_overflow (_IO_FILE *f, int ch) +_IO_new_file_overflow (FILE *f, int ch) { if (f->_flags & _IO_NO_WRITES) /* SET ERROR */ { @@ -864,9 +796,9 @@ _IO_new_file_overflow (_IO_FILE *f, int ch) libc_hidden_ver (_IO_new_file_overflow, _IO_file_overflow) int -_IO_new_file_sync (_IO_FILE *fp) +_IO_new_file_sync (FILE *fp) { - _IO_ssize_t delta; + ssize_t delta; int retval = 0; /* char* ptr = cur_ptr(); */ @@ -875,17 +807,11 @@ _IO_new_file_sync (_IO_FILE *fp) delta = fp->_IO_read_ptr - fp->_IO_read_end; if (delta != 0) { -#ifdef TODO - if (_IO_in_backup (fp)) - delta -= eGptr () - Gbase (); -#endif - _IO_off64_t new_pos = _IO_SYSSEEK (fp, delta, 1); - if (new_pos != (_IO_off64_t) EOF) + off64_t new_pos = _IO_SYSSEEK (fp, delta, 1); + if (new_pos != (off64_t) EOF) fp->_IO_read_end = fp->_IO_read_ptr; -#ifdef ESPIPE else if (errno == ESPIPE) ; /* Ignore error from unseekable devices. */ -#endif else retval = EOF; } @@ -898,14 +824,10 @@ _IO_new_file_sync (_IO_FILE *fp) libc_hidden_ver (_IO_new_file_sync, _IO_file_sync) static int -_IO_file_sync_mmap (_IO_FILE *fp) +_IO_file_sync_mmap (FILE *fp) { if (fp->_IO_read_ptr != fp->_IO_read_end) { -#ifdef TODO - if (_IO_in_backup (fp)) - delta -= eGptr () - Gbase (); -#endif if (__lseek64 (fp->_fileno, fp->_IO_read_ptr - fp->_IO_buf_base, SEEK_SET) != fp->_IO_read_ptr - fp->_IO_buf_base) @@ -922,10 +844,10 @@ _IO_file_sync_mmap (_IO_FILE *fp) /* ftell{,o} implementation. The only time we modify the state of the stream is when we have unflushed writes. In that case we seek to the end and record that offset in the stream object. */ -static _IO_off64_t -do_ftell (_IO_FILE *fp) +static off64_t +do_ftell (FILE *fp) { - _IO_off64_t result, offset = 0; + off64_t result, offset = 0; /* No point looking at unflushed data if we haven't allocated buffers yet. */ @@ -981,11 +903,11 @@ do_ftell (_IO_FILE *fp) return result; } -_IO_off64_t -_IO_new_file_seekoff (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode) +off64_t +_IO_new_file_seekoff (FILE *fp, off64_t offset, int dir, int mode) { - _IO_off64_t result; - _IO_off64_t delta, new_offset; + off64_t result; + off64_t delta, new_offset; long count; /* Short-circuit into a separate function. We don't want to mix any @@ -1057,14 +979,17 @@ _IO_new_file_seekoff (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode) goto dumb; } } + + _IO_free_backup_area (fp); + /* At this point, dir==_IO_seek_set. */ /* If destination is within current buffer, optimize: */ if (fp->_offset != _IO_pos_BAD && fp->_IO_read_base != NULL && !_IO_in_backup (fp)) { - _IO_off64_t start_offset = (fp->_offset - - (fp->_IO_read_end - fp->_IO_buf_base)); + off64_t start_offset = (fp->_offset + - (fp->_IO_read_end - fp->_IO_buf_base)); if (offset >= start_offset && offset < fp->_offset) { _IO_setg (fp, fp->_IO_buf_base, @@ -1137,10 +1062,10 @@ resync: } libc_hidden_ver (_IO_new_file_seekoff, _IO_file_seekoff) -_IO_off64_t -_IO_file_seekoff_mmap (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode) +off64_t +_IO_file_seekoff_mmap (FILE *fp, off64_t offset, int dir, int mode) { - _IO_off64_t result; + off64_t result; /* If we are only interested in the current position, calculate it and return right now. This calculation does the right thing when we are @@ -1192,15 +1117,15 @@ _IO_file_seekoff_mmap (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode) return offset; } -static _IO_off64_t -_IO_file_seekoff_maybe_mmap (_IO_FILE *fp, _IO_off64_t offset, int dir, +static off64_t +_IO_file_seekoff_maybe_mmap (FILE *fp, off64_t offset, int dir, int mode) { /* We only get here when we haven't tried to read anything yet. So there is nothing more useful for us to do here than just the underlying lseek call. */ - _IO_off64_t result = _IO_SYSSEEK (fp, offset, dir); + off64_t result = _IO_SYSSEEK (fp, offset, dir); if (result < 0) return EOF; @@ -1208,59 +1133,59 @@ _IO_file_seekoff_maybe_mmap (_IO_FILE *fp, _IO_off64_t offset, int dir, return result; } -_IO_ssize_t -_IO_file_read (_IO_FILE *fp, void *buf, _IO_ssize_t size) +ssize_t +_IO_file_read (FILE *fp, void *buf, ssize_t size) { return (__builtin_expect (fp->_flags2 & _IO_FLAGS2_NOTCANCEL, 0) - ? read_not_cancel (fp->_fileno, buf, size) - : read (fp->_fileno, buf, size)); + ? __read_nocancel (fp->_fileno, buf, size) + : __read (fp->_fileno, buf, size)); } libc_hidden_def (_IO_file_read) -_IO_off64_t -_IO_file_seek (_IO_FILE *fp, _IO_off64_t offset, int dir) +off64_t +_IO_file_seek (FILE *fp, off64_t offset, int dir) { return __lseek64 (fp->_fileno, offset, dir); } libc_hidden_def (_IO_file_seek) int -_IO_file_stat (_IO_FILE *fp, void *st) +_IO_file_stat (FILE *fp, void *st) { return __fxstat64 (_STAT_VER, fp->_fileno, (struct stat64 *) st); } libc_hidden_def (_IO_file_stat) int -_IO_file_close_mmap (_IO_FILE *fp) +_IO_file_close_mmap (FILE *fp) { /* In addition to closing the file descriptor we have to unmap the file. */ (void) __munmap (fp->_IO_buf_base, fp->_IO_buf_end - fp->_IO_buf_base); fp->_IO_buf_base = fp->_IO_buf_end = NULL; /* Cancelling close should be avoided if possible since it leaves an unrecoverable state behind. */ - return close_not_cancel (fp->_fileno); + return __close_nocancel (fp->_fileno); } int -_IO_file_close (_IO_FILE *fp) +_IO_file_close (FILE *fp) { /* Cancelling close should be avoided if possible since it leaves an unrecoverable state behind. */ - return close_not_cancel (fp->_fileno); + return __close_nocancel (fp->_fileno); } libc_hidden_def (_IO_file_close) -_IO_ssize_t -_IO_new_file_write (_IO_FILE *f, const void *data, _IO_ssize_t n) +ssize_t +_IO_new_file_write (FILE *f, const void *data, ssize_t n) { - _IO_ssize_t to_do = n; + ssize_t to_do = n; while (to_do > 0) { - _IO_ssize_t count = (__builtin_expect (f->_flags2 - & _IO_FLAGS2_NOTCANCEL, 0) - ? write_not_cancel (f->_fileno, data, to_do) - : write (f->_fileno, data, to_do)); + ssize_t count = (__builtin_expect (f->_flags2 + & _IO_FLAGS2_NOTCANCEL, 0) + ? __write_nocancel (f->_fileno, data, to_do) + : __write (f->_fileno, data, to_do)); if (count < 0) { f->_flags |= _IO_ERR_SEEN; @@ -1275,13 +1200,13 @@ _IO_new_file_write (_IO_FILE *f, const void *data, _IO_ssize_t n) return n; } -_IO_size_t -_IO_new_file_xsputn (_IO_FILE *f, const void *data, _IO_size_t n) +size_t +_IO_new_file_xsputn (FILE *f, const void *data, size_t n) { const char *s = (const char *) data; - _IO_size_t to_do = n; + size_t to_do = n; int must_flush = 0; - _IO_size_t count = 0; + size_t count = 0; if (n <= 0) return 0; @@ -1315,18 +1240,13 @@ _IO_new_file_xsputn (_IO_FILE *f, const void *data, _IO_size_t n) { if (count > to_do) count = to_do; -#ifdef _LIBC f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count); -#else - memcpy (f->_IO_write_ptr, s, count); - f->_IO_write_ptr += count; -#endif s += count; to_do -= count; } if (to_do + must_flush > 0) { - _IO_size_t block_size, do_write; + size_t block_size, do_write; /* Next flush the (full) buffer. */ if (_IO_OVERFLOW (f, EOF) == EOF) /* If nothing else has to be written we must not signal the @@ -1355,11 +1275,11 @@ _IO_new_file_xsputn (_IO_FILE *f, const void *data, _IO_size_t n) } libc_hidden_ver (_IO_new_file_xsputn, _IO_file_xsputn) -_IO_size_t -_IO_file_xsgetn (_IO_FILE *fp, void *data, _IO_size_t n) +size_t +_IO_file_xsgetn (FILE *fp, void *data, size_t n) { - _IO_size_t want, have; - _IO_ssize_t count; + size_t want, have; + ssize_t count; char *s = data; want = n; @@ -1388,12 +1308,7 @@ _IO_file_xsgetn (_IO_FILE *fp, void *data, _IO_size_t n) { if (have > 0) { -#ifdef _LIBC s = __mempcpy (s, fp->_IO_read_ptr, have); -#else - memcpy (s, fp->_IO_read_ptr, have); - s += have; -#endif want -= have; fp->_IO_read_ptr += have; } @@ -1426,7 +1341,7 @@ _IO_file_xsgetn (_IO_FILE *fp, void *data, _IO_size_t n) count = want; if (fp->_IO_buf_base) { - _IO_size_t block_size = fp->_IO_buf_end - fp->_IO_buf_base; + size_t block_size = fp->_IO_buf_end - fp->_IO_buf_base; if (block_size >= 128) count -= want % block_size; } @@ -1453,10 +1368,10 @@ _IO_file_xsgetn (_IO_FILE *fp, void *data, _IO_size_t n) } libc_hidden_def (_IO_file_xsgetn) -static _IO_size_t -_IO_file_xsgetn_mmap (_IO_FILE *fp, void *data, _IO_size_t n) +static size_t +_IO_file_xsgetn_mmap (FILE *fp, void *data, size_t n) { - _IO_size_t have; + size_t have; char *read_ptr = fp->_IO_read_ptr; char *s = (char *) data; @@ -1466,12 +1381,7 @@ _IO_file_xsgetn_mmap (_IO_FILE *fp, void *data, _IO_size_t n) { if (__glibc_unlikely (_IO_in_backup (fp))) { -#ifdef _LIBC s = __mempcpy (s, read_ptr, have); -#else - memcpy (s, read_ptr, have); - s += have; -#endif n -= have; _IO_switch_to_main_get_area (fp); read_ptr = fp->_IO_read_ptr; @@ -1496,20 +1406,15 @@ _IO_file_xsgetn_mmap (_IO_FILE *fp, void *data, _IO_size_t n) if (have != 0) { have = MIN (have, n); -#ifdef _LIBC s = __mempcpy (s, read_ptr, have); -#else - memcpy (s, read_ptr, have); - s += have; -#endif fp->_IO_read_ptr = read_ptr + have; } return s - (char *) data; } -static _IO_size_t -_IO_file_xsgetn_maybe_mmap (_IO_FILE *fp, void *data, _IO_size_t n) +static size_t +_IO_file_xsgetn_maybe_mmap (FILE *fp, void *data, size_t n) { /* We only get here if this is the first attempt to read something. Decide which operations to use and then punt to the chosen one. */ @@ -1518,7 +1423,6 @@ _IO_file_xsgetn_maybe_mmap (_IO_FILE *fp, void *data, _IO_size_t n) return _IO_XSGETN (fp, data, n); } -#ifdef _LIBC versioned_symbol (libc, _IO_new_do_write, _IO_do_write, GLIBC_2_1); versioned_symbol (libc, _IO_new_file_attach, _IO_file_attach, GLIBC_2_1); versioned_symbol (libc, _IO_new_file_close_it, _IO_file_close_it, GLIBC_2_1); @@ -1532,9 +1436,8 @@ versioned_symbol (libc, _IO_new_file_seekoff, _IO_file_seekoff, GLIBC_2_1); versioned_symbol (libc, _IO_new_file_underflow, _IO_file_underflow, GLIBC_2_1); versioned_symbol (libc, _IO_new_file_write, _IO_file_write, GLIBC_2_1); versioned_symbol (libc, _IO_new_file_xsputn, _IO_file_xsputn, GLIBC_2_1); -#endif -const struct _IO_jump_t _IO_file_jumps = +const struct _IO_jump_t _IO_file_jumps libio_vtable = { JUMP_INIT_DUMMY, JUMP_INIT(finish, _IO_file_finish), @@ -1559,7 +1462,7 @@ const struct _IO_jump_t _IO_file_jumps = }; libc_hidden_data_def (_IO_file_jumps) -const struct _IO_jump_t _IO_file_jumps_mmap = +const struct _IO_jump_t _IO_file_jumps_mmap libio_vtable = { JUMP_INIT_DUMMY, JUMP_INIT(finish, _IO_file_finish), @@ -1583,7 +1486,7 @@ const struct _IO_jump_t _IO_file_jumps_mmap = JUMP_INIT(imbue, _IO_default_imbue) }; -const struct _IO_jump_t _IO_file_jumps_maybe_mmap = +const struct _IO_jump_t _IO_file_jumps_maybe_mmap libio_vtable = { JUMP_INIT_DUMMY, JUMP_INIT(finish, _IO_file_finish), diff --git a/libio/fmemopen.c b/libio/fmemopen.c index 23b5c5fea8..319dba83cb 100644 --- a/libio/fmemopen.c +++ b/libio/fmemopen.c @@ -1,5 +1,5 @@ /* fmemopen implementation. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -22,7 +22,6 @@ #include <errno.h> -#include <libio.h> #include <stdio.h> #include <stdlib.h> #include <stdint.h> @@ -38,7 +37,7 @@ struct fmemopen_cookie_struct int mybuffer; /* allocated my buffer? */ int append; /* buffer open for append? */ size_t size; /* buffer length in bytes. */ - _IO_off64_t pos; /* current position at the buffer. */ + off64_t pos; /* current position at the buffer. */ size_t maxpos; /* max position in buffer. */ }; @@ -50,16 +49,14 @@ fmemopen_read (void *cookie, char *b, size_t s) if (c->pos + s > c->maxpos) { - if ((size_t) c->pos == c->maxpos) - return 0; - s = c->size - c->pos; + s = c->maxpos - c->pos; + if ((size_t) c->pos > c->maxpos) + s = 0; } memcpy (b, &(c->buffer[c->pos]), s); c->pos += s; - if ((size_t) c->pos > c->maxpos) - c->maxpos = c->pos; return s; } @@ -69,29 +66,30 @@ static ssize_t fmemopen_write (void *cookie, const char *b, size_t s) { fmemopen_cookie_t *c = (fmemopen_cookie_t *) cookie;; - _IO_off64_t pos = c->append ? c->maxpos : c->pos; - int addnullc; - - addnullc = (s == 0 || b[s - 1] != '\0'); + off64_t pos = c->append ? c->maxpos : c->pos; + int addnullc = (s == 0 || b[s - 1] != '\0'); - if (pos + s + addnullc > c->size) + if (pos + s > c->size) { if ((size_t) (c->pos + addnullc) >= c->size) { __set_errno (ENOSPC); return 0; } - s = c->size - pos - addnullc; + s = c->size - pos; } memcpy (&(c->buffer[pos]), b, s); - pos += s; - if ((size_t) pos > c->maxpos) + c->pos = pos + s; + if ((size_t) c->pos > c->maxpos) { - c->maxpos = pos; - if (addnullc) + c->maxpos = c->pos; + if (c->maxpos < c->size && addnullc) c->buffer[c->maxpos] = '\0'; + /* A null byte is written in a stream open for update iff it fits. */ + else if (c->append == 0 && addnullc != 0) + c->buffer[c->size-1] = '\0'; } return s; @@ -99,9 +97,9 @@ fmemopen_write (void *cookie, const char *b, size_t s) static int -fmemopen_seek (void *cookie, _IO_off64_t *p, int w) +fmemopen_seek (void *cookie, off64_t *p, int w) { - _IO_off64_t np; + off64_t np; fmemopen_cookie_t *c = (fmemopen_cookie_t *) cookie; switch (w) @@ -123,7 +121,10 @@ fmemopen_seek (void *cookie, _IO_off64_t *p, int w) } if (np < 0 || (size_t) np > c->size) - return -1; + { + __set_errno (EINVAL); + return -1; + } *p = c->pos = np; diff --git a/libio/fputc.c b/libio/fputc.c index 261fa2d1b1..1e743eb74c 100644 --- a/libio/fputc.c +++ b/libio/fputc.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -28,17 +28,19 @@ #include "stdio.h" int -fputc (int c, _IO_FILE *fp) +fputc (int c, FILE *fp) { int result; CHECK_FILE (fp, EOF); + if (!_IO_need_lock (fp)) + return _IO_putc_unlocked (c, fp); _IO_acquire_lock (fp); result = _IO_putc_unlocked (c, fp); _IO_release_lock (fp); return result; } -#if defined weak_alias && !defined _IO_MTSAFE_IO +#ifndef _IO_MTSAFE_IO #undef fputc_unlocked weak_alias (fputc, fputc_unlocked) #endif diff --git a/libio/fputc_u.c b/libio/fputc_u.c index 478a2478df..a0a03cbda4 100644 --- a/libio/fputc_u.c +++ b/libio/fputc_u.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -30,8 +30,9 @@ #undef fputc_unlocked int -fputc_unlocked (int c, _IO_FILE *fp) +fputc_unlocked (int c, FILE *fp) { CHECK_FILE (fp, EOF); return _IO_putc_unlocked (c, fp); } +libc_hidden_def (fputc_unlocked) diff --git a/libio/fputwc.c b/libio/fputwc.c index 1591569059..be2baf98fd 100644 --- a/libio/fputwc.c +++ b/libio/fputwc.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -28,7 +28,7 @@ #include <wchar.h> wint_t -fputwc (wchar_t wc, _IO_FILE *fp) +fputwc (wchar_t wc, FILE *fp) { wint_t result; CHECK_FILE (fp, EOF); diff --git a/libio/fputwc_u.c b/libio/fputwc_u.c index 3a92b4fa6d..3bcd997848 100644 --- a/libio/fputwc_u.c +++ b/libio/fputwc_u.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -30,7 +30,7 @@ #undef fputwc_unlocked wint_t -fputwc_unlocked (wchar_t wc, _IO_FILE *fp) +fputwc_unlocked (wchar_t wc, FILE *fp) { CHECK_FILE (fp, WEOF); if (_IO_fwide (fp, 1) < 0) diff --git a/libio/freopen.c b/libio/freopen.c index 8a2a417068..abf19e96f1 100644 --- a/libio/freopen.c +++ b/libio/freopen.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -76,40 +76,31 @@ freopen (const char *filename, const char *mode, FILE *fp) /* unbound stream orientation */ result->_mode = 0; - if (fd != -1) + if (fd != -1 && _IO_fileno (result) != fd) { -#ifdef O_CLOEXEC -# ifndef __ASSUME_DUP3 - int newfd; - if (__have_dup3 < 0) - newfd = -1; - else - newfd = -# endif - __dup3 (_IO_fileno (result), fd, - (result->_flags2 & _IO_FLAGS2_CLOEXEC) != 0 - ? O_CLOEXEC : 0); -#else -# define newfd 1 -#endif - -#ifndef __ASSUME_DUP3 - if (newfd < 0) + /* At this point we have both file descriptors already allocated, + so __dup3 will not fail with EBADF, EINVAL, or EMFILE. But + we still need to check for EINVAL and, due Linux internal + implementation, EBUSY. It is because on how it internally opens + the file by splitting the buffer allocation operation and VFS + opening (a dup operation may run when a file is still pending + 'install' on VFS). */ + if (__dup3 (_IO_fileno (result), fd, + (result->_flags2 & _IO_FLAGS2_CLOEXEC) != 0 + ? O_CLOEXEC : 0) == -1) { - if (errno == ENOSYS) - __have_dup3 = -1; - - __dup2 (_IO_fileno (result), fd); - if ((result->_flags2 & _IO_FLAGS2_CLOEXEC) != 0) - __fcntl (fd, F_SETFD, FD_CLOEXEC); + _IO_file_close_it (result); + result = NULL; + goto end; } -#endif __close (_IO_fileno (result)); _IO_fileno (result) = fd; } } else if (fd != -1) __close (fd); + +end: if (filename == NULL) free ((char *) gfilename); diff --git a/libio/freopen64.c b/libio/freopen64.c index ba85c3ea4f..ea7ebd3da4 100644 --- a/libio/freopen64.c +++ b/libio/freopen64.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -59,40 +59,31 @@ freopen64 (const char *filename, const char *mode, FILE *fp) /* unbound stream orientation */ result->_mode = 0; - if (fd != -1) + if (fd != -1 && _IO_fileno (result) != fd) { -#ifdef O_CLOEXEC -# ifndef __ASSUME_DUP3 - int newfd; - if (__have_dup3 < 0) - newfd = -1; - else - newfd = -# endif - __dup3 (_IO_fileno (result), fd, - (result->_flags2 & _IO_FLAGS2_CLOEXEC) != 0 - ? O_CLOEXEC : 0); -#else -# define newfd 1 -#endif - -#ifndef __ASSUME_DUP3 - if (newfd < 0) + /* At this point we have both file descriptors already allocated, + so __dup3 will not fail with EBADF, EINVAL, or EMFILE. But + we still need to check for EINVAL and, due Linux internal + implementation, EBUSY. It is because on how it internally opens + the file by splitting the buffer allocation operation and VFS + opening (a dup operation may run when a file is still pending + 'install' on VFS). */ + if (__dup3 (_IO_fileno (result), fd, + (result->_flags2 & _IO_FLAGS2_CLOEXEC) != 0 + ? O_CLOEXEC : 0) == -1) { - if (errno == ENOSYS) - __have_dup3 = -1; - - __dup2 (_IO_fileno (result), fd); - if ((result->_flags2 & _IO_FLAGS2_CLOEXEC) != 0) - __fcntl (fd, F_SETFD, FD_CLOEXEC); + _IO_file_close_it (result); + result = NULL; + goto end; } -#endif __close (_IO_fileno (result)); _IO_fileno (result) = fd; } } else if (fd != -1) __close (fd); + +end: if (filename == NULL) free ((char *) gfilename); _IO_release_lock (fp); diff --git a/libio/fseek.c b/libio/fseek.c index a8d677048f..0865321f55 100644 --- a/libio/fseek.c +++ b/libio/fseek.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -28,7 +28,7 @@ #include <stdio.h> int -fseek (_IO_FILE *fp, long int offset, int whence) +fseek (FILE *fp, long int offset, int whence) { int result; CHECK_FILE (fp, -1); diff --git a/libio/fseeko.c b/libio/fseeko.c index 288a48b94e..4d086c15d8 100644 --- a/libio/fseeko.c +++ b/libio/fseeko.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -24,11 +24,15 @@ This exception applies to code released by its copyright holders in files containing the exception. */ +/* We need to disable the redirect for __fseeko64 for the alias + definitions below to work. */ +#define __fseeko64 __fseeko64_disable + #include "libioP.h" #include "stdio.h" int -fseeko (_IO_FILE *fp, off_t offset, int whence) +__fseeko (FILE *fp, off_t offset, int whence) { int result; CHECK_FILE (fp, -1); @@ -37,7 +41,11 @@ fseeko (_IO_FILE *fp, off_t offset, int whence) _IO_release_lock (fp); return result; } +weak_alias (__fseeko, fseeko) #ifdef __OFF_T_MATCHES_OFF64_T -weak_alias (fseeko, fseeko64) +weak_alias (__fseeko, fseeko64) +# undef __fseeko64 +strong_alias (__fseeko, __fseeko64) +libc_hidden_ver (__fseeko, __fseeko64) #endif diff --git a/libio/fseeko64.c b/libio/fseeko64.c index 068bf4e871..1d9bb190a6 100644 --- a/libio/fseeko64.c +++ b/libio/fseeko64.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -32,7 +32,7 @@ #ifndef __OFF_T_MATCHES_OFF64_T int -fseeko64 (_IO_FILE *fp, __off64_t offset, int whence) +__fseeko64 (FILE *fp, off64_t offset, int whence) { int result; CHECK_FILE (fp, -1); @@ -41,5 +41,6 @@ fseeko64 (_IO_FILE *fp, __off64_t offset, int whence) _IO_release_lock (fp); return result; } - +libc_hidden_def (__fseeko64) +weak_alias (__fseeko64, fseeko64) #endif diff --git a/libio/ftello.c b/libio/ftello.c index 7122815f2e..5a3caf4ad9 100644 --- a/libio/ftello.c +++ b/libio/ftello.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -24,16 +24,19 @@ This exception applies to code released by its copyright holders in files containing the exception. */ +/* We need to disable the redirect for __ftello64 for the alias + definitions below to work. */ +#define __ftello64 __ftello64_disable + #include <stdio.h> #include <stdlib.h> #include <libioP.h> #include <errno.h> - off_t -__ftello (_IO_FILE *fp) +__ftello (FILE *fp) { - _IO_off64_t pos; + off64_t pos; CHECK_FILE (fp, -1L); _IO_acquire_lock (fp); pos = _IO_seekoff_unlocked (fp, 0, _IO_seek_cur, 0); @@ -45,17 +48,13 @@ __ftello (_IO_FILE *fp) _IO_release_lock (fp); if (pos == _IO_pos_BAD) { -#ifdef EIO if (errno == 0) __set_errno (EIO); -#endif return -1L; } - if ((_IO_off64_t) (off_t) pos != pos) + if ((off64_t) (off_t) pos != pos) { -#ifdef EOVERFLOW __set_errno (EOVERFLOW); -#endif return -1L; } return pos; @@ -65,4 +64,7 @@ weak_alias (__ftello, ftello) #ifdef __OFF_T_MATCHES_OFF64_T weak_alias (__ftello, ftello64) +# undef __ftello64 +strong_alias (__ftello, __ftello64) +libc_hidden_ver (__ftello, __ftello64) #endif diff --git a/libio/ftello64.c b/libio/ftello64.c index 534968cf9f..d5546e1fb0 100644 --- a/libio/ftello64.c +++ b/libio/ftello64.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -32,9 +32,9 @@ #ifndef __OFF_T_MATCHES_OFF64_T off64_t -ftello64 (_IO_FILE *fp) +__ftello64 (FILE *fp) { - _IO_off64_t pos; + off64_t pos; CHECK_FILE (fp, -1L); _IO_acquire_lock (fp); pos = _IO_seekoff_unlocked (fp, 0, _IO_seek_cur, 0); @@ -46,13 +46,12 @@ ftello64 (_IO_FILE *fp) _IO_release_lock (fp); if (pos == _IO_pos_BAD) { -#ifdef EIO if (errno == 0) __set_errno (EIO); -#endif return -1L; } return pos; } - +libc_hidden_def (__ftello64) +weak_alias (__ftello64, ftello64) #endif diff --git a/libio/fwide.c b/libio/fwide.c index b9dceeaf22..3e105592cd 100644 --- a/libio/fwide.c +++ b/libio/fwide.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1999-2016 Free Software Foundation, Inc. +/* Copyright (C) 1999-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -29,7 +29,7 @@ #include <wchar.h> int -fwide (_IO_FILE *fp, int mode) +fwide (FILE *fp, int mode) { int result; diff --git a/libio/fwprintf.c b/libio/fwprintf.c index 8a8903b187..fab63a8716 100644 --- a/libio/fwprintf.c +++ b/libio/fwprintf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-2016 Free Software Foundation, Inc. +/* Copyright (C) 1991-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/libio/fwscanf.c b/libio/fwscanf.c index b61db7b316..ce4b35d31d 100644 --- a/libio/fwscanf.c +++ b/libio/fwscanf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-2016 Free Software Foundation, Inc. +/* Copyright (C) 1991-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/libio/genops.c b/libio/genops.c index 5803cbf04f..2fec221b99 100644 --- a/libio/genops.c +++ b/libio/genops.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -30,19 +30,13 @@ #include <stdlib.h> #include <string.h> #include <stdbool.h> -#ifdef _LIBC #include <sched.h> -#endif #ifdef _IO_MTSAFE_IO static _IO_lock_t list_all_lock = _IO_lock_initializer; #endif -/* Used to signal modifications to the list of FILE decriptors. */ -static int _IO_list_all_stamp; - - -static _IO_FILE *run_fp; +static FILE *run_fp; #ifdef _IO_MTSAFE_IO static void @@ -59,31 +53,27 @@ _IO_un_link (struct _IO_FILE_plus *fp) { if (fp->file._flags & _IO_LINKED) { - struct _IO_FILE **f; + FILE **f; #ifdef _IO_MTSAFE_IO _IO_cleanup_region_start_noarg (flush_cleanup); _IO_lock_lock (list_all_lock); - run_fp = (_IO_FILE *) fp; - _IO_flockfile ((_IO_FILE *) fp); + run_fp = (FILE *) fp; + _IO_flockfile ((FILE *) fp); #endif if (_IO_list_all == NULL) ; else if (fp == _IO_list_all) - { - _IO_list_all = (struct _IO_FILE_plus *) _IO_list_all->file._chain; - ++_IO_list_all_stamp; - } + _IO_list_all = (struct _IO_FILE_plus *) _IO_list_all->file._chain; else for (f = &_IO_list_all->file._chain; *f; f = &(*f)->_chain) - if (*f == (_IO_FILE *) fp) + if (*f == (FILE *) fp) { *f = fp->file._chain; - ++_IO_list_all_stamp; break; } fp->file._flags &= ~_IO_LINKED; #ifdef _IO_MTSAFE_IO - _IO_funlockfile ((_IO_FILE *) fp); + _IO_funlockfile ((FILE *) fp); run_fp = NULL; _IO_lock_unlock (list_all_lock); _IO_cleanup_region_end (0); @@ -101,14 +91,13 @@ _IO_link_in (struct _IO_FILE_plus *fp) #ifdef _IO_MTSAFE_IO _IO_cleanup_region_start_noarg (flush_cleanup); _IO_lock_lock (list_all_lock); - run_fp = (_IO_FILE *) fp; - _IO_flockfile ((_IO_FILE *) fp); + run_fp = (FILE *) fp; + _IO_flockfile ((FILE *) fp); #endif - fp->file._chain = (_IO_FILE *) _IO_list_all; + fp->file._chain = (FILE *) _IO_list_all; _IO_list_all = fp; - ++_IO_list_all_stamp; #ifdef _IO_MTSAFE_IO - _IO_funlockfile ((_IO_FILE *) fp); + _IO_funlockfile ((FILE *) fp); run_fp = NULL; _IO_lock_unlock (list_all_lock); _IO_cleanup_region_end (0); @@ -119,12 +108,12 @@ libc_hidden_def (_IO_link_in) /* Return minimum _pos markers Assumes the current get area is the main get area. */ -_IO_ssize_t _IO_least_marker (_IO_FILE *fp, char *end_p); +ssize_t _IO_least_marker (FILE *fp, char *end_p); -_IO_ssize_t -_IO_least_marker (_IO_FILE *fp, char *end_p) +ssize_t +_IO_least_marker (FILE *fp, char *end_p) { - _IO_ssize_t least_so_far = end_p - fp->_IO_read_base; + ssize_t least_so_far = end_p - fp->_IO_read_base; struct _IO_marker *mark; for (mark = fp->_markers; mark != NULL; mark = mark->_next) if (mark->_pos < least_so_far) @@ -135,7 +124,7 @@ _IO_least_marker (_IO_FILE *fp, char *end_p) /* Switch current get area from backup buffer to (start of) main get area. */ void -_IO_switch_to_main_get_area (_IO_FILE *fp) +_IO_switch_to_main_get_area (FILE *fp) { char *tmp; fp->_flags &= ~_IO_IN_BACKUP; @@ -154,7 +143,7 @@ _IO_switch_to_main_get_area (_IO_FILE *fp) /* Switch current get area from main get area to (end of) backup area. */ void -_IO_switch_to_backup_area (_IO_FILE *fp) +_IO_switch_to_backup_area (FILE *fp) { char *tmp; fp->_flags |= _IO_IN_BACKUP; @@ -171,7 +160,7 @@ _IO_switch_to_backup_area (_IO_FILE *fp) } int -_IO_switch_to_get_mode (_IO_FILE *fp) +_IO_switch_to_get_mode (FILE *fp) { if (fp->_IO_write_ptr > fp->_IO_write_base) if (_IO_OVERFLOW (fp, EOF) == EOF) @@ -194,7 +183,7 @@ _IO_switch_to_get_mode (_IO_FILE *fp) libc_hidden_def (_IO_switch_to_get_mode) void -_IO_free_backup_area (_IO_FILE *fp) +_IO_free_backup_area (FILE *fp) { if (_IO_in_backup (fp)) _IO_switch_to_main_get_area (fp); /* Just in case. */ @@ -205,26 +194,8 @@ _IO_free_backup_area (_IO_FILE *fp) } libc_hidden_def (_IO_free_backup_area) -#if 0 -int -_IO_switch_to_put_mode (_IO_FILE *fp) -{ - fp->_IO_write_base = fp->_IO_read_ptr; - fp->_IO_write_ptr = fp->_IO_read_ptr; - /* Following is wrong if line- or un-buffered? */ - fp->_IO_write_end = (fp->_flags & _IO_IN_BACKUP - ? fp->_IO_read_end : fp->_IO_buf_end); - - fp->_IO_read_ptr = fp->_IO_read_end; - fp->_IO_read_base = fp->_IO_read_end; - - fp->_flags |= _IO_CURRENTLY_PUTTING; - return 0; -} -#endif - int -__overflow (_IO_FILE *f, int ch) +__overflow (FILE *f, int ch) { /* This is a single-byte stream. */ if (f->_mode == 0) @@ -233,26 +204,17 @@ __overflow (_IO_FILE *f, int ch) } libc_hidden_def (__overflow) -static int save_for_backup (_IO_FILE *fp, char *end_p) -#ifdef _LIBC - internal_function -#endif - ; - static int -#ifdef _LIBC -internal_function -#endif -save_for_backup (_IO_FILE *fp, char *end_p) +save_for_backup (FILE *fp, char *end_p) { /* Append [_IO_read_base..end_p] to backup area. */ - _IO_ssize_t least_mark = _IO_least_marker (fp, end_p); + ssize_t least_mark = _IO_least_marker (fp, end_p); /* needed_size is how much space we need in the backup area. */ - _IO_size_t needed_size = (end_p - fp->_IO_read_base) - least_mark; + size_t needed_size = (end_p - fp->_IO_read_base) - least_mark; /* FIXME: Dubious arithmetic if pointers are NULL */ - _IO_size_t current_Bsize = fp->_IO_save_end - fp->_IO_save_base; - _IO_size_t avail; /* Extra space available for future expansion. */ - _IO_ssize_t delta; + size_t current_Bsize = fp->_IO_save_end - fp->_IO_save_base; + size_t avail; /* Extra space available for future expansion. */ + ssize_t delta; struct _IO_marker *mark; if (needed_size > current_Bsize) { @@ -263,20 +225,11 @@ save_for_backup (_IO_FILE *fp, char *end_p) return EOF; /* FIXME */ if (least_mark < 0) { -#ifdef _LIBC __mempcpy (__mempcpy (new_buffer + avail, fp->_IO_save_end + least_mark, -least_mark), fp->_IO_read_base, end_p - fp->_IO_read_base); -#else - memcpy (new_buffer + avail, - fp->_IO_save_end + least_mark, - -least_mark); - memcpy (new_buffer + avail - least_mark, - fp->_IO_read_base, - end_p - fp->_IO_read_base); -#endif } else memcpy (new_buffer + avail, @@ -312,12 +265,10 @@ save_for_backup (_IO_FILE *fp, char *end_p) } int -__underflow (_IO_FILE *fp) +__underflow (FILE *fp) { -#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T if (_IO_vtable_offset (fp) == 0 && _IO_fwide (fp, -1) != -1) return EOF; -#endif if (fp->_mode == 0) _IO_fwide (fp, -1); @@ -344,12 +295,10 @@ __underflow (_IO_FILE *fp) libc_hidden_def (__underflow) int -__uflow (_IO_FILE *fp) +__uflow (FILE *fp) { -#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T if (_IO_vtable_offset (fp) == 0 && _IO_fwide (fp, -1) != -1) return EOF; -#endif if (fp->_mode == 0) _IO_fwide (fp, -1); @@ -376,7 +325,7 @@ __uflow (_IO_FILE *fp) libc_hidden_def (__uflow) void -_IO_setb (_IO_FILE *f, char *b, char *eb, int a) +_IO_setb (FILE *f, char *b, char *eb, int a) { if (f->_IO_buf_base && !(f->_flags & _IO_USER_BUF)) free (f->_IO_buf_base); @@ -390,7 +339,7 @@ _IO_setb (_IO_FILE *f, char *b, char *eb, int a) libc_hidden_def (_IO_setb) void -_IO_doallocbuf (_IO_FILE *fp) +_IO_doallocbuf (FILE *fp) { if (fp->_IO_buf_base) return; @@ -402,13 +351,13 @@ _IO_doallocbuf (_IO_FILE *fp) libc_hidden_def (_IO_doallocbuf) int -_IO_default_underflow (_IO_FILE *fp) +_IO_default_underflow (FILE *fp) { return EOF; } int -_IO_default_uflow (_IO_FILE *fp) +_IO_default_uflow (FILE *fp) { int ch = _IO_UNDERFLOW (fp); if (ch == EOF) @@ -417,11 +366,11 @@ _IO_default_uflow (_IO_FILE *fp) } libc_hidden_def (_IO_default_uflow) -_IO_size_t -_IO_default_xsputn (_IO_FILE *f, const void *data, _IO_size_t n) +size_t +_IO_default_xsputn (FILE *f, const void *data, size_t n) { const char *s = (char *) data; - _IO_size_t more = n; + size_t more = n; if (more <= 0) return 0; for (;;) @@ -429,23 +378,18 @@ _IO_default_xsputn (_IO_FILE *f, const void *data, _IO_size_t n) /* Space available. */ if (f->_IO_write_ptr < f->_IO_write_end) { - _IO_size_t count = f->_IO_write_end - f->_IO_write_ptr; + size_t count = f->_IO_write_end - f->_IO_write_ptr; if (count > more) count = more; if (count > 20) { -#ifdef _LIBC f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count); -#else - memcpy (f->_IO_write_ptr, s, count); - f->_IO_write_ptr += count; -#endif s += count; } else if (count) { char *p = f->_IO_write_ptr; - _IO_ssize_t i; + ssize_t i; for (i = count; --i >= 0; ) *p++ = *s++; f->_IO_write_ptr = p; @@ -460,35 +404,30 @@ _IO_default_xsputn (_IO_FILE *f, const void *data, _IO_size_t n) } libc_hidden_def (_IO_default_xsputn) -_IO_size_t -_IO_sgetn (_IO_FILE *fp, void *data, _IO_size_t n) +size_t +_IO_sgetn (FILE *fp, void *data, size_t n) { /* FIXME handle putback buffer here! */ return _IO_XSGETN (fp, data, n); } libc_hidden_def (_IO_sgetn) -_IO_size_t -_IO_default_xsgetn (_IO_FILE *fp, void *data, _IO_size_t n) +size_t +_IO_default_xsgetn (FILE *fp, void *data, size_t n) { - _IO_size_t more = n; + size_t more = n; char *s = (char*) data; for (;;) { /* Data available. */ if (fp->_IO_read_ptr < fp->_IO_read_end) { - _IO_size_t count = fp->_IO_read_end - fp->_IO_read_ptr; + size_t count = fp->_IO_read_end - fp->_IO_read_ptr; if (count > more) count = more; if (count > 20) { -#ifdef _LIBC s = __mempcpy (s, fp->_IO_read_ptr, count); -#else - memcpy (s, fp->_IO_read_ptr, count); - s += count; -#endif fp->_IO_read_ptr += count; } else if (count) @@ -508,17 +447,8 @@ _IO_default_xsgetn (_IO_FILE *fp, void *data, _IO_size_t n) } libc_hidden_def (_IO_default_xsgetn) -#if 0 -/* Seems not to be needed. --drepper */ -int -_IO_sync (_IO_FILE *fp) -{ - return 0; -} -#endif - -_IO_FILE * -_IO_default_setbuf (_IO_FILE *fp, char *p, _IO_ssize_t len) +FILE * +_IO_default_setbuf (FILE *fp, char *p, ssize_t len) { if (_IO_SYNC (fp) == EOF) return NULL; @@ -537,38 +467,72 @@ _IO_default_setbuf (_IO_FILE *fp, char *p, _IO_ssize_t len) return fp; } -_IO_off64_t -_IO_default_seekpos (_IO_FILE *fp, _IO_off64_t pos, int mode) +off64_t +_IO_default_seekpos (FILE *fp, off64_t pos, int mode) { return _IO_SEEKOFF (fp, pos, 0, mode); } int -_IO_default_doallocate (_IO_FILE *fp) +_IO_default_doallocate (FILE *fp) { char *buf; - buf = malloc(_IO_BUFSIZ); + buf = malloc(BUFSIZ); if (__glibc_unlikely (buf == NULL)) return EOF; - _IO_setb (fp, buf, buf+_IO_BUFSIZ, 1); + _IO_setb (fp, buf, buf+BUFSIZ, 1); return 1; } libc_hidden_def (_IO_default_doallocate) void -_IO_init (_IO_FILE *fp, int flags) +_IO_init_internal (FILE *fp, int flags) { _IO_no_init (fp, flags, -1, NULL, NULL); } -libc_hidden_def (_IO_init) void -_IO_old_init (_IO_FILE *fp, int flags) +_IO_init (FILE *fp, int flags) +{ + IO_set_accept_foreign_vtables (&_IO_vtable_check); + _IO_init_internal (fp, flags); +} + +static int stdio_needs_locking; + +/* In a single-threaded process most stdio locks can be omitted. After + _IO_enable_locks is called, locks are not optimized away any more. + It must be first called while the process is still single-threaded. + + This lock optimization can be disabled on a per-file basis by setting + _IO_FLAGS2_NEED_LOCK, because a file can have user-defined callbacks + or can be locked with flockfile and then a thread may be created + between a lock and unlock, so omitting the lock is not valid. + + Here we have to make sure that the flag is set on all existing files + and files created later. */ +void +_IO_enable_locks (void) +{ + _IO_ITER i; + + if (stdio_needs_locking) + return; + stdio_needs_locking = 1; + for (i = _IO_iter_begin (); i != _IO_iter_end (); i = _IO_iter_next (i)) + _IO_iter_file (i)->_flags2 |= _IO_FLAGS2_NEED_LOCK; +} +libc_hidden_def (_IO_enable_locks) + +void +_IO_old_init (FILE *fp, int flags) { fp->_flags = _IO_MAGIC|flags; fp->_flags2 = 0; + if (stdio_needs_locking) + fp->_flags2 |= _IO_FLAGS2_NEED_LOCK; fp->_IO_buf_base = NULL; fp->_IO_buf_end = NULL; fp->_IO_read_base = NULL; @@ -594,12 +558,11 @@ _IO_old_init (_IO_FILE *fp, int flags) } void -_IO_no_init (_IO_FILE *fp, int flags, int orientation, +_IO_no_init (FILE *fp, int flags, int orientation, struct _IO_wide_data *wd, const struct _IO_jump_t *jmp) { _IO_old_init (fp, flags); fp->_mode = orientation; -#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T if (orientation >= 0) { fp->_wide_data = wd; @@ -621,12 +584,11 @@ _IO_no_init (_IO_FILE *fp, int flags, int orientation, /* Cause predictable crash when a wide function is called on a byte stream. */ fp->_wide_data = (struct _IO_wide_data *) -1L; -#endif fp->_freeres_list = NULL; } int -_IO_default_sync (_IO_FILE *fp) +_IO_default_sync (FILE *fp) { return 0; } @@ -635,7 +597,7 @@ _IO_default_sync (_IO_FILE *fp) current implementation, this function can get called twice! */ void -_IO_default_finish (_IO_FILE *fp, int dummy) +_IO_default_finish (FILE *fp, int dummy) { struct _IO_marker *mark; if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF)) @@ -662,14 +624,14 @@ _IO_default_finish (_IO_FILE *fp, int dummy) } libc_hidden_def (_IO_default_finish) -_IO_off64_t -_IO_default_seekoff (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode) +off64_t +_IO_default_seekoff (FILE *fp, off64_t offset, int dir, int mode) { return _IO_pos_BAD; } int -_IO_sputbackc (_IO_FILE *fp, int c) +_IO_sputbackc (FILE *fp, int c) { int result; @@ -690,7 +652,7 @@ _IO_sputbackc (_IO_FILE *fp, int c) libc_hidden_def (_IO_sputbackc) int -_IO_sungetc (_IO_FILE *fp) +_IO_sungetc (FILE *fp) { int result; @@ -708,28 +670,6 @@ _IO_sungetc (_IO_FILE *fp) return result; } -#if 0 /* Work in progress */ -/* Seems not to be needed. */ -#if 0 -void -_IO_set_column (_IO_FILE *fp, int c) -{ - if (c == -1) - fp->_column = -1; - else - fp->_column = c - (fp->_IO_write_ptr - fp->_IO_write_base); -} -#else -int -_IO_set_column (_IO_FILE *fp, int i) -{ - fp->_cur_column = i + 1; - return 0; -} -#endif -#endif - - unsigned _IO_adjust_column (unsigned start, const char *line, int count) { @@ -741,47 +681,27 @@ _IO_adjust_column (unsigned start, const char *line, int count) } libc_hidden_def (_IO_adjust_column) -#if 0 -/* Seems not to be needed. --drepper */ -int -_IO_get_column (_IO_FILE *fp) -{ - if (fp->_cur_column) - return _IO_adjust_column (fp->_cur_column - 1, - fp->_IO_write_base, - fp->_IO_write_ptr - fp->_IO_write_base); - return -1; -} -#endif - - int _IO_flush_all_lockp (int do_lock) { int result = 0; - struct _IO_FILE *fp; - int last_stamp; + FILE *fp; #ifdef _IO_MTSAFE_IO - __libc_cleanup_region_start (do_lock, flush_cleanup, NULL); - if (do_lock) - _IO_lock_lock (list_all_lock); + _IO_cleanup_region_start_noarg (flush_cleanup); + _IO_lock_lock (list_all_lock); #endif - last_stamp = _IO_list_all_stamp; - fp = (_IO_FILE *) _IO_list_all; - while (fp != NULL) + for (fp = (FILE *) _IO_list_all; fp != NULL; fp = fp->_chain) { run_fp = fp; if (do_lock) _IO_flockfile (fp); if (((fp->_mode <= 0 && fp->_IO_write_ptr > fp->_IO_write_base) -#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T || (_IO_vtable_offset (fp) == 0 && fp->_mode > 0 && (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_write_base)) -#endif ) && _IO_OVERFLOW (fp, EOF) == EOF) result = EOF; @@ -789,21 +709,11 @@ _IO_flush_all_lockp (int do_lock) if (do_lock) _IO_funlockfile (fp); run_fp = NULL; - - if (last_stamp != _IO_list_all_stamp) - { - /* Something was added to the list. Start all over again. */ - fp = (_IO_FILE *) _IO_list_all; - last_stamp = _IO_list_all_stamp; - } - else - fp = fp->_chain; } #ifdef _IO_MTSAFE_IO - if (do_lock) - _IO_lock_unlock (list_all_lock); - __libc_cleanup_region_end (0); + _IO_lock_unlock (list_all_lock); + _IO_cleanup_region_end (0); #endif return result; @@ -821,17 +731,14 @@ libc_hidden_def (_IO_flush_all) void _IO_flush_all_linebuffered (void) { - struct _IO_FILE *fp; - int last_stamp; + FILE *fp; #ifdef _IO_MTSAFE_IO _IO_cleanup_region_start_noarg (flush_cleanup); _IO_lock_lock (list_all_lock); #endif - last_stamp = _IO_list_all_stamp; - fp = (_IO_FILE *) _IO_list_all; - while (fp != NULL) + for (fp = (FILE *) _IO_list_all; fp != NULL; fp = fp->_chain) { run_fp = fp; _IO_flockfile (fp); @@ -841,15 +748,6 @@ _IO_flush_all_linebuffered (void) _IO_funlockfile (fp); run_fp = NULL; - - if (last_stamp != _IO_list_all_stamp) - { - /* Something was added to the list. Start all over again. */ - fp = (_IO_FILE *) _IO_list_all; - last_stamp = _IO_list_all_stamp; - } - else - fp = fp->_chain; } #ifdef _IO_MTSAFE_IO @@ -858,9 +756,7 @@ _IO_flush_all_linebuffered (void) #endif } libc_hidden_def (_IO_flush_all_linebuffered) -#ifdef _LIBC weak_alias (_IO_flush_all_linebuffered, _flushlbf) -#endif /* The following is a bit tricky. In general, we want to unbuffer the @@ -879,13 +775,19 @@ weak_alias (_IO_flush_all_linebuffered, _flushlbf) static void _IO_unbuffer_all (void); static bool dealloc_buffers; -static _IO_FILE *freeres_list; +static FILE *freeres_list; static void _IO_unbuffer_all (void) { - struct _IO_FILE *fp; - for (fp = (_IO_FILE *) _IO_list_all; fp; fp = fp->_chain) + FILE *fp; + +#ifdef _IO_MTSAFE_IO + _IO_cleanup_region_start_noarg (flush_cleanup); + _IO_lock_lock (list_all_lock); +#endif + + for (fp = (FILE *) _IO_list_all; fp; fp = fp->_chain) { if (! (fp->_flags & _IO_UNBUFFERED) /* Iff stream is un-orientated, it wasn't used. */ @@ -927,6 +829,11 @@ _IO_unbuffer_all (void) used. */ fp->_mode = -1; } + +#ifdef _IO_MTSAFE_IO + _IO_lock_unlock (list_all_lock); + _IO_cleanup_region_end (0); +#endif } @@ -964,7 +871,7 @@ _IO_cleanup (void) void -_IO_init_marker (struct _IO_marker *marker, _IO_FILE *fp) +_IO_init_marker (struct _IO_marker *marker, FILE *fp) { marker->_sbuf = fp; if (_IO_in_put_mode (fp)) @@ -994,10 +901,8 @@ _IO_remove_marker (struct _IO_marker *marker) return; } } -#if 0 - if _sbuf has a backup area that is no longer needed, should we delete - it now, or wait until the next underflow? -#endif + /* FIXME: if _sbuf has a backup area that is no longer needed, + should we delete it now, or wait until the next underflow? */ } #define BAD_DELTA EOF @@ -1023,7 +928,7 @@ _IO_marker_delta (struct _IO_marker *mark) } int -_IO_seekmark (_IO_FILE *fp, struct _IO_marker *mark, int delta) +_IO_seekmark (FILE *fp, struct _IO_marker *mark, int delta) { if (mark->_sbuf != fp) return EOF; @@ -1043,25 +948,11 @@ _IO_seekmark (_IO_FILE *fp, struct _IO_marker *mark, int delta) } void -_IO_unsave_markers (_IO_FILE *fp) +_IO_unsave_markers (FILE *fp) { struct _IO_marker *mark = fp->_markers; if (mark) { -#ifdef TODO - streampos offset = seekoff (0, ios::cur, ios::in); - if (offset != EOF) - { - offset += eGptr () - Gbase (); - for ( ; mark != NULL; mark = mark->_next) - mark->set_streampos (mark->_pos + offset); - } - else - { - for ( ; mark != NULL; mark = mark->_next) - mark->set_streampos (EOF); - } -#endif fp->_markers = 0; } @@ -1070,21 +961,8 @@ _IO_unsave_markers (_IO_FILE *fp) } libc_hidden_def (_IO_unsave_markers) -#if 0 -/* Seems not to be needed. --drepper */ int -_IO_nobackup_pbackfail (_IO_FILE *fp, int c) -{ - if (fp->_IO_read_ptr > fp->_IO_read_base) - fp->_IO_read_ptr--; - if (c != EOF && *fp->_IO_read_ptr != c) - *fp->_IO_read_ptr = c; - return (unsigned char) c; -} -#endif - -int -_IO_default_pbackfail (_IO_FILE *fp, int c) +_IO_default_pbackfail (FILE *fp, int c) { if (fp->_IO_read_ptr > fp->_IO_read_base && !_IO_in_backup (fp) && (unsigned char) fp->_IO_read_ptr[-1] == c) @@ -1119,8 +997,8 @@ _IO_default_pbackfail (_IO_FILE *fp, int c) else if (fp->_IO_read_ptr <= fp->_IO_read_base) { /* Increase size of existing backup buffer. */ - _IO_size_t new_size; - _IO_size_t old_size = fp->_IO_read_end - fp->_IO_read_base; + size_t new_size; + size_t old_size = fp->_IO_read_end - fp->_IO_read_base; char *new_buf; new_size = 2 * old_size; new_buf = (char *) malloc (new_size); @@ -1140,38 +1018,38 @@ _IO_default_pbackfail (_IO_FILE *fp, int c) } libc_hidden_def (_IO_default_pbackfail) -_IO_off64_t -_IO_default_seek (_IO_FILE *fp, _IO_off64_t offset, int dir) +off64_t +_IO_default_seek (FILE *fp, off64_t offset, int dir) { return _IO_pos_BAD; } int -_IO_default_stat (_IO_FILE *fp, void *st) +_IO_default_stat (FILE *fp, void *st) { return EOF; } -_IO_ssize_t -_IO_default_read (_IO_FILE *fp, void *data, _IO_ssize_t n) +ssize_t +_IO_default_read (FILE *fp, void *data, ssize_t n) { return -1; } -_IO_ssize_t -_IO_default_write (_IO_FILE *fp, const void *data, _IO_ssize_t n) +ssize_t +_IO_default_write (FILE *fp, const void *data, ssize_t n) { return 0; } int -_IO_default_showmanyc (_IO_FILE *fp) +_IO_default_showmanyc (FILE *fp) { return -1; } void -_IO_default_imbue (_IO_FILE *fp, void *locale) +_IO_default_imbue (FILE *fp, void *locale) { } @@ -1196,7 +1074,7 @@ _IO_iter_next (_IO_ITER iter) } libc_hidden_def (_IO_iter_next) -_IO_FILE * +FILE * _IO_iter_file (_IO_ITER iter) { return iter; @@ -1230,24 +1108,4 @@ _IO_list_resetlock (void) } libc_hidden_def (_IO_list_resetlock) - -#ifdef TODO -#if defined(linux) -#define IO_CLEANUP ; -#endif - -#ifdef IO_CLEANUP - IO_CLEANUP -#else -struct __io_defs { - __io_defs() { } - ~__io_defs() { _IO_cleanup (); } -}; -__io_defs io_defs__; -#endif - -#endif /* TODO */ - -#ifdef text_set_element text_set_element(__libc_atexit, _IO_cleanup); -#endif diff --git a/libio/getc.c b/libio/getc.c index 434367c7e5..dd925232d5 100644 --- a/libio/getc.c +++ b/libio/getc.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -34,6 +34,8 @@ _IO_getc (FILE *fp) { int result; CHECK_FILE (fp, EOF); + if (!_IO_need_lock (fp)) + return _IO_getc_unlocked (fp); _IO_acquire_lock (fp); result = _IO_getc_unlocked (fp); _IO_release_lock (fp); @@ -42,7 +44,6 @@ _IO_getc (FILE *fp) #undef getc -#ifdef weak_alias weak_alias (_IO_getc, getc) weak_alias (_IO_getc, fgetc) @@ -51,4 +52,3 @@ weak_alias (_IO_getc, fgetc) weak_alias (_IO_getc, getc_unlocked) weak_alias (_IO_getc, fgetc_unlocked) #endif -#endif diff --git a/libio/getc_u.c b/libio/getc_u.c index 7567670b56..ce2bb88849 100644 --- a/libio/getc_u.c +++ b/libio/getc_u.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -37,4 +37,5 @@ __getc_unlocked (FILE *fp) } weak_alias (__getc_unlocked, getc_unlocked) +libc_hidden_weak (getc_unlocked) weak_alias (__getc_unlocked, fgetc_unlocked) diff --git a/libio/getchar.c b/libio/getchar.c index db1b6e3698..0e3f4153c8 100644 --- a/libio/getchar.c +++ b/libio/getchar.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -33,13 +33,15 @@ int getchar (void) { int result; + if (!_IO_need_lock (_IO_stdin)) + return _IO_getc_unlocked (_IO_stdin); _IO_acquire_lock (_IO_stdin); result = _IO_getc_unlocked (_IO_stdin); _IO_release_lock (_IO_stdin); return result; } -#if defined weak_alias && !defined _IO_MTSAFE_IO +#ifndef _IO_MTSAFE_IO #undef getchar_unlocked weak_alias (getchar, getchar_unlocked) #endif diff --git a/libio/getchar_u.c b/libio/getchar_u.c index de158ac895..4a0499dc69 100644 --- a/libio/getchar_u.c +++ b/libio/getchar_u.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/libio/getwc.c b/libio/getwc.c index dc41d71fc2..f660c93a75 100644 --- a/libio/getwc.c +++ b/libio/getwc.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -43,7 +43,5 @@ _IO_getwc (FILE *fp) #undef getwc -#ifdef weak_alias weak_alias (_IO_getwc, getwc) weak_alias (_IO_getwc, fgetwc) -#endif diff --git a/libio/getwc_u.c b/libio/getwc_u.c index 2f8682fea7..57ebad958e 100644 --- a/libio/getwc_u.c +++ b/libio/getwc_u.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/libio/getwchar.c b/libio/getwchar.c index 03df4755eb..f58a8a62b7 100644 --- a/libio/getwchar.c +++ b/libio/getwchar.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/libio/getwchar_u.c b/libio/getwchar_u.c index e7f17777cb..d10acf1329 100644 --- a/libio/getwchar_u.c +++ b/libio/getwchar_u.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/libio/iofclose.c b/libio/iofclose.c index 33b130eb25..7a8b89f9f5 100644 --- a/libio/iofclose.c +++ b/libio/iofclose.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -26,16 +26,11 @@ #include "libioP.h" #include <stdlib.h> -#if _LIBC -# include "../iconv/gconv_int.h" -# include <shlib-compat.h> -#else -# define SHLIB_COMPAT(a, b, c) 0 -# define _IO_new_fclose fclose -#endif +#include "../iconv/gconv_int.h" +#include <shlib-compat.h> int -_IO_new_fclose (_IO_FILE *fp) +_IO_new_fclose (FILE *fp) { int status; @@ -50,11 +45,11 @@ _IO_new_fclose (_IO_FILE *fp) #endif /* First unlink the stream. */ - if (fp->_IO_file_flags & _IO_IS_FILEBUF) + if (fp->_flags & _IO_IS_FILEBUF) _IO_un_link ((struct _IO_FILE_plus *) fp); _IO_acquire_lock (fp); - if (fp->_IO_file_flags & _IO_IS_FILEBUF) + if (fp->_flags & _IO_IS_FILEBUF) status = _IO_file_close_it (fp); else status = fp->_flags & _IO_ERR_SEEN ? -1 : 0; @@ -62,7 +57,6 @@ _IO_new_fclose (_IO_FILE *fp) _IO_FINISH (fp); if (fp->_mode > 0) { -#if _LIBC /* This stream has a wide orientation. This means we have to free the conversion functions. */ struct _IO_codecvt *cc = fp->_codecvt; @@ -71,7 +65,6 @@ _IO_new_fclose (_IO_FILE *fp) __gconv_release_step (cc->__cd_in.__cd.__steps); __gconv_release_step (cc->__cd_out.__cd.__steps); __libc_lock_unlock (__gconv_lock); -#endif } else { @@ -80,15 +73,13 @@ _IO_new_fclose (_IO_FILE *fp) } if (fp != _IO_stdin && fp != _IO_stdout && fp != _IO_stderr) { - fp->_IO_file_flags = 0; + fp->_flags = 0; free(fp); } return status; } -#ifdef _LIBC versioned_symbol (libc, _IO_new_fclose, _IO_fclose, GLIBC_2_1); strong_alias (_IO_new_fclose, __new_fclose) versioned_symbol (libc, __new_fclose, fclose, GLIBC_2_1); -#endif diff --git a/libio/iofdopen.c b/libio/iofdopen.c index e00f337521..1f20eacb25 100644 --- a/libio/iofdopen.c +++ b/libio/iofdopen.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -28,19 +28,9 @@ #include "libioP.h" #include <fcntl.h> -#ifdef _LIBC -# include <shlib-compat.h> -#endif - -#ifndef _IO_fcntl -#ifdef _LIBC -#define _IO_fcntl __fcntl -#else -#define _IO_fcntl fcntl -#endif -#endif +#include <shlib-compat.h> -_IO_FILE * +FILE * _IO_new_fdopen (int fd, const char *mode) { int read_write; @@ -72,7 +62,7 @@ _IO_new_fdopen (int fd, const char *mode) read_write = _IO_NO_READS|_IO_IS_APPENDING; break; default: - MAYBE_SET_EINVAL; + __set_errno (EINVAL); return NULL; } for (i = 1; i < 5; ++i) @@ -95,18 +85,14 @@ _IO_new_fdopen (int fd, const char *mode) } break; } -#ifdef F_GETFL - int fd_flags = _IO_fcntl (fd, F_GETFL); -#ifndef O_ACCMODE -#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) -#endif + int fd_flags = __fcntl (fd, F_GETFL); if (fd_flags == -1) return NULL; if (((fd_flags & O_ACCMODE) == O_RDONLY && !(read_write & _IO_NO_WRITES)) || ((fd_flags & O_ACCMODE) == O_WRONLY && !(read_write & _IO_NO_READS))) { - MAYBE_SET_EINVAL; + __set_errno (EINVAL); return NULL; } @@ -129,12 +115,9 @@ _IO_new_fdopen (int fd, const char *mode) if ((read_write & _IO_IS_APPENDING) && !(fd_flags & O_APPEND)) { do_seek = true; -#ifdef F_SETFL - if (_IO_fcntl (fd, F_SETFL, fd_flags | O_APPEND) == -1) -#endif + if (__fcntl (fd, F_SETFL, fd_flags | O_APPEND) == -1) return NULL; } -#endif new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE)); if (new_f == NULL) @@ -143,25 +126,22 @@ _IO_new_fdopen (int fd, const char *mode) new_f->fp.file._lock = &new_f->lock; #endif _IO_no_init (&new_f->fp.file, 0, 0, &new_f->wd, -#ifdef _G_HAVE_MMAP +#if _G_HAVE_MMAP (use_mmap && (read_write & _IO_NO_WRITES)) ? &_IO_wfile_jumps_maybe_mmap : #endif &_IO_wfile_jumps); _IO_JUMPS (&new_f->fp) = -#ifdef _G_HAVE_MMAP +#if _G_HAVE_MMAP (use_mmap && (read_write & _IO_NO_WRITES)) ? &_IO_file_jumps_maybe_mmap : #endif &_IO_file_jumps; - _IO_file_init (&new_f->fp); -#if !_IO_UNIFIED_JUMPTABLES - new_f->fp.vtable = NULL; -#endif - /* We only need to record the fd because _IO_file_init will have unset the - offset. It is important to unset the cached offset because the real - offset in the file could change between now and when the handle is - activated and we would then mislead ftell into believing that we have a - valid offset. */ + _IO_new_file_init_internal (&new_f->fp); + /* We only need to record the fd because _IO_file_init_internal will + have unset the offset. It is important to unset the cached + offset because the real offset in the file could change between + now and when the handle is activated and we would then mislead + ftell into believing that we have a valid offset. */ new_f->fp.file._fileno = fd; new_f->fp.file._flags &= ~_IO_DELETE_DONT_CLOSE; @@ -174,7 +154,7 @@ _IO_new_fdopen (int fd, const char *mode) if (do_seek && ((read_write & (_IO_IS_APPENDING | _IO_NO_READS)) == (_IO_IS_APPENDING | _IO_NO_READS))) { - _IO_off64_t new_pos = _IO_SYSSEEK (&new_f->fp.file, 0, _IO_seek_end); + off64_t new_pos = _IO_SYSSEEK (&new_f->fp.file, 0, _IO_seek_end); if (new_pos == _IO_pos_BAD && errno != ESPIPE) return NULL; } diff --git a/libio/iofflush.c b/libio/iofflush.c index f81bc339f1..5f3a3246a9 100644 --- a/libio/iofflush.c +++ b/libio/iofflush.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -28,7 +28,7 @@ #include <stdio.h> int -_IO_fflush (_IO_FILE *fp) +_IO_fflush (FILE *fp) { if (fp == NULL) return _IO_flush_all (); @@ -44,7 +44,6 @@ _IO_fflush (_IO_FILE *fp) } libc_hidden_def (_IO_fflush) -#ifdef weak_alias weak_alias (_IO_fflush, fflush) libc_hidden_weak (fflush) @@ -54,4 +53,3 @@ libc_hidden_def (__fflush_unlocked) weak_alias (_IO_fflush, fflush_unlocked) libc_hidden_weak (fflush_unlocked) #endif -#endif diff --git a/libio/iofflush_u.c b/libio/iofflush_u.c index ad5b122bc5..aff264a0b3 100644 --- a/libio/iofflush_u.c +++ b/libio/iofflush_u.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -28,7 +28,7 @@ #include <stdio.h> int -__fflush_unlocked (_IO_FILE *fp) +__fflush_unlocked (FILE *fp) { if (fp == NULL) return _IO_flush_all (); diff --git a/libio/iofgetpos.c b/libio/iofgetpos.c index 70b3a6d33f..8177326c9c 100644 --- a/libio/iofgetpos.c +++ b/libio/iofgetpos.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -29,20 +29,22 @@ complain about the mismatch when we do the alias below. */ #define _IO_new_fgetpos64 __renamed__IO_new_fgetpos64 #define _IO_fgetpos64 __renamed__IO_fgetpos64 +#define fgetpos64 __renamed_fgetpos64 #include "libioP.h" #undef _IO_new_fgetpos64 #undef _IO_fgetpos64 +#undef fgetpos64 #include <errno.h> #include <stdlib.h> #include <shlib-compat.h> int -_IO_new_fgetpos (_IO_FILE *fp, _IO_fpos_t *posp) +_IO_new_fgetpos (FILE *fp, __fpos_t *posp) { - _IO_off64_t pos; + off64_t pos; int result = 0; CHECK_FILE (fp, EOF); _IO_acquire_lock (fp); @@ -56,17 +58,13 @@ _IO_new_fgetpos (_IO_FILE *fp, _IO_fpos_t *posp) { /* ANSI explicitly requires setting errno to a positive value on failure. */ -#ifdef EIO if (errno == 0) __set_errno (EIO); -#endif result = EOF; } - else if ((_IO_off64_t) (__typeof (posp->__pos)) pos != pos) + else if ((off64_t) (__typeof (posp->__pos)) pos != pos) { -#ifdef EOVERFLOW __set_errno (EOVERFLOW); -#endif result = EOF; } else diff --git a/libio/iofgetpos64.c b/libio/iofgetpos64.c index 563d075cdc..0ec5413197 100644 --- a/libio/iofgetpos64.c +++ b/libio/iofgetpos64.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -31,9 +31,9 @@ #ifndef __OFF_T_MATCHES_OFF64_T int -_IO_new_fgetpos64 (_IO_FILE *fp, _IO_fpos64_t *posp) +_IO_new_fgetpos64 (FILE *fp, __fpos64_t *posp) { - _IO_off64_t pos; + off64_t pos; int result = 0; CHECK_FILE (fp, EOF); _IO_acquire_lock (fp); @@ -47,10 +47,8 @@ _IO_new_fgetpos64 (_IO_FILE *fp, _IO_fpos64_t *posp) { /* ANSI explicitly requires setting errno to a positive value on failure. */ -# ifdef EIO if (errno == 0) __set_errno (EIO); -# endif result = EOF; } else diff --git a/libio/iofgets.c b/libio/iofgets.c index 6fd86eac75..68177dbe22 100644 --- a/libio/iofgets.c +++ b/libio/iofgets.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -28,9 +28,9 @@ #include <stdio.h> char * -_IO_fgets (char *buf, int n, _IO_FILE *fp) +_IO_fgets (char *buf, int n, FILE *fp) { - _IO_size_t count; + size_t count; char *result; int old_error; CHECK_FILE (fp, NULL); @@ -48,25 +48,23 @@ _IO_fgets (char *buf, int n, _IO_FILE *fp) /* This is very tricky since a file descriptor may be in the non-blocking mode. The error flag doesn't mean much in this case. We return an error only when there is a new error. */ - old_error = fp->_IO_file_flags & _IO_ERR_SEEN; - fp->_IO_file_flags &= ~_IO_ERR_SEEN; + old_error = fp->_flags & _IO_ERR_SEEN; + fp->_flags &= ~_IO_ERR_SEEN; count = _IO_getline (fp, buf, n - 1, '\n', 1); /* If we read in some bytes and errno is EAGAIN, that error will be reported for next read. */ - if (count == 0 || ((fp->_IO_file_flags & _IO_ERR_SEEN) - && errno != EAGAIN)) + if (count == 0 || ((fp->_flags & _IO_ERR_SEEN) && errno != EAGAIN)) result = NULL; else { buf[count] = '\0'; result = buf; } - fp->_IO_file_flags |= old_error; + fp->_flags |= old_error; _IO_release_lock (fp); return result; } -#ifdef weak_alias weak_alias (_IO_fgets, fgets) # ifndef _IO_MTSAFE_IO @@ -75,4 +73,3 @@ libc_hidden_def (__fgets_unlocked) weak_alias (_IO_fgets, fgets_unlocked) libc_hidden_weak (fgets_unlocked) # endif -#endif diff --git a/libio/iofgets_u.c b/libio/iofgets_u.c index e4705ffb05..9d33a37621 100644 --- a/libio/iofgets_u.c +++ b/libio/iofgets_u.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -28,9 +28,9 @@ #include <stdio.h> char * -__fgets_unlocked (char *buf, int n, _IO_FILE *fp) +__fgets_unlocked (char *buf, int n, FILE *fp) { - _IO_size_t count; + size_t count; char *result; int old_error; CHECK_FILE (fp, NULL); @@ -47,20 +47,19 @@ __fgets_unlocked (char *buf, int n, _IO_FILE *fp) /* This is very tricky since a file descriptor may be in the non-blocking mode. The error flag doesn't mean much in this case. We return an error only when there is a new error. */ - old_error = fp->_IO_file_flags & _IO_ERR_SEEN; - fp->_IO_file_flags &= ~_IO_ERR_SEEN; + old_error = fp->_flags & _IO_ERR_SEEN; + fp->_flags &= ~_IO_ERR_SEEN; count = _IO_getline (fp, buf, n - 1, '\n', 1); /* If we read in some bytes and errno is EAGAIN, that error will be reported for next read. */ - if (count == 0 || ((fp->_IO_file_flags & _IO_ERR_SEEN) - && errno != EAGAIN)) + if (count == 0 || ((fp->_flags & _IO_ERR_SEEN) && errno != EAGAIN)) result = NULL; else { buf[count] = '\0'; result = buf; } - fp->_IO_file_flags |= old_error; + fp->_flags |= old_error; return result; } libc_hidden_def (__fgets_unlocked) diff --git a/libio/iofgetws.c b/libio/iofgetws.c index 7a61d8c675..292a161757 100644 --- a/libio/iofgetws.c +++ b/libio/iofgetws.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -28,9 +28,9 @@ #include <wchar.h> wchar_t * -fgetws (wchar_t *buf, int n, _IO_FILE *fp) +fgetws (wchar_t *buf, int n, FILE *fp) { - _IO_size_t count; + size_t count; wchar_t *result; int old_error; CHECK_FILE (fp, NULL); @@ -48,8 +48,8 @@ fgetws (wchar_t *buf, int n, _IO_FILE *fp) /* This is very tricky since a file descriptor may be in the non-blocking mode. The error flag doesn't mean much in this case. We return an error only when there is a new error. */ - old_error = fp->_IO_file_flags & _IO_ERR_SEEN; - fp->_IO_file_flags &= ~_IO_ERR_SEEN; + old_error = fp->_flags & _IO_ERR_SEEN; + fp->_flags &= ~_IO_ERR_SEEN; count = _IO_getwline (fp, buf, n - 1, L'\n', 1); /* If we read in some bytes and errno is EAGAIN, that error will be reported for next read. */ @@ -60,7 +60,7 @@ fgetws (wchar_t *buf, int n, _IO_FILE *fp) buf[count] = '\0'; result = buf; } - fp->_IO_file_flags |= old_error; + fp->_flags |= old_error; _IO_release_lock (fp); return result; } diff --git a/libio/iofgetws_u.c b/libio/iofgetws_u.c index eafc45e469..46431a278b 100644 --- a/libio/iofgetws_u.c +++ b/libio/iofgetws_u.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -28,9 +28,9 @@ #include <wchar.h> wchar_t * -fgetws_unlocked (wchar_t *buf, int n, _IO_FILE *fp) +fgetws_unlocked (wchar_t *buf, int n, FILE *fp) { - _IO_size_t count; + size_t count; wchar_t *result; int old_error; CHECK_FILE (fp, NULL); @@ -47,19 +47,18 @@ fgetws_unlocked (wchar_t *buf, int n, _IO_FILE *fp) /* This is very tricky since a file descriptor may be in the non-blocking mode. The error flag doesn't mean much in this case. We return an error only when there is a new error. */ - old_error = fp->_IO_file_flags & _IO_ERR_SEEN; - fp->_IO_file_flags &= ~_IO_ERR_SEEN; + old_error = fp->_flags & _IO_ERR_SEEN; + fp->_flags &= ~_IO_ERR_SEEN; count = _IO_getwline (fp, buf, n - 1, L'\n', 1); /* If we read in some bytes and errno is EAGAIN, that error will be reported for next read. */ - if (count == 0 || ((fp->_IO_file_flags & _IO_ERR_SEEN) - && errno != EAGAIN)) + if (count == 0 || ((fp->_flags & _IO_ERR_SEEN) && errno != EAGAIN)) result = NULL; else { buf[count] = '\0'; result = buf; } - fp->_IO_file_flags |= old_error; + fp->_flags |= old_error; return result; } diff --git a/libio/iofopen.c b/libio/iofopen.c index 13e3910b63..ed3e8b853c 100644 --- a/libio/iofopen.c +++ b/libio/iofopen.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -28,16 +28,12 @@ #include <fcntl.h> #include <stdlib.h> #include <stddef.h> -#ifdef _LIBC -# include <shlib-compat.h> -#else -# define _IO_new_fopen fopen -#endif +#include <shlib-compat.h> -_IO_FILE * -__fopen_maybe_mmap (_IO_FILE *fp) +FILE * +__fopen_maybe_mmap (FILE *fp) { -#ifdef _G_HAVE_MMAP +#if _G_HAVE_MMAP if ((fp->_flags2 & _IO_FLAGS2_MMAP) && (fp->_flags & _IO_NO_WRITES)) { /* Since this is read-only, we might be able to mmap the contents @@ -56,7 +52,7 @@ __fopen_maybe_mmap (_IO_FILE *fp) } -_IO_FILE * +FILE * __fopen_internal (const char *filename, const char *mode, int is32) { struct locked_FILE @@ -73,17 +69,10 @@ __fopen_internal (const char *filename, const char *mode, int is32) #ifdef _IO_MTSAFE_IO new_f->fp.file._lock = &new_f->lock; #endif -#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T _IO_no_init (&new_f->fp.file, 0, 0, &new_f->wd, &_IO_wfile_jumps); -#else - _IO_no_init (&new_f->fp.file, 1, 0, NULL, NULL); -#endif _IO_JUMPS (&new_f->fp) = &_IO_file_jumps; - _IO_file_init (&new_f->fp); -#if !_IO_UNIFIED_JUMPTABLES - new_f->fp.vtable = NULL; -#endif - if (_IO_file_fopen ((_IO_FILE *) new_f, filename, mode, is32) != NULL) + _IO_new_file_init_internal (&new_f->fp); + if (_IO_file_fopen ((FILE *) new_f, filename, mode, is32) != NULL) return __fopen_maybe_mmap (&new_f->fp.file); _IO_un_link (&new_f->fp); @@ -91,13 +80,12 @@ __fopen_internal (const char *filename, const char *mode, int is32) return NULL; } -_IO_FILE * +FILE * _IO_new_fopen (const char *filename, const char *mode) { return __fopen_internal (filename, mode, 1); } -#ifdef _LIBC strong_alias (_IO_new_fopen, __new_fopen) versioned_symbol (libc, _IO_new_fopen, _IO_fopen, GLIBC_2_1); versioned_symbol (libc, __new_fopen, fopen, GLIBC_2_1); @@ -106,4 +94,3 @@ versioned_symbol (libc, __new_fopen, fopen, GLIBC_2_1); weak_alias (_IO_new_fopen, _IO_fopen64) weak_alias (_IO_new_fopen, fopen64) # endif -#endif diff --git a/libio/iofopen64.c b/libio/iofopen64.c index daf722432d..e3c7c29903 100644 --- a/libio/iofopen64.c +++ b/libio/iofopen64.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -29,16 +29,14 @@ #include <stdlib.h> /* iofopen.c defines _IO_fopen64/fopen64 as aliases if O_LARGEFILE==0. */ -#if !defined _LIBC || (defined O_LARGEFILE && O_LARGEFILE != 0) +#if defined O_LARGEFILE && O_LARGEFILE != 0 -_IO_FILE * +FILE * _IO_fopen64 (const char *filename, const char *mode) { return __fopen_internal (filename, mode, 0); } -#ifdef weak_alias weak_alias (_IO_fopen64, fopen64) -#endif #endif diff --git a/libio/iofopncook.c b/libio/iofopncook.c index 9eda7c1eaa..43a87fe4be 100644 --- a/libio/iofopncook.c +++ b/libio/iofopncook.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -29,71 +29,77 @@ #include <stdlib.h> #include <shlib-compat.h> -/* Prototyped for local functions. */ -static _IO_ssize_t _IO_cookie_read (_IO_FILE* fp, void* buf, - _IO_ssize_t size); -static _IO_ssize_t _IO_cookie_write (_IO_FILE* fp, - const void* buf, _IO_ssize_t size); -static _IO_off64_t _IO_cookie_seek (_IO_FILE *fp, _IO_off64_t offset, int dir); -static _IO_off64_t _IO_cookie_seekoff (_IO_FILE *fp, _IO_off64_t offset, - int dir, int mode); -static int _IO_cookie_close (_IO_FILE* fp); - -static _IO_ssize_t -_IO_cookie_read (_IO_FILE *fp, void *buf, _IO_ssize_t size) +static ssize_t +_IO_cookie_read (FILE *fp, void *buf, ssize_t size) { struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp; + cookie_read_function_t *read_cb = cfile->__io_functions.read; +#ifdef PTR_DEMANGLE + PTR_DEMANGLE (read_cb); +#endif - if (cfile->__io_functions.read == NULL) + if (read_cb == NULL) return -1; - return cfile->__io_functions.read (cfile->__cookie, buf, size); + return read_cb (cfile->__cookie, buf, size); } -static _IO_ssize_t -_IO_cookie_write (_IO_FILE *fp, const void *buf, _IO_ssize_t size) +static ssize_t +_IO_cookie_write (FILE *fp, const void *buf, ssize_t size) { struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp; + cookie_write_function_t *write_cb = cfile->__io_functions.write; +#ifdef PTR_DEMANGLE + PTR_DEMANGLE (write_cb); +#endif - if (cfile->__io_functions.write == NULL) + if (write_cb == NULL) { fp->_flags |= _IO_ERR_SEEN; return 0; } - _IO_ssize_t n = cfile->__io_functions.write (cfile->__cookie, buf, size); + ssize_t n = write_cb (cfile->__cookie, buf, size); if (n < size) fp->_flags |= _IO_ERR_SEEN; return n; } -static _IO_off64_t -_IO_cookie_seek (_IO_FILE *fp, _IO_off64_t offset, int dir) +static off64_t +_IO_cookie_seek (FILE *fp, off64_t offset, int dir) { struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp; + cookie_seek_function_t *seek_cb = cfile->__io_functions.seek; +#ifdef PTR_DEMANGLE + PTR_DEMANGLE (seek_cb); +#endif - return ((cfile->__io_functions.seek == NULL - || (cfile->__io_functions.seek (cfile->__cookie, &offset, dir) + return ((seek_cb == NULL + || (seek_cb (cfile->__cookie, &offset, dir) == -1) - || offset == (_IO_off64_t) -1) + || offset == (off64_t) -1) ? _IO_pos_BAD : offset); } static int -_IO_cookie_close (_IO_FILE *fp) +_IO_cookie_close (FILE *fp) { struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp; + cookie_close_function_t *close_cb = cfile->__io_functions.close; +#ifdef PTR_DEMANGLE + PTR_DEMANGLE (close_cb); +#endif - if (cfile->__io_functions.close == NULL) + if (close_cb == NULL) return 0; - return cfile->__io_functions.close (cfile->__cookie); + return close_cb (cfile->__cookie); } -static _IO_off64_t -_IO_cookie_seekoff (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode) +static off64_t +_IO_cookie_seekoff (FILE *fp, off64_t offset, int dir, int mode) { /* We must force the fileops code to always use seek to determine the position. */ @@ -102,7 +108,7 @@ _IO_cookie_seekoff (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode) } -static const struct _IO_jump_t _IO_cookie_jumps = { +static const struct _IO_jump_t _IO_cookie_jumps libio_vtable = { JUMP_INIT_DUMMY, JUMP_INIT(finish, _IO_file_finish), JUMP_INIT(overflow, _IO_file_overflow), @@ -126,21 +132,38 @@ static const struct _IO_jump_t _IO_cookie_jumps = { }; +/* Copy the callbacks from SOURCE to *TARGET, with pointer + mangling. */ +static void +set_callbacks (cookie_io_functions_t *target, + cookie_io_functions_t source) +{ +#ifdef PTR_MANGLE + PTR_MANGLE (source.read); + PTR_MANGLE (source.write); + PTR_MANGLE (source.seek); + PTR_MANGLE (source.close); +#endif + *target = source; +} + void _IO_cookie_init (struct _IO_cookie_file *cfile, int read_write, - void *cookie, _IO_cookie_io_functions_t io_functions) + void *cookie, cookie_io_functions_t io_functions) { - _IO_init (&cfile->__fp.file, 0); + _IO_init_internal (&cfile->__fp.file, 0); _IO_JUMPS (&cfile->__fp) = &_IO_cookie_jumps; cfile->__cookie = cookie; - cfile->__io_functions = io_functions; + set_callbacks (&cfile->__io_functions, io_functions); - _IO_file_init (&cfile->__fp); + _IO_new_file_init_internal (&cfile->__fp); _IO_mask_flags (&cfile->__fp.file, read_write, _IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING); + cfile->__fp.file._flags2 |= _IO_FLAGS2_NEED_LOCK; + /* We use a negative number different from -1 for _fileno to mark that this special stream is not associated with a real file, but still has to be treated as such. */ @@ -148,9 +171,9 @@ _IO_cookie_init (struct _IO_cookie_file *cfile, int read_write, } -_IO_FILE * +FILE * _IO_fopencookie (void *cookie, const char *mode, - _IO_cookie_io_functions_t io_functions) + cookie_io_functions_t io_functions) { int read_write; struct locked_FILE @@ -188,36 +211,33 @@ _IO_fopencookie (void *cookie, const char *mode, _IO_cookie_init (&new_f->cfile, read_write, cookie, io_functions); - return (_IO_FILE *) &new_f->cfile.__fp; + return (FILE *) &new_f->cfile.__fp; } versioned_symbol (libc, _IO_fopencookie, fopencookie, GLIBC_2_2); #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2) -static _IO_off64_t _IO_old_cookie_seek (_IO_FILE *fp, _IO_off64_t offset, - int dir); -_IO_FILE * _IO_old_fopencookie (void *cookie, const char *mode, - _IO_cookie_io_functions_t io_functions); - -static _IO_off64_t +static off64_t attribute_compat_text_section -_IO_old_cookie_seek (_IO_FILE *fp, _IO_off64_t offset, int dir) +_IO_old_cookie_seek (FILE *fp, off64_t offset, int dir) { struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp; - int (*seek) (_IO_FILE *, _IO_off_t, int); - int ret; + int (*seek_cb) (FILE *, off_t, int) + = (int (*) (FILE *, off_t, int)) cfile->__io_functions.seek; +#ifdef PTR_DEMANGLE + PTR_DEMANGLE (seek_cb); +#endif - seek = (int (*)(_IO_FILE *, _IO_off_t, int)) cfile->__io_functions.seek; - if (seek == NULL) + if (seek_cb == NULL) return _IO_pos_BAD; - ret = seek (cfile->__cookie, offset, dir); + int ret = seek_cb (cfile->__cookie, offset, dir); return (ret == -1) ? _IO_pos_BAD : ret; } -static const struct _IO_jump_t _IO_old_cookie_jumps = { +static const struct _IO_jump_t _IO_old_cookie_jumps libio_vtable = { JUMP_INIT_DUMMY, JUMP_INIT(finish, _IO_file_finish), JUMP_INIT(overflow, _IO_file_overflow), @@ -240,12 +260,12 @@ static const struct _IO_jump_t _IO_old_cookie_jumps = { JUMP_INIT(imbue, _IO_default_imbue), }; -_IO_FILE * +FILE * attribute_compat_text_section _IO_old_fopencookie (void *cookie, const char *mode, - _IO_cookie_io_functions_t io_functions) + cookie_io_functions_t io_functions) { - _IO_FILE *ret; + FILE *ret; ret = _IO_fopencookie (cookie, mode, io_functions); if (ret != NULL) diff --git a/libio/iofputs.c b/libio/iofputs.c index 4868ce40d9..96c7e8d329 100644 --- a/libio/iofputs.c +++ b/libio/iofputs.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -28,9 +28,9 @@ #include <string.h> int -_IO_fputs (const char *str, _IO_FILE *fp) +_IO_fputs (const char *str, FILE *fp) { - _IO_size_t len = strlen (str); + size_t len = strlen (str); int result = EOF; CHECK_FILE (fp, EOF); _IO_acquire_lock (fp); @@ -42,8 +42,8 @@ _IO_fputs (const char *str, _IO_FILE *fp) } libc_hidden_def (_IO_fputs) -#ifdef weak_alias weak_alias (_IO_fputs, fputs) +libc_hidden_weak (fputs) # ifndef _IO_MTSAFE_IO strong_alias (_IO_fputs, __fputs_unlocked) @@ -51,4 +51,3 @@ libc_hidden_def (__fputs_unlocked) weak_alias (_IO_fputs, fputs_unlocked) libc_hidden_ver (_IO_fputs, fputs_unlocked) # endif -#endif diff --git a/libio/iofputs_u.c b/libio/iofputs_u.c index 9997dfc38f..94309b48a2 100644 --- a/libio/iofputs_u.c +++ b/libio/iofputs_u.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -29,9 +29,9 @@ #include <string.h> int -__fputs_unlocked (const char *str, _IO_FILE *fp) +__fputs_unlocked (const char *str, FILE *fp) { - _IO_size_t len = strlen (str); + size_t len = strlen (str); int result = EOF; CHECK_FILE (fp, EOF); if (_IO_fwide (fp, -1) == -1 && _IO_sputn (fp, str, len) == len) diff --git a/libio/iofputws.c b/libio/iofputws.c index de67ce0fa1..70b1f064d2 100644 --- a/libio/iofputws.c +++ b/libio/iofputws.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -28,9 +28,9 @@ #include <wchar.h> int -fputws (const wchar_t *str, _IO_FILE *fp) +fputws (const wchar_t *str, FILE *fp) { - _IO_size_t len = __wcslen (str); + size_t len = __wcslen (str); int result = EOF; CHECK_FILE (fp, EOF); _IO_acquire_lock (fp); diff --git a/libio/iofputws_u.c b/libio/iofputws_u.c index aa8fb8a484..7d035751c7 100644 --- a/libio/iofputws_u.c +++ b/libio/iofputws_u.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -29,9 +29,9 @@ #include <wchar.h> int -fputws_unlocked (const wchar_t *str, _IO_FILE *fp) +fputws_unlocked (const wchar_t *str, FILE *fp) { - _IO_size_t len = __wcslen (str); + size_t len = __wcslen (str); int result = EOF; CHECK_FILE (fp, EOF); if (_IO_fwide (fp, 1) == 1 diff --git a/libio/iofread.c b/libio/iofread.c index 80ed3e7ebd..5ed05e9dbe 100644 --- a/libio/iofread.c +++ b/libio/iofread.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -26,11 +26,11 @@ #include "libioP.h" -_IO_size_t -_IO_fread (void *buf, _IO_size_t size, _IO_size_t count, _IO_FILE *fp) +size_t +_IO_fread (void *buf, size_t size, size_t count, FILE *fp) { - _IO_size_t bytes_requested = size * count; - _IO_size_t bytes_read; + size_t bytes_requested = size * count; + size_t bytes_read; CHECK_FILE (fp, 0); if (bytes_requested == 0) return 0; @@ -41,7 +41,6 @@ _IO_fread (void *buf, _IO_size_t size, _IO_size_t count, _IO_FILE *fp) } libc_hidden_def (_IO_fread) -#ifdef weak_alias weak_alias (_IO_fread, fread) # ifndef _IO_MTSAFE_IO @@ -49,4 +48,3 @@ strong_alias (_IO_fread, __fread_unlocked) libc_hidden_def (__fread_unlocked) weak_alias (_IO_fread, fread_unlocked) # endif -#endif diff --git a/libio/iofread_u.c b/libio/iofread_u.c index 25bea32a44..2c3baf99f3 100644 --- a/libio/iofread_u.c +++ b/libio/iofread_u.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -29,11 +29,11 @@ #undef fread_unlocked -_IO_size_t -__fread_unlocked (void *buf, _IO_size_t size, _IO_size_t count, _IO_FILE *fp) +size_t +__fread_unlocked (void *buf, size_t size, size_t count, FILE *fp) { - _IO_size_t bytes_requested = size * count; - _IO_size_t bytes_read; + size_t bytes_requested = size * count; + size_t bytes_read; CHECK_FILE (fp, 0); if (bytes_requested == 0) return 0; diff --git a/libio/iofsetpos.c b/libio/iofsetpos.c index ca5104b8cd..da48b27c3b 100644 --- a/libio/iofsetpos.c +++ b/libio/iofsetpos.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -29,17 +29,19 @@ complain about the mismatch when we do the alias below. */ #define _IO_new_fsetpos64 __renamed__IO_new_fsetpos64 #define _IO_fsetpos64 __renamed__IO_fsetpos64 +#define fsetpos64 __renamed_fsetpos64 #include <libioP.h> #undef _IO_new_fsetpos64 #undef _IO_fsetpos64 +#undef fsetpos64 #include <errno.h> #include <shlib-compat.h> int -_IO_new_fsetpos (_IO_FILE *fp, const _IO_fpos_t *posp) +_IO_new_fsetpos (FILE *fp, const __fpos_t *posp) { int result; CHECK_FILE (fp, EOF); @@ -49,10 +51,8 @@ _IO_new_fsetpos (_IO_FILE *fp, const _IO_fpos_t *posp) { /* ANSI explicitly requires setting errno to a positive value on failure. */ -#ifdef EIO if (errno == 0) __set_errno (EIO); -#endif result = EOF; } else diff --git a/libio/iofsetpos64.c b/libio/iofsetpos64.c index adbac8ae39..29da981488 100644 --- a/libio/iofsetpos64.c +++ b/libio/iofsetpos64.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -31,7 +31,7 @@ #ifndef __OFF_T_MATCHES_OFF64_T int -_IO_new_fsetpos64 (_IO_FILE *fp, const _IO_fpos64_t *posp) +_IO_new_fsetpos64 (FILE *fp, const fpos64_t *posp) { int result; CHECK_FILE (fp, EOF); @@ -41,10 +41,8 @@ _IO_new_fsetpos64 (_IO_FILE *fp, const _IO_fpos64_t *posp) { /* ANSI explicitly requires setting errno to a positive value on failure. */ -#ifdef EIO if (errno == 0) __set_errno (EIO); -#endif result = EOF; } else diff --git a/libio/ioftell.c b/libio/ioftell.c index a05693b2f6..571a648788 100644 --- a/libio/ioftell.c +++ b/libio/ioftell.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -30,9 +30,9 @@ /* ANSI explicily requires setting errno to a positive value on failure. */ long int -_IO_ftell (_IO_FILE *fp) +_IO_ftell (FILE *fp) { - _IO_off64_t pos; + off64_t pos; CHECK_FILE (fp, -1L); _IO_acquire_lock (fp); pos = _IO_seekoff_unlocked (fp, 0, _IO_seek_cur, 0); @@ -44,23 +44,17 @@ _IO_ftell (_IO_FILE *fp) _IO_release_lock (fp); if (pos == _IO_pos_BAD) { -#ifdef EIO if (errno == 0) __set_errno (EIO); -#endif return -1L; } - if ((_IO_off64_t) (long int) pos != pos) + if ((off64_t) (long int) pos != pos) { -#ifdef EOVERFLOW __set_errno (EOVERFLOW); -#endif return -1L; } return pos; } libc_hidden_def (_IO_ftell) -#ifdef weak_alias weak_alias (_IO_ftell, ftell) -#endif diff --git a/libio/iofwide.c b/libio/iofwide.c index bc82e8b6c1..d8ec66428e 100644 --- a/libio/iofwide.c +++ b/libio/iofwide.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1999-2016 Free Software Foundation, Inc. +/* Copyright (C) 1999-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -25,22 +25,18 @@ in files containing the exception. */ #include <libioP.h> -#ifdef _LIBC -# include <dlfcn.h> -# include <wchar.h> -#endif +#include <dlfcn.h> +#include <wchar.h> #include <assert.h> #include <stdlib.h> #include <string.h> -#ifdef _LIBC -# include <langinfo.h> -# include <locale/localeinfo.h> -# include <wcsmbs/wcsmbsload.h> -# include <iconv/gconv_int.h> -# include <shlib-compat.h> -# include <sysdep.h> -#endif +#include <langinfo.h> +#include <locale/localeinfo.h> +#include <wcsmbs/wcsmbsload.h> +#include <iconv/gconv_int.h> +#include <shlib-compat.h> +#include <sysdep.h> /* Prototypes of libio's codecvt functions. */ @@ -62,7 +58,7 @@ static enum __codecvt_result do_in (struct _IO_codecvt *codecvt, static int do_encoding (struct _IO_codecvt *codecvt); static int do_length (struct _IO_codecvt *codecvt, __mbstate_t *statep, const char *from_start, - const char *from_end, _IO_size_t max); + const char *from_end, size_t max); static int do_max_length (struct _IO_codecvt *codecvt); static int do_always_noconv (struct _IO_codecvt *codecvt); @@ -85,13 +81,12 @@ const struct _IO_codecvt __libio_codecvt = the orientation first. */ #undef _IO_fwide int -_IO_fwide (_IO_FILE *fp, int mode) +_IO_fwide (FILE *fp, int mode) { /* Normalize the value. */ mode = mode < 0 ? -1 : (mode == 0 ? 0 : 1); -#if defined SHARED && defined _LIBC \ - && 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) && (fp == _IO_stdin || fp == _IO_stdout || fp == _IO_stderr)) /* This is for a stream in the glibc 2.0 format. */ @@ -114,7 +109,6 @@ _IO_fwide (_IO_FILE *fp, int mode) /* Get the character conversion functions based on the currently selected locale for LC_CTYPE. */ -#ifdef _LIBC { /* Clear the state. We start all over again. */ memset (&fp->_wide_data->_IO_state, '\0', sizeof (__mbstate_t)); @@ -145,41 +139,6 @@ _IO_fwide (_IO_FILE *fp, int mode) = __GCONV_IS_LAST | __GCONV_TRANSLIT; cc->__cd_out.__cd.__data[0].__statep = &fp->_wide_data->_IO_state; } -#else -# ifdef _GLIBCPP_USE_WCHAR_T - { - /* Determine internal and external character sets. - - XXX For now we make our life easy: we assume a fixed internal - encoding (as most sane systems have; hi HP/UX!). If somebody - cares about systems which changing internal charsets they - should come up with a solution for the determination of the - currently used internal character set. */ - const char *internal_ccs = _G_INTERNAL_CCS; - const char *external_ccs = NULL; - -# ifdef HAVE_NL_LANGINFO - external_ccs = nl_langinfo (CODESET); -# endif - if (external_ccs == NULL) - external_ccs = "ISO-8859-1"; - - cc->__cd_in = iconv_open (internal_ccs, external_ccs); - if (cc->__cd_in != (iconv_t) -1) - cc->__cd_out = iconv_open (external_ccs, internal_ccs); - - if (cc->__cd_in == (iconv_t) -1 || cc->__cd_out == (iconv_t) -1) - { - if (cc->__cd_in != (iconv_t) -1) - iconv_close (cc->__cd_in); - /* XXX */ - abort (); - } - } -# else -# error "somehow determine this from LC_CTYPE" -# endif -#endif /* From now on use the wide character callback functions. */ _IO_JUMPS_FILE_plus (fp) = fp->_wide_data->_wide_vtable; @@ -200,7 +159,6 @@ do_out (struct _IO_codecvt *codecvt, __mbstate_t *statep, { enum __codecvt_result result; -#ifdef _LIBC struct __gconv_step *gs = codecvt->__cd_out.__cd.__steps; int status; size_t dummy; @@ -240,28 +198,6 @@ do_out (struct _IO_codecvt *codecvt, __mbstate_t *statep, result = __codecvt_error; break; } -#else -# ifdef _GLIBCPP_USE_WCHAR_T - size_t res; - const char *from_start_copy = (const char *) from_start; - size_t from_len = from_end - from_start; - char *to_start_copy = to_start; - size_t to_len = to_end - to_start; - res = iconv (codecvt->__cd_out, &from_start_copy, &from_len, - &to_start_copy, &to_len); - - if (res == 0 || from_len == 0) - result = __codecvt_ok; - else if (to_len < codecvt->__codecvt_do_max_length (codecvt)) - result = __codecvt_partial; - else - result = __codecvt_error; - -# else - /* Decide what to do. */ - result = __codecvt_error; -# endif -#endif return result; } @@ -273,7 +209,6 @@ do_unshift (struct _IO_codecvt *codecvt, __mbstate_t *statep, { enum __codecvt_result result; -#ifdef _LIBC struct __gconv_step *gs = codecvt->__cd_out.__cd.__steps; int status; size_t dummy; @@ -310,25 +245,6 @@ do_unshift (struct _IO_codecvt *codecvt, __mbstate_t *statep, result = __codecvt_error; break; } -#else -# ifdef _GLIBCPP_USE_WCHAR_T - size_t res; - char *to_start_copy = (char *) to_start; - size_t to_len = to_end - to_start; - - res = iconv (codecvt->__cd_out, NULL, NULL, &to_start_copy, &to_len); - - if (res == 0) - result = __codecvt_ok; - else if (to_len < codecvt->__codecvt_do_max_length (codecvt)) - result = __codecvt_partial; - else - result = __codecvt_error; -# else - /* Decide what to do. */ - result = __codecvt_error; -# endif -#endif return result; } @@ -341,7 +257,6 @@ do_in (struct _IO_codecvt *codecvt, __mbstate_t *statep, { enum __codecvt_result result; -#ifdef _LIBC struct __gconv_step *gs = codecvt->__cd_in.__cd.__steps; int status; size_t dummy; @@ -381,30 +296,6 @@ do_in (struct _IO_codecvt *codecvt, __mbstate_t *statep, result = __codecvt_error; break; } -#else -# ifdef _GLIBCPP_USE_WCHAR_T - size_t res; - const char *from_start_copy = (const char *) from_start; - size_t from_len = from_end - from_start; - char *to_start_copy = (char *) from_start; - size_t to_len = to_end - to_start; - - res = iconv (codecvt->__cd_in, &from_start_copy, &from_len, - &to_start_copy, &to_len); - - if (res == 0) - result = __codecvt_ok; - else if (to_len == 0) - result = __codecvt_partial; - else if (from_len < codecvt->__codecvt_do_max_length (codecvt)) - result = __codecvt_partial; - else - result = __codecvt_error; -# else - /* Decide what to do. */ - result = __codecvt_error; -# endif -#endif return result; } @@ -413,7 +304,6 @@ do_in (struct _IO_codecvt *codecvt, __mbstate_t *statep, static int do_encoding (struct _IO_codecvt *codecvt) { -#ifdef _LIBC /* See whether the encoding is stateful. */ if (codecvt->__cd_in.__cd.__steps[0].__stateful) return -1; @@ -425,10 +315,6 @@ do_encoding (struct _IO_codecvt *codecvt) return 0; return codecvt->__cd_in.__cd.__steps[0].__min_needed_from; -#else - /* Worst case scenario. */ - return -1; -#endif } @@ -441,10 +327,9 @@ do_always_noconv (struct _IO_codecvt *codecvt) static int do_length (struct _IO_codecvt *codecvt, __mbstate_t *statep, - const char *from_start, const char *from_end, _IO_size_t max) + const char *from_start, const char *from_end, size_t max) { int result; -#ifdef _LIBC const unsigned char *cp = (const unsigned char *) from_start; wchar_t to_buf[max]; struct __gconv_step *gs = codecvt->__cd_in.__cd.__steps; @@ -466,23 +351,6 @@ do_length (struct _IO_codecvt *codecvt, __mbstate_t *statep, &dummy, 0, 0)); result = cp - (const unsigned char *) from_start; -#else -# ifdef _GLIBCPP_USE_WCHAR_T - const char *from_start_copy = (const char *) from_start; - size_t from_len = from_end - from_start; - wchar_t to_buf[max]; - size_t res; - char *to_start = (char *) to_buf; - - res = iconv (codecvt->__cd_in, &from_start_copy, &from_len, - &to_start, &max); - - result = from_start_copy - (char *) from_start; -# else - /* Decide what to do. */ - result = 0; -# endif -#endif return result; } @@ -491,9 +359,5 @@ do_length (struct _IO_codecvt *codecvt, __mbstate_t *statep, static int do_max_length (struct _IO_codecvt *codecvt) { -#ifdef _LIBC return codecvt->__cd_in.__cd.__steps[0].__max_needed_from; -#else - return MB_CUR_MAX; -#endif } diff --git a/libio/iofwrite.c b/libio/iofwrite.c index 325ff430c4..800341b7da 100644 --- a/libio/iofwrite.c +++ b/libio/iofwrite.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -26,11 +26,11 @@ #include "libioP.h" -_IO_size_t -_IO_fwrite (const void *buf, _IO_size_t size, _IO_size_t count, _IO_FILE *fp) +size_t +_IO_fwrite (const void *buf, size_t size, size_t count, FILE *fp) { - _IO_size_t request = size * count; - _IO_size_t written = 0; + size_t request = size * count; + size_t written = 0; CHECK_FILE (fp, 0); if (request == 0) return 0; @@ -49,7 +49,6 @@ _IO_fwrite (const void *buf, _IO_size_t size, _IO_size_t count, _IO_FILE *fp) } libc_hidden_def (_IO_fwrite) -#ifdef weak_alias # include <stdio.h> weak_alias (_IO_fwrite, fwrite) libc_hidden_weak (fwrite) @@ -57,4 +56,3 @@ libc_hidden_weak (fwrite) weak_alias (_IO_fwrite, fwrite_unlocked) libc_hidden_weak (fwrite_unlocked) # endif -#endif diff --git a/libio/iofwrite_u.c b/libio/iofwrite_u.c index 188321bb08..71ac6266c0 100644 --- a/libio/iofwrite_u.c +++ b/libio/iofwrite_u.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -29,12 +29,11 @@ #undef fwrite_unlocked -_IO_size_t -fwrite_unlocked (const void *buf, _IO_size_t size, _IO_size_t count, - _IO_FILE *fp) +size_t +fwrite_unlocked (const void *buf, size_t size, size_t count, FILE *fp) { - _IO_size_t request = size * count; - _IO_size_t written = 0; + size_t request = size * count; + size_t written = 0; CHECK_FILE (fp, 0); if (request == 0) return 0; diff --git a/libio/iogetdelim.c b/libio/iogetdelim.c index 50fda58e68..4f3ce5ed62 100644 --- a/libio/iogetdelim.c +++ b/libio/iogetdelim.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1994-2016 Free Software Foundation, Inc. +/* Copyright (C) 1994-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -36,16 +36,16 @@ necessary. Returns the number of characters read (not including the null terminator), or -1 on error or EOF. */ -_IO_ssize_t -_IO_getdelim (char **lineptr, _IO_size_t *n, int delimiter, _IO_FILE *fp) +ssize_t +_IO_getdelim (char **lineptr, size_t *n, int delimiter, FILE *fp) { - _IO_ssize_t result; - _IO_ssize_t cur_len = 0; - _IO_ssize_t len; + ssize_t result; + ssize_t cur_len = 0; + ssize_t len; if (lineptr == NULL || n == NULL) { - MAYBE_SET_EINVAL; + __set_errno (EINVAL); return -1; } CHECK_FILE (fp, -1); @@ -80,7 +80,7 @@ _IO_getdelim (char **lineptr, _IO_size_t *n, int delimiter, _IO_FILE *fp) for (;;) { - _IO_size_t needed; + size_t needed; char *t; t = (char *) memchr ((void *) fp->_IO_read_ptr, delimiter, len); if (t != NULL) @@ -123,7 +123,5 @@ unlock_return: return result; } -#ifdef weak_alias weak_alias (_IO_getdelim, __getdelim) weak_alias (_IO_getdelim, getdelim) -#endif diff --git a/libio/iogetline.c b/libio/iogetline.c index 944bad8701..8deeacee08 100644 --- a/libio/iogetline.c +++ b/libio/iogetline.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -27,8 +27,8 @@ #include "libioP.h" #include <string.h> -_IO_size_t -_IO_getline (_IO_FILE *fp, char *buf, _IO_size_t n, int delim, +size_t +_IO_getline (FILE *fp, char *buf, size_t n, int delim, int extract_delim) { return _IO_getline_info (fp, buf, n, delim, extract_delim, (int *) 0); @@ -43,8 +43,8 @@ libc_hidden_def (_IO_getline) If extract_delim < 0, leave delimiter unread. If extract_delim > 0, insert delim in output. */ -_IO_size_t -_IO_getline_info (_IO_FILE *fp, char *buf, _IO_size_t n, int delim, +size_t +_IO_getline_info (FILE *fp, char *buf, size_t n, int delim, int extract_delim, int *eof) { char *ptr = buf; @@ -54,7 +54,7 @@ _IO_getline_info (_IO_FILE *fp, char *buf, _IO_size_t n, int delim, _IO_fwide (fp, -1); while (n != 0) { - _IO_ssize_t len = fp->_IO_read_end - fp->_IO_read_ptr; + ssize_t len = fp->_IO_read_end - fp->_IO_read_ptr; if (len <= 0) { int c = __uflow (fp); @@ -80,12 +80,12 @@ _IO_getline_info (_IO_FILE *fp, char *buf, _IO_size_t n, int delim, else { char *t; - if ((_IO_size_t) len >= n) + if ((size_t) len >= n) len = n; t = (char *) memchr ((void *) fp->_IO_read_ptr, delim, len); if (t != NULL) { - _IO_size_t old_len = ptr-buf; + size_t old_len = ptr-buf; len = t - fp->_IO_read_ptr; if (extract_delim >= 0) { diff --git a/libio/iogets.c b/libio/iogets.c index 4e2c99f843..c2223e6ecc 100644 --- a/libio/iogets.c +++ b/libio/iogets.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -30,7 +30,7 @@ char * _IO_gets (char *buf) { - _IO_size_t count; + size_t count; int ch; char *retval; @@ -48,17 +48,17 @@ _IO_gets (char *buf) /* This is very tricky since a file descriptor may be in the non-blocking mode. The error flag doesn't mean much in this case. We return an error only when there is a new error. */ - int old_error = _IO_stdin->_IO_file_flags & _IO_ERR_SEEN; - _IO_stdin->_IO_file_flags &= ~_IO_ERR_SEEN; + int old_error = _IO_stdin->_flags & _IO_ERR_SEEN; + _IO_stdin->_flags &= ~_IO_ERR_SEEN; buf[0] = (char) ch; count = _IO_getline (_IO_stdin, buf + 1, INT_MAX, '\n', 0) + 1; - if (_IO_stdin->_IO_file_flags & _IO_ERR_SEEN) + if (_IO_stdin->_flags & _IO_ERR_SEEN) { retval = NULL; goto unlock_return; } else - _IO_stdin->_IO_file_flags |= old_error; + _IO_stdin->_flags |= old_error; } buf[count] = 0; retval = buf; @@ -67,10 +67,6 @@ unlock_return: return retval; } -#ifdef weak_alias weak_alias (_IO_gets, gets) -#endif -#ifdef _LIBC link_warning (gets, "the `gets' function is dangerous and should not be used.") -#endif diff --git a/libio/iogetwline.c b/libio/iogetwline.c index b2e11bcec3..d69be5a979 100644 --- a/libio/iogetwline.c +++ b/libio/iogetwline.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -28,12 +28,8 @@ #include <string.h> #include <wchar.h> -#ifdef _LIBC -# define wmemcpy __wmemcpy -#endif - -_IO_size_t -_IO_getwline (_IO_FILE *fp, wchar_t *buf, _IO_size_t n, wint_t delim, +size_t +_IO_getwline (FILE *fp, wchar_t *buf, size_t n, wint_t delim, int extract_delim) { return _IO_getwline_info (fp, buf, n, delim, extract_delim, (wint_t *) 0); @@ -47,8 +43,8 @@ _IO_getwline (_IO_FILE *fp, wchar_t *buf, _IO_size_t n, wint_t delim, If extract_delim < 0, leave delimiter unread. If extract_delim > 0, insert delim in output. */ -_IO_size_t -_IO_getwline_info (_IO_FILE *fp, wchar_t *buf, _IO_size_t n, wint_t delim, +size_t +_IO_getwline_info (FILE *fp, wchar_t *buf, size_t n, wint_t delim, int extract_delim, wint_t *eof) { wchar_t *ptr = buf; @@ -58,8 +54,8 @@ _IO_getwline_info (_IO_FILE *fp, wchar_t *buf, _IO_size_t n, wint_t delim, _IO_fwide (fp, 1); while (n != 0) { - _IO_ssize_t len = (fp->_wide_data->_IO_read_end - - fp->_wide_data->_IO_read_ptr); + ssize_t len = (fp->_wide_data->_IO_read_end + - fp->_wide_data->_IO_read_ptr); if (len <= 0) { wint_t wc = __wuflow (fp); @@ -85,12 +81,12 @@ _IO_getwline_info (_IO_FILE *fp, wchar_t *buf, _IO_size_t n, wint_t delim, else { wchar_t *t; - if ((_IO_size_t) len >= n) + if ((size_t) len >= n) len = n; t = wmemchr ((void *) fp->_wide_data->_IO_read_ptr, delim, len); if (t != NULL) { - _IO_size_t old_len = ptr - buf; + size_t old_len = ptr - buf; len = t - fp->_wide_data->_IO_read_ptr; if (extract_delim >= 0) { @@ -98,12 +94,12 @@ _IO_getwline_info (_IO_FILE *fp, wchar_t *buf, _IO_size_t n, wint_t delim, if (extract_delim > 0) ++len; } - wmemcpy ((void *) ptr, (void *) fp->_wide_data->_IO_read_ptr, - len); + __wmemcpy ((void *) ptr, (void *) fp->_wide_data->_IO_read_ptr, + len); fp->_wide_data->_IO_read_ptr = t; return old_len + len; } - wmemcpy ((void *) ptr, (void *) fp->_wide_data->_IO_read_ptr, len); + __wmemcpy ((void *) ptr, (void *) fp->_wide_data->_IO_read_ptr, len); fp->_wide_data->_IO_read_ptr += len; ptr += len; n -= len; diff --git a/libio/iolibio.h b/libio/iolibio.h index f215fcef01..6c94fe6d62 100644 --- a/libio/iolibio.h +++ b/libio/iolibio.h @@ -1,66 +1,65 @@ -#include <libio.h> +#ifndef _IOLIBIO_H +#define _IOLIBIO_H 1 -/* These emulate stdio functionality, but with a different name - (_IO_ungetc instead of ungetc), and using _IO_FILE instead of FILE. */ +#include <stdio.h> +#include <libio/libio.h> -#ifdef __cplusplus -extern "C" { -#endif +/* Alternative names for many of the stdio.h functions, used + internally and exposed for backward compatibility's sake. */ -extern int _IO_fclose (_IO_FILE*); -extern int _IO_new_fclose (_IO_FILE*); -extern int _IO_old_fclose (_IO_FILE*); -extern _IO_FILE *_IO_fdopen (int, const char*) __THROW; +extern int _IO_fclose (FILE*); +extern int _IO_new_fclose (FILE*); +extern int _IO_old_fclose (FILE*); +extern FILE *_IO_fdopen (int, const char*) __THROW; libc_hidden_proto (_IO_fdopen) -extern _IO_FILE *_IO_old_fdopen (int, const char*) __THROW; -extern _IO_FILE *_IO_new_fdopen (int, const char*) __THROW; -extern int _IO_fflush (_IO_FILE*); +extern FILE *_IO_old_fdopen (int, const char*) __THROW; +extern FILE *_IO_new_fdopen (int, const char*) __THROW; +extern int _IO_fflush (FILE*); libc_hidden_proto (_IO_fflush) -extern int _IO_fgetpos (_IO_FILE*, _IO_fpos_t*); -extern int _IO_fgetpos64 (_IO_FILE*, _IO_fpos64_t*); -extern char* _IO_fgets (char*, int, _IO_FILE*); -extern _IO_FILE *_IO_fopen (const char*, const char*); -extern _IO_FILE *_IO_old_fopen (const char*, const char*); -extern _IO_FILE *_IO_new_fopen (const char*, const char*); -extern _IO_FILE *_IO_fopen64 (const char*, const char*); -extern _IO_FILE *__fopen_internal (const char*, const char*, int); -extern _IO_FILE *__fopen_maybe_mmap (_IO_FILE *) __THROW; -extern int _IO_fprintf (_IO_FILE*, const char*, ...); -extern int _IO_fputs (const char*, _IO_FILE*); +extern int _IO_fgetpos (FILE*, __fpos_t*); +extern int _IO_fgetpos64 (FILE*, __fpos64_t*); +extern char* _IO_fgets (char*, int, FILE*); +extern FILE *_IO_fopen (const char*, const char*); +extern FILE *_IO_old_fopen (const char*, const char*); +extern FILE *_IO_new_fopen (const char*, const char*); +extern FILE *_IO_fopen64 (const char*, const char*); +extern FILE *__fopen_internal (const char*, const char*, int) + attribute_hidden; +extern FILE *__fopen_maybe_mmap (FILE *) __THROW attribute_hidden; +extern int _IO_fprintf (FILE*, const char*, ...); +extern int _IO_fputs (const char*, FILE*); libc_hidden_proto (_IO_fputs) -extern int _IO_fsetpos (_IO_FILE*, const _IO_fpos_t *); -extern int _IO_fsetpos64 (_IO_FILE*, const _IO_fpos64_t *); -extern long int _IO_ftell (_IO_FILE*); +extern int _IO_fsetpos (FILE*, const __fpos_t *); +extern int _IO_fsetpos64 (FILE*, const __fpos64_t *); +extern long int _IO_ftell (FILE*); libc_hidden_proto (_IO_ftell) -extern _IO_size_t _IO_fread (void*, _IO_size_t, _IO_size_t, _IO_FILE*); +extern size_t _IO_fread (void*, size_t, size_t, FILE*); libc_hidden_proto (_IO_fread) -extern _IO_size_t _IO_fwrite (const void*, _IO_size_t, _IO_size_t, _IO_FILE*); +extern size_t _IO_fwrite (const void*, size_t, size_t, FILE*); libc_hidden_proto (_IO_fwrite) extern char* _IO_gets (char*); extern void _IO_perror (const char*) __THROW; extern int _IO_printf (const char*, ...); extern int _IO_puts (const char*); +libc_hidden_proto (_IO_puts) extern int _IO_scanf (const char*, ...); -extern void _IO_setbuffer (_IO_FILE *, char*, _IO_size_t) __THROW; +extern void _IO_setbuffer (FILE *, char*, size_t) __THROW; libc_hidden_proto (_IO_setbuffer) -extern int _IO_setvbuf (_IO_FILE*, char*, int, _IO_size_t) __THROW; +extern int _IO_setvbuf (FILE*, char*, int, size_t) __THROW; libc_hidden_proto (_IO_setvbuf) extern int _IO_sscanf (const char*, const char*, ...) __THROW; extern int _IO_sprintf (char *, const char*, ...) __THROW; -extern int _IO_ungetc (int, _IO_FILE*) __THROW; -extern int _IO_vsscanf (const char *, const char *, _IO_va_list) __THROW; -extern int _IO_vsprintf (char*, const char*, _IO_va_list) __THROW; +extern int _IO_ungetc (int, FILE*) __THROW; +extern int _IO_vsscanf (const char *, const char *, __gnuc_va_list) __THROW; +extern int _IO_vsprintf (char*, const char*, __gnuc_va_list) __THROW; libc_hidden_proto (_IO_vsprintf) -extern int _IO_vswprintf (wchar_t*, _IO_size_t, const wchar_t*, _IO_va_list) +extern int _IO_vswprintf (wchar_t*, size_t, const wchar_t*, __gnuc_va_list) __THROW; struct obstack; -extern int _IO_obstack_vprintf (struct obstack *, const char *, _IO_va_list) +extern int _IO_obstack_vprintf (struct obstack *, const char *, __gnuc_va_list) __THROW; extern int _IO_obstack_printf (struct obstack *, const char *, ...) __THROW; -#ifndef _IO_pos_BAD -#define _IO_pos_BAD ((_IO_off64_t)(-1)) -#endif #define _IO_clearerr(FP) ((FP)->_flags &= ~(_IO_ERR_SEEN|_IO_EOF_SEEN)) #define _IO_fseek(__fp, __offset, __whence) \ (_IO_seekoff_unlocked (__fp, __offset, __whence, _IOS_INPUT|_IOS_OUTPUT) \ @@ -78,18 +77,16 @@ extern int _IO_obstack_printf (struct obstack *, const char *, ...) __THROW; (_IO_file_close_it (FP), \ _IO_file_fopen (FP, FILENAME, MODE, 0)) #define _IO_fileno(FP) ((FP)->_fileno) -extern _IO_FILE* _IO_popen (const char*, const char*) __THROW; -extern _IO_FILE* _IO_new_popen (const char*, const char*) __THROW; -extern _IO_FILE* _IO_old_popen (const char*, const char*) __THROW; -extern int __new_pclose (_IO_FILE *) __THROW; -extern int __old_pclose (_IO_FILE *) __THROW; +extern FILE* _IO_popen (const char*, const char*) __THROW; +extern FILE* _IO_new_popen (const char*, const char*) __THROW; +extern FILE* _IO_old_popen (const char*, const char*) __THROW; +extern int __new_pclose (FILE *) __THROW; +extern int __old_pclose (FILE *) __THROW; #define _IO_pclose _IO_fclose -#define _IO_setbuf(_FP, _BUF) _IO_setbuffer (_FP, _BUF, _IO_BUFSIZ) +#define _IO_setbuf(_FP, _BUF) _IO_setbuffer (_FP, _BUF, BUFSIZ) #define _IO_setlinebuf(_FP) _IO_setvbuf (_FP, NULL, 1, 0) -_IO_FILE *__new_freopen (const char *, const char *, _IO_FILE *) __THROW; -_IO_FILE *__old_freopen (const char *, const char *, _IO_FILE *) __THROW; +FILE *__new_freopen (const char *, const char *, FILE *) __THROW; +FILE *__old_freopen (const char *, const char *, FILE *) __THROW; -#ifdef __cplusplus -} -#endif +#endif /* iolibio.h. */ diff --git a/libio/iopadn.c b/libio/iopadn.c index 0e509df09c..3e6e69aa89 100644 --- a/libio/iopadn.c +++ b/libio/iopadn.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -32,14 +32,14 @@ static char const blanks[PADSIZE] = static char const zeroes[PADSIZE] = {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}; -_IO_ssize_t -_IO_padn (_IO_FILE *fp, int pad, _IO_ssize_t count) +ssize_t +_IO_padn (FILE *fp, int pad, ssize_t count) { char padbuf[PADSIZE]; const char *padptr; int i; - _IO_size_t written = 0; - _IO_size_t w; + size_t written = 0; + size_t w; if (pad == ' ') padptr = blanks; diff --git a/libio/iopopen.c b/libio/iopopen.c index 9ddde23494..2eff45b4c8 100644 --- a/libio/iopopen.c +++ b/libio/iopopen.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Written by Per Bothner <bothner@cygnus.com>. @@ -25,68 +25,22 @@ This exception applies to code released by its copyright holders in files containing the exception. */ -#ifndef _POSIX_SOURCE -# define _POSIX_SOURCE -#endif #include "libioP.h" #include <fcntl.h> #include <signal.h> #include <unistd.h> #include <stdlib.h> -#ifdef _LIBC -# include <shlib-compat.h> -# include <not-cancel.h> -#endif +#include <shlib-compat.h> +#include <not-cancel.h> #include <sys/types.h> #include <sys/wait.h> #include <kernel-features.h> -#ifndef _IO_fork -#ifdef _LIBC -#define _IO_fork __fork -#else -#define _IO_fork fork /* defined in libiberty, if needed */ -#endif -extern _IO_pid_t _IO_fork (void) __THROW; -#endif - -#ifndef _IO_dup2 -#ifdef _LIBC -#define _IO_dup2 __dup2 -#else -#define _IO_dup2 dup2 -#endif -extern int _IO_dup2 (int fd, int fd2) __THROW; -#endif - -#ifndef _IO_waitpid -#ifdef _LIBC -#define _IO_waitpid waitpid_not_cancel -#else -#define _IO_waitpid waitpid -#endif -#endif - -#ifndef _IO_execl -#define _IO_execl execl -#endif -#ifndef _IO__exit -#define _IO__exit _exit -#endif - -#ifndef _IO_close -#ifdef _LIBC -#define _IO_close close_not_cancel -#else -#define _IO_close close -#endif -#endif - struct _IO_proc_file { struct _IO_FILE_plus file; /* Following fields must match those in class procbuf (procbuf.h) */ - _IO_pid_t pid; + pid_t pid; struct _IO_proc_file *next; }; typedef struct _IO_proc_file _IO_proc_file; @@ -105,13 +59,13 @@ unlock (void *not_used) } #endif -_IO_FILE * -_IO_new_proc_open (_IO_FILE *fp, const char *command, const char *mode) +FILE * +_IO_new_proc_open (FILE *fp, const char *command, const char *mode) { int read_or_write; int parent_end, child_end; int pipe_fds[2]; - _IO_pid_t child_pid; + pid_t child_pid; int do_read = 0; int do_write = 0; @@ -140,29 +94,17 @@ _IO_new_proc_open (_IO_FILE *fp, const char *command, const char *mode) if (_IO_file_is_open (fp)) return NULL; -#ifdef O_CLOEXEC -# ifndef __ASSUME_PIPE2 - if (__have_pipe2 >= 0) -# endif - { - int r = __pipe2 (pipe_fds, O_CLOEXEC); -# ifndef __ASSUME_PIPE2 - if (__have_pipe2 == 0) - __have_pipe2 = r != -1 || errno != ENOSYS ? 1 : -1; - - if (__have_pipe2 > 0) -# endif - if (r < 0) - return NULL; - } -#endif -#ifndef __ASSUME_PIPE2 -# ifdef O_CLOEXEC - if (__have_pipe2 < 0) -# endif - if (__pipe (pipe_fds) < 0) - return NULL; -#endif + /* Atomically set the O_CLOEXEC flag for the pipe end used by the + child process (to avoid leaking the file descriptor in case of a + concurrent fork). This is later reverted in the child process. + When popen returns, the parent pipe end can be O_CLOEXEC or not, + depending on the 'e' open mode, but there is only one flag which + controls both descriptors. The parent end is adjusted below, + after creating the child process. (In the child process, the + parent end should be closed on execve, so O_CLOEXEC remains set + there.) */ + if (__pipe2 (pipe_fds, O_CLOEXEC) < 0) + return NULL; if (do_read) { @@ -177,78 +119,46 @@ _IO_new_proc_open (_IO_FILE *fp, const char *command, const char *mode) read_or_write = _IO_NO_READS; } - ((_IO_proc_file *) fp)->pid = child_pid = _IO_fork (); + ((_IO_proc_file *) fp)->pid = child_pid = __fork (); if (child_pid == 0) { int child_std_end = do_read ? 1 : 0; struct _IO_proc_file *p; -#ifndef __ASSUME_PIPE2 - /* If we have pipe2 the descriptor is marked for close-on-exec. */ - _IO_close (parent_end); -#endif if (child_end != child_std_end) - { - _IO_dup2 (child_end, child_std_end); -#ifndef __ASSUME_PIPE2 - _IO_close (child_end); -#endif - } -#ifdef O_CLOEXEC + __dup2 (child_end, child_std_end); else - { - /* The descriptor is already the one we will use. But it must - not be marked close-on-exec. Undo the effects. */ -# ifndef __ASSUME_PIPE2 - if (__have_pipe2 > 0) -# endif - __fcntl (child_end, F_SETFD, 0); - } -#endif + /* The descriptor is already the one we will use. But it must + not be marked close-on-exec. Undo the effects. */ + __fcntl (child_end, F_SETFD, 0); /* POSIX.2: "popen() shall ensure that any streams from previous popen() calls that remain open in the parent process are closed in the new child process." */ for (p = proc_file_chain; p; p = p->next) { - int fd = _IO_fileno ((_IO_FILE *) p); + int fd = _IO_fileno ((FILE *) p); /* If any stream from previous popen() calls has fileno child_std_end, it has been already closed by the dup2 syscall above. */ if (fd != child_std_end) - _IO_close (fd); + __close_nocancel (fd); } - _IO_execl ("/bin/sh", "sh", "-c", command, (char *) 0); - _IO__exit (127); + execl ("/bin/sh", "sh", "-c", command, (char *) 0); + _exit (127); } - _IO_close (child_end); + __close_nocancel (child_end); if (child_pid < 0) { - _IO_close (parent_end); + __close_nocancel (parent_end); return NULL; } - if (do_cloexec) - { -#ifndef __ASSUME_PIPE2 -# ifdef O_CLOEXEC - if (__have_pipe2 < 0) -# endif - __fcntl (parent_end, F_SETFD, FD_CLOEXEC); -#endif - } - else - { -#ifdef O_CLOEXEC - /* Undo the effects of the pipe2 call which set the - close-on-exec flag. */ -# ifndef __ASSUME_PIPE2 - if (__have_pipe2 > 0) -# endif - __fcntl (parent_end, F_SETFD, 0); -#endif - } + if (!do_cloexec) + /* Undo the effects of the pipe2 call which set the + close-on-exec flag. */ + __fcntl (parent_end, F_SETFD, 0); _IO_fileno (fp) = parent_end; @@ -268,7 +178,7 @@ _IO_new_proc_open (_IO_FILE *fp, const char *command, const char *mode) return fp; } -_IO_FILE * +FILE * _IO_new_popen (const char *command, const char *mode) { struct locked_FILE @@ -278,7 +188,7 @@ _IO_new_popen (const char *command, const char *mode) _IO_lock_t lock; #endif } *new_f; - _IO_FILE *fp; + FILE *fp; new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE)); if (new_f == NULL) @@ -287,26 +197,23 @@ _IO_new_popen (const char *command, const char *mode) new_f->fpx.file.file._lock = &new_f->lock; #endif fp = &new_f->fpx.file.file; - _IO_init (fp, 0); + _IO_init_internal (fp, 0); _IO_JUMPS (&new_f->fpx.file) = &_IO_proc_jumps; - _IO_new_file_init (&new_f->fpx.file); -#if !_IO_UNIFIED_JUMPTABLES - new_f->fpx.file.vtable = NULL; -#endif + _IO_new_file_init_internal (&new_f->fpx.file); if (_IO_new_proc_open (fp, command, mode) != NULL) - return (_IO_FILE *) &new_f->fpx.file; + return (FILE *) &new_f->fpx.file; _IO_un_link (&new_f->fpx.file); free (new_f); return NULL; } int -_IO_new_proc_close (_IO_FILE *fp) +_IO_new_proc_close (FILE *fp) { /* This is not name-space clean. FIXME! */ int wstatus; _IO_proc_file **ptr = &proc_file_chain; - _IO_pid_t wait_pid; + pid_t wait_pid; int status = -1; /* Unlink from proc_file_chain. */ @@ -328,7 +235,7 @@ _IO_new_proc_close (_IO_FILE *fp) _IO_cleanup_region_end (0); #endif - if (status < 0 || _IO_close (_IO_fileno(fp)) < 0) + if (status < 0 || __close_nocancel (_IO_fileno(fp)) < 0) return -1; /* POSIX.2 Rationale: "Some historical implementations either block or ignore the signals SIGINT, SIGQUIT, and SIGHUP while waiting @@ -336,7 +243,7 @@ _IO_new_proc_close (_IO_FILE *fp) described in POSIX.2, such implementations are not conforming." */ do { - wait_pid = _IO_waitpid (((_IO_proc_file *) fp)->pid, &wstatus, 0); + wait_pid = __waitpid_nocancel (((_IO_proc_file *) fp)->pid, &wstatus, 0); } while (wait_pid == -1 && errno == EINTR); if (wait_pid == -1) @@ -344,7 +251,7 @@ _IO_new_proc_close (_IO_FILE *fp) return wstatus; } -static const struct _IO_jump_t _IO_proc_jumps = { +static const struct _IO_jump_t _IO_proc_jumps libio_vtable = { JUMP_INIT_DUMMY, JUMP_INIT(finish, _IO_new_file_finish), JUMP_INIT(overflow, _IO_new_file_overflow), diff --git a/libio/ioputs.c b/libio/ioputs.c index bc10e3cef8..c9967c3883 100644 --- a/libio/ioputs.c +++ b/libio/ioputs.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -32,7 +32,7 @@ int _IO_puts (const char *str) { int result = EOF; - _IO_size_t len = strlen (str); + size_t len = strlen (str); _IO_acquire_lock (_IO_stdout); if ((_IO_vtable_offset (_IO_stdout) != 0 @@ -45,6 +45,5 @@ _IO_puts (const char *str) return result; } -#ifdef weak_alias weak_alias (_IO_puts, puts) -#endif +libc_hidden_def (_IO_puts) diff --git a/libio/ioseekoff.c b/libio/ioseekoff.c index 05d90bbeec..773cdc672d 100644 --- a/libio/ioseekoff.c +++ b/libio/ioseekoff.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -27,15 +27,9 @@ #include <stdlib.h> #include <libioP.h> #include <errno.h> -#ifndef errno -extern int errno; -#endif -#ifndef __set_errno -# define __set_errno(Val) errno = (Val) -#endif -_IO_off64_t -_IO_seekoff_unlocked (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode) +off64_t +_IO_seekoff_unlocked (FILE *fp, off64_t offset, int dir, int mode) { if (dir != _IO_seek_cur && dir != _IO_seek_set && dir != _IO_seek_end) { @@ -66,10 +60,10 @@ _IO_seekoff_unlocked (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode) } -_IO_off64_t -_IO_seekoff (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode) +off64_t +_IO_seekoff (FILE *fp, off64_t offset, int dir, int mode) { - _IO_off64_t retval; + off64_t retval; _IO_acquire_lock (fp); retval = _IO_seekoff_unlocked (fp, offset, dir, mode); diff --git a/libio/ioseekpos.c b/libio/ioseekpos.c index 2789b19645..5e8b0ff2cc 100644 --- a/libio/ioseekpos.c +++ b/libio/ioseekpos.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -26,8 +26,8 @@ #include <libioP.h> -_IO_off64_t -_IO_seekpos_unlocked (_IO_FILE *fp, _IO_off64_t pos, int mode) +off64_t +_IO_seekpos_unlocked (FILE *fp, off64_t pos, int mode) { /* If we have a backup buffer, get rid of it, since the __seekoff callback may not know to do the right thing about it. @@ -47,10 +47,10 @@ _IO_seekpos_unlocked (_IO_FILE *fp, _IO_off64_t pos, int mode) } -_IO_off64_t -_IO_seekpos (_IO_FILE *fp, _IO_off64_t pos, int mode) +off64_t +_IO_seekpos (FILE *fp, off64_t pos, int mode) { - _IO_off64_t retval; + off64_t retval; _IO_acquire_lock (fp); retval = _IO_seekpos_unlocked (fp, pos, mode); diff --git a/libio/iosetbuffer.c b/libio/iosetbuffer.c index fcdb125047..0419db3113 100644 --- a/libio/iosetbuffer.c +++ b/libio/iosetbuffer.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -27,7 +27,7 @@ #include "libioP.h" void -_IO_setbuffer (_IO_FILE *fp, char *buf, _IO_size_t size) +_IO_setbuffer (FILE *fp, char *buf, size_t size) { CHECK_FILE (fp, ); _IO_acquire_lock (fp); @@ -42,6 +42,4 @@ _IO_setbuffer (_IO_FILE *fp, char *buf, _IO_size_t size) } libc_hidden_def (_IO_setbuffer) -#ifdef weak_alias weak_alias (_IO_setbuffer, setbuffer) -#endif diff --git a/libio/iosetvbuf.c b/libio/iosetvbuf.c index 75f937f343..a35d866d82 100644 --- a/libio/iosetvbuf.c +++ b/libio/iosetvbuf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -31,7 +31,7 @@ #define _IONBF 2 /* No buffering. */ int -_IO_setvbuf (_IO_FILE *fp, char *buf, int mode, _IO_size_t size) +_IO_setvbuf (FILE *fp, char *buf, int mode, size_t size) { int result; CHECK_FILE (fp, EOF); @@ -39,7 +39,7 @@ _IO_setvbuf (_IO_FILE *fp, char *buf, int mode, _IO_size_t size) switch (mode) { case _IOFBF: - fp->_IO_file_flags &= ~(_IO_LINE_BUF|_IO_UNBUFFERED); + fp->_flags &= ~(_IO_LINE_BUF|_IO_UNBUFFERED); if (buf == NULL) { if (fp->_IO_buf_base == NULL) @@ -62,15 +62,15 @@ _IO_setvbuf (_IO_FILE *fp, char *buf, int mode, _IO_size_t size) result = EOF; goto unlock_return; } - fp->_IO_file_flags &= ~_IO_LINE_BUF; + fp->_flags &= ~_IO_LINE_BUF; } result = 0; goto unlock_return; } break; case _IOLBF: - fp->_IO_file_flags &= ~_IO_UNBUFFERED; - fp->_IO_file_flags |= _IO_LINE_BUF; + fp->_flags &= ~_IO_UNBUFFERED; + fp->_flags |= _IO_LINE_BUF; if (buf == NULL) { result = 0; @@ -78,8 +78,8 @@ _IO_setvbuf (_IO_FILE *fp, char *buf, int mode, _IO_size_t size) } break; case _IONBF: - fp->_IO_file_flags &= ~_IO_LINE_BUF; - fp->_IO_file_flags |= _IO_UNBUFFERED; + fp->_flags &= ~_IO_LINE_BUF; + fp->_flags |= _IO_UNBUFFERED; buf = NULL; size = 0; break; @@ -95,6 +95,4 @@ unlock_return: } libc_hidden_def (_IO_setvbuf) -#ifdef weak_alias weak_alias (_IO_setvbuf, setvbuf) -#endif diff --git a/libio/ioungetc.c b/libio/ioungetc.c index 093af744b4..59ebb06177 100644 --- a/libio/ioungetc.c +++ b/libio/ioungetc.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -27,18 +27,18 @@ #include "libioP.h" int -_IO_ungetc (int c, _IO_FILE *fp) +_IO_ungetc (int c, FILE *fp) { int result; CHECK_FILE (fp, EOF); if (c == EOF) return EOF; + if (!_IO_need_lock (fp)) + return _IO_sputbackc (fp, (unsigned char) c); _IO_acquire_lock (fp); result = _IO_sputbackc (fp, (unsigned char) c); _IO_release_lock (fp); return result; } -#ifdef weak_alias weak_alias (_IO_ungetc, ungetc) -#endif diff --git a/libio/ioungetwc.c b/libio/ioungetwc.c index 7d50288a89..5f882f9436 100644 --- a/libio/ioungetwc.c +++ b/libio/ioungetwc.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -28,7 +28,7 @@ #include <wchar.h> wint_t -ungetwc (wint_t c, _IO_FILE *fp) +ungetwc (wint_t c, FILE *fp) { wint_t result; CHECK_FILE (fp, WEOF); diff --git a/libio/iovdprintf.c b/libio/iovdprintf.c index 8ca55fccae..78a3a2bd15 100644 --- a/libio/iovdprintf.c +++ b/libio/iovdprintf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1995-2016 Free Software Foundation, Inc. +/* Copyright (C) 1995-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -28,7 +28,7 @@ #include <stdio_ext.h> int -_IO_vdprintf (int d, const char *format, _IO_va_list arg) +_IO_vdprintf (int d, const char *format, va_list arg) { struct _IO_FILE_plus tmpfil; struct _IO_wide_data wd; @@ -39,10 +39,7 @@ _IO_vdprintf (int d, const char *format, _IO_va_list arg) #endif _IO_no_init (&tmpfil.file, _IO_USER_LOCK, 0, &wd, &_IO_wfile_jumps); _IO_JUMPS (&tmpfil) = &_IO_file_jumps; - _IO_file_init (&tmpfil); -#if !_IO_UNIFIED_JUMPTABLES - tmpfil.vtable = NULL; -#endif + _IO_new_file_init_internal (&tmpfil); if (_IO_file_attach (&tmpfil.file, d) == NULL) { _IO_un_link (&tmpfil); diff --git a/libio/iovsprintf.c b/libio/iovsprintf.c index 712d178c2a..4def251701 100644 --- a/libio/iovsprintf.c +++ b/libio/iovsprintf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -28,7 +28,7 @@ #include "strfile.h" int -__IO_vsprintf (char *string, const char *format, _IO_va_list args) +__IO_vsprintf (char *string, const char *format, va_list args) { _IO_strfile sf; int ret; diff --git a/libio/iovsscanf.c b/libio/iovsscanf.c index 18d9aaa5c0..e56ab8bd7d 100644 --- a/libio/iovsscanf.c +++ b/libio/iovsscanf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -28,7 +28,7 @@ #include "strfile.h" int -_IO_vsscanf (const char *string, const char *format, _IO_va_list args) +_IO_vsscanf (const char *string, const char *format, va_list args) { int ret; _IO_strfile sf; diff --git a/libio/iovswscanf.c b/libio/iovswscanf.c index ff360696ca..5bd1c88412 100644 --- a/libio/iovswscanf.c +++ b/libio/iovswscanf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -29,7 +29,7 @@ #include <wchar.h> int -__vswscanf (const wchar_t *string, const wchar_t *format, _IO_va_list args) +__vswscanf (const wchar_t *string, const wchar_t *format, va_list args) { int ret; _IO_strfile sf; @@ -40,7 +40,7 @@ __vswscanf (const wchar_t *string, const wchar_t *format, _IO_va_list args) _IO_no_init (&sf._sbf._f, _IO_USER_LOCK, 0, &wd, &_IO_wstr_jumps); _IO_fwide (&sf._sbf._f, 1); _IO_wstr_init_static (&sf._sbf._f, (wchar_t *)string, 0, NULL); - ret = _IO_vfwscanf ((_IO_FILE *) &sf._sbf, format, args, NULL); + ret = _IO_vfwscanf ((FILE *) &sf._sbf, format, args, NULL); return ret; } libc_hidden_def (__vswscanf) diff --git a/libio/iowpadn.c b/libio/iowpadn.c index 9881205436..47f74f20c4 100644 --- a/libio/iowpadn.c +++ b/libio/iowpadn.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -38,14 +38,14 @@ static wchar_t const zeroes[PADSIZE] = L'0', L'0', L'0', L'0', L'0', L'0', L'0', L'0' }; -_IO_ssize_t -_IO_wpadn (_IO_FILE *fp, wint_t pad, _IO_ssize_t count) +ssize_t +_IO_wpadn (FILE *fp, wint_t pad, ssize_t count) { wchar_t padbuf[PADSIZE]; const wchar_t *padptr; int i; - _IO_size_t written = 0; - _IO_size_t w; + size_t written = 0; + size_t w; if (pad == L' ') padptr = blanks; diff --git a/libio/libc_fatal.c b/libio/libc_fatal.c index bb0b5bb85e..a3ce928f97 100644 --- a/libio/libc_fatal.c +++ b/libio/libc_fatal.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/libio/libio.h b/libio/libio.h index efd09f120b..00f9169613 100644 --- a/libio/libio.h +++ b/libio/libio.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-2016 Free Software Foundation, Inc. +/* Copyright (C) 1991-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Written by Per Bothner <bothner@cygnus.com>. @@ -25,151 +25,97 @@ This exception applies to code released by its copyright holders in files containing the exception. */ -#ifndef _IO_STDIO_H -#define _IO_STDIO_H - -#include <_G_config.h> -/* ALL of these should be defined in _G_config.h */ -#define _IO_fpos_t _G_fpos_t -#define _IO_fpos64_t _G_fpos64_t -#define _IO_size_t size_t -#define _IO_ssize_t __ssize_t -#define _IO_off_t __off_t -#define _IO_off64_t __off64_t -#define _IO_pid_t __pid_t -#define _IO_uid_t __uid_t -#define _IO_iconv_t _G_iconv_t -#define _IO_HAVE_ST_BLKSIZE _G_HAVE_ST_BLKSIZE -#define _IO_BUFSIZ _G_BUFSIZ -#define _IO_va_list _G_va_list -#define _IO_wint_t wint_t - -/* This define avoids name pollution if we're using GNU stdarg.h */ -#define __need___va_list -#include <stdarg.h> -#ifdef __GNUC_VA_LIST -# undef _IO_va_list -# define _IO_va_list __gnuc_va_list -#endif /* __GNUC_VA_LIST */ - -#ifndef __P -# include <sys/cdefs.h> -#endif /*!__P*/ - -#define _IO_UNIFIED_JUMPTABLES 1 - -#ifndef EOF -# define EOF (-1) +#ifndef _LIBIO_H +#define _LIBIO_H 1 + +#ifndef _LIBC +# error "libio.h should only be included when building glibc itself" #endif -#ifndef NULL -# if defined __GNUG__ && \ - (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)) -# define NULL (__null) -# else -# if !defined(__cplusplus) -# define NULL ((void*)0) -# else -# define NULL (0) -# endif -# endif +#ifdef _ISOMAC +# error "libio.h should not be included under _ISOMAC" +#endif + +#include <stdio.h> + +#if defined _IO_MTSAFE_IO && !defined _IO_lock_t_defined +# error "Someone forgot to include stdio-lock.h" #endif +#define __need_wchar_t +#include <stddef.h> + +#include <bits/types/__mbstate_t.h> +#include <bits/types/wint_t.h> +#include <gconv.h> + +typedef union +{ + struct __gconv_info __cd; + struct + { + struct __gconv_info __cd; + struct __gconv_step_data __data; + } __combined; +} _IO_iconv_t; + +#include <shlib-compat.h> + +/* _IO_seekoff modes */ #define _IOS_INPUT 1 #define _IOS_OUTPUT 2 -#define _IOS_ATEND 4 -#define _IOS_APPEND 8 -#define _IOS_TRUNC 16 -#define _IOS_NOCREATE 32 -#define _IOS_NOREPLACE 64 -#define _IOS_BIN 128 - -/* Magic numbers and bits for the _flags field. - The magic numbers use the high-order bits of _flags; - the remaining bits are available for variable flags. - Note: The magic numbers must all be negative if stdio - emulation is desired. */ - -#define _IO_MAGIC 0xFBAD0000 /* Magic number */ -#define _OLD_STDIO_MAGIC 0xFABC0000 /* Emulate old stdio. */ -#define _IO_MAGIC_MASK 0xFFFF0000 -#define _IO_USER_BUF 1 /* User owns buffer; don't delete it on close. */ -#define _IO_UNBUFFERED 2 -#define _IO_NO_READS 4 /* Reading not allowed */ -#define _IO_NO_WRITES 8 /* Writing not allowd */ -#define _IO_EOF_SEEN 0x10 -#define _IO_ERR_SEEN 0x20 -#define _IO_DELETE_DONT_CLOSE 0x40 /* Don't call close(_fileno) on cleanup. */ -#define _IO_LINKED 0x80 /* Set if linked (using _chain) to streambuf::_list_all.*/ -#define _IO_IN_BACKUP 0x100 -#define _IO_LINE_BUF 0x200 -#define _IO_TIED_PUT_GET 0x400 /* Set if put and get pointer logicly tied. */ -#define _IO_CURRENTLY_PUTTING 0x800 -#define _IO_IS_APPENDING 0x1000 -#define _IO_IS_FILEBUF 0x2000 -#define _IO_BAD_SEEN 0x4000 -#define _IO_USER_LOCK 0x8000 +/* Magic number and bits for the _flags field. The magic number is + mostly vestigial, but preserved for compatibility. It occupies the + high 16 bits of _flags; the low 16 bits are actual flag bits. */ + +#define _IO_MAGIC 0xFBAD0000 /* Magic number */ +#define _IO_MAGIC_MASK 0xFFFF0000 +#define _IO_USER_BUF 0x0001 /* Don't deallocate buffer on close. */ +#define _IO_UNBUFFERED 0x0002 +#define _IO_NO_READS 0x0004 /* Reading not allowed. */ +#define _IO_NO_WRITES 0x0008 /* Writing not allowed. */ +#define _IO_EOF_SEEN 0x0010 +#define _IO_ERR_SEEN 0x0020 +#define _IO_DELETE_DONT_CLOSE 0x0040 /* Don't call close(_fileno) on close. */ +#define _IO_LINKED 0x0080 /* In the list of all open files. */ +#define _IO_IN_BACKUP 0x0100 +#define _IO_LINE_BUF 0x0200 +#define _IO_TIED_PUT_GET 0x0400 /* Put and get pointer move in unison. */ +#define _IO_CURRENTLY_PUTTING 0x0800 +#define _IO_IS_APPENDING 0x1000 +#define _IO_IS_FILEBUF 0x2000 + /* 0x4000 No longer used, reserved for compat. */ +#define _IO_USER_LOCK 0x8000 + +/* Bits for the _flags2 field. */ #define _IO_FLAGS2_MMAP 1 #define _IO_FLAGS2_NOTCANCEL 2 -#ifdef _LIBC -# define _IO_FLAGS2_FORTIFY 4 -#endif +#define _IO_FLAGS2_FORTIFY 4 #define _IO_FLAGS2_USER_WBUF 8 -#ifdef _LIBC -# define _IO_FLAGS2_SCANF_STD 16 -# define _IO_FLAGS2_NOCLOSE 32 -# define _IO_FLAGS2_CLOEXEC 64 -#endif +#define _IO_FLAGS2_SCANF_STD 16 +#define _IO_FLAGS2_NOCLOSE 32 +#define _IO_FLAGS2_CLOEXEC 64 +#define _IO_FLAGS2_NEED_LOCK 128 -/* These are "formatting flags" matching the iostream fmtflags enum values. */ -#define _IO_SKIPWS 01 -#define _IO_LEFT 02 -#define _IO_RIGHT 04 -#define _IO_INTERNAL 010 -#define _IO_DEC 020 -#define _IO_OCT 040 -#define _IO_HEX 0100 -#define _IO_SHOWBASE 0200 -#define _IO_SHOWPOINT 0400 -#define _IO_UPPERCASE 01000 -#define _IO_SHOWPOS 02000 -#define _IO_SCIENTIFIC 04000 -#define _IO_FIXED 010000 -#define _IO_UNITBUF 020000 -#define _IO_STDIO 040000 -#define _IO_DONT_CLOSE 0100000 -#define _IO_BOOLALPHA 0200000 - - -struct _IO_jump_t; struct _IO_FILE; - -/* Handle lock. */ -#ifdef _IO_MTSAFE_IO -/* _IO_lock_t defined in internal headers during the glibc build. */ -#else -typedef void _IO_lock_t; -#endif +/* _IO_pos_BAD is an off64_t value indicating error, unknown, or EOF. */ +#define _IO_pos_BAD ((off64_t) -1) +/* _IO_pos_adjust adjusts an off64_t by some number of bytes. */ +#define _IO_pos_adjust(pos, delta) ((pos) += (delta)) -/* A streammarker remembers a position in a buffer. */ +/* _IO_pos_0 is an off64_t value indicating beginning of file. */ +#define _IO_pos_0 ((off64_t) 0) +struct _IO_jump_t; + +/* A streammarker remembers a position in a buffer. */ struct _IO_marker { struct _IO_marker *_next; - struct _IO_FILE *_sbuf; + FILE *_sbuf; /* If _pos >= 0 it points to _buf->Gbase()+_pos. FIXME comment */ /* if _pos < 0, it points to _buf->eBptr()+_pos. FIXME comment */ int _pos; -#if 0 - void set_streampos(streampos sp) { _spos = sp; } - void set_offset(int offset) { _pos = offset; _spos = (streampos)(-2); } - public: - streammarker(streambuf *sb); - ~streammarker(); - int saving() { return _spos == -2; } - int delta(streammarker&); - int delta(); -#endif }; /* This is the structure from the libstdc++ codecvt class. */ @@ -181,7 +127,6 @@ enum __codecvt_result __codecvt_noconv }; -#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T /* The order of the elements in the following struct must match the order of the virtual functions in the libstdc++ codecvt class. */ struct _IO_codecvt @@ -204,7 +149,7 @@ struct _IO_codecvt int (*__codecvt_do_encoding) (struct _IO_codecvt *); int (*__codecvt_do_always_noconv) (struct _IO_codecvt *); int (*__codecvt_do_length) (struct _IO_codecvt *, __mbstate_t *, - const char *, const char *, _IO_size_t); + const char *, const char *, size_t); int (*__codecvt_do_max_length) (struct _IO_codecvt *); _IO_iconv_t __cd_in; @@ -236,260 +181,108 @@ struct _IO_wide_data const struct _IO_jump_t *_wide_vtable; }; -#endif - -struct _IO_FILE { - int _flags; /* High-order word is _IO_MAGIC; rest is flags. */ -#define _IO_file_flags _flags - - /* The following pointers correspond to the C++ streambuf protocol. */ - /* Note: Tk uses the _IO_read_ptr and _IO_read_end fields directly. */ - char* _IO_read_ptr; /* Current read pointer */ - char* _IO_read_end; /* End of get area. */ - char* _IO_read_base; /* Start of putback+get area. */ - char* _IO_write_base; /* Start of put area. */ - char* _IO_write_ptr; /* Current put pointer. */ - char* _IO_write_end; /* End of put area. */ - char* _IO_buf_base; /* Start of reserve area. */ - char* _IO_buf_end; /* End of reserve area. */ - /* The following fields are used to support backing up and undo. */ - char *_IO_save_base; /* Pointer to start of non-current get area. */ - char *_IO_backup_base; /* Pointer to first valid character of backup area */ - char *_IO_save_end; /* Pointer to end of non-current get area. */ - - struct _IO_marker *_markers; - - struct _IO_FILE *_chain; - - int _fileno; -#if 0 - int _blksize; -#else - int _flags2; -#endif - _IO_off_t _old_offset; /* This used to be _offset but it's too small. */ - -#define __HAVE_COLUMN /* temporary */ - /* 1+column number of pbase(); 0 is unknown. */ - unsigned short _cur_column; - signed char _vtable_offset; - char _shortbuf[1]; - - /* char* _save_gptr; char* _save_egptr; */ - - _IO_lock_t *_lock; -#ifdef _IO_USE_OLD_IO_FILE -}; - -struct _IO_FILE_complete -{ - struct _IO_FILE _file; -#endif -#if defined _G_IO_IO_FILE_VERSION && _G_IO_IO_FILE_VERSION == 0x20001 - _IO_off64_t _offset; -# if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T - /* Wide character stream stuff. */ - struct _IO_codecvt *_codecvt; - struct _IO_wide_data *_wide_data; - struct _IO_FILE *_freeres_list; - void *_freeres_buf; -# else - void *__pad1; - void *__pad2; - void *__pad3; - void *__pad4; -# endif - size_t __pad5; - int _mode; - /* Make sure we don't get into trouble again. */ - char _unused2[15 * sizeof (int) - 4 * sizeof (void *) - sizeof (size_t)]; -#endif -}; - -#ifndef __cplusplus -typedef struct _IO_FILE _IO_FILE; -#endif 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_; -#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 attribute_hidden; -extern _IO_FILE *_IO_stdout attribute_hidden; -extern _IO_FILE *_IO_stderr attribute_hidden; -#endif - - -/* Functions to do I/O and file management for a stream. */ - -/* Read NBYTES bytes from COOKIE into a buffer pointed to by BUF. - Return number of bytes read. */ -typedef __ssize_t __io_read_fn (void *__cookie, char *__buf, size_t __nbytes); - -/* Write N bytes pointed to by BUF to COOKIE. Write all N bytes - unless there is an error. Return number of bytes written. If - there is an error, return 0 and do not write anything. If the file - has been opened for append (__mode.__append set), then set the file - pointer to the end of the file and then do the write; if not, just - write at the current file pointer. */ -typedef __ssize_t __io_write_fn (void *__cookie, const char *__buf, - size_t __n); - -/* Move COOKIE's file position to *POS bytes from the - beginning of the file (if W is SEEK_SET), - the current position (if W is SEEK_CUR), - or the end of the file (if W is SEEK_END). - Set *POS to the new file position. - Returns zero if successful, nonzero if not. */ -typedef int __io_seek_fn (void *__cookie, _IO_off64_t *__pos, int __w); - -/* Close COOKIE. */ -typedef int __io_close_fn (void *__cookie); - - -#ifdef _GNU_SOURCE -/* User-visible names for the above. */ -typedef __io_read_fn cookie_read_function_t; -typedef __io_write_fn cookie_write_function_t; -typedef __io_seek_fn cookie_seek_function_t; -typedef __io_close_fn cookie_close_function_t; - -/* The structure with the cookie function pointers. */ -typedef struct -{ - __io_read_fn *read; /* Read bytes. */ - __io_write_fn *write; /* Write bytes. */ - __io_seek_fn *seek; /* Seek/tell file position. */ - __io_close_fn *close; /* Close file. */ -} _IO_cookie_io_functions_t; -typedef _IO_cookie_io_functions_t cookie_io_functions_t; +extern FILE *_IO_stdin attribute_hidden; +extern FILE *_IO_stdout attribute_hidden; +extern FILE *_IO_stderr attribute_hidden; struct _IO_cookie_file; /* Initialize one of those. */ extern void _IO_cookie_init (struct _IO_cookie_file *__cfile, int __read_write, - void *__cookie, _IO_cookie_io_functions_t __fns); -#endif + void *__cookie, cookie_io_functions_t __fns); + +extern int __underflow (FILE *); +extern wint_t __wunderflow (FILE *); +extern wint_t __wuflow (FILE *); +extern wint_t __woverflow (FILE *, wint_t); + +#define _IO_getc_unlocked(_fp) __getc_unlocked_body (_fp) +#define _IO_peekc_unlocked(_fp) \ + (__glibc_unlikely ((_fp)->_IO_read_ptr >= (_fp)->_IO_read_end) \ + && __underflow (_fp) == EOF \ + ? EOF \ + : *(unsigned char *) (_fp)->_IO_read_ptr) +#define _IO_putc_unlocked(_ch, _fp) __putc_unlocked_body (_ch, _fp) + +# define _IO_getwc_unlocked(_fp) \ + (__glibc_unlikely ((_fp)->_wide_data == NULL \ + || ((_fp)->_wide_data->_IO_read_ptr \ + >= (_fp)->_wide_data->_IO_read_end)) \ + ? __wuflow (_fp) : (wint_t) *(_fp)->_wide_data->_IO_read_ptr++) +# define _IO_putwc_unlocked(_wch, _fp) \ + (__glibc_unlikely ((_fp)->_wide_data == NULL \ + || ((_fp)->_wide_data->_IO_write_ptr \ + >= (_fp)->_wide_data->_IO_write_end)) \ + ? __woverflow (_fp, _wch) \ + : (wint_t) (*(_fp)->_wide_data->_IO_write_ptr++ = (_wch))) +#define _IO_feof_unlocked(_fp) __feof_unlocked_body (_fp) +#define _IO_ferror_unlocked(_fp) __ferror_unlocked_body (_fp) -#ifdef __cplusplus -extern "C" { -#endif +extern int _IO_getc (FILE *__fp); +extern int _IO_putc (int __c, FILE *__fp); +extern int _IO_feof (FILE *__fp) __THROW; +extern int _IO_ferror (FILE *__fp) __THROW; -extern int __underflow (_IO_FILE *); -extern int __uflow (_IO_FILE *); -extern int __overflow (_IO_FILE *, int); -#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T -extern _IO_wint_t __wunderflow (_IO_FILE *); -extern _IO_wint_t __wuflow (_IO_FILE *); -extern _IO_wint_t __woverflow (_IO_FILE *, _IO_wint_t); -#endif +extern int _IO_peekc_locked (FILE *__fp); -#if __GNUC__ >= 3 -# define _IO_BE(expr, res) __builtin_expect ((expr), res) -#else -# define _IO_BE(expr, res) (expr) -#endif +/* This one is for Emacs. */ +#define _IO_PENDING_OUTPUT_COUNT(_fp) \ + ((_fp)->_IO_write_ptr - (_fp)->_IO_write_base) -#define _IO_getc_unlocked(_fp) \ - (_IO_BE ((_fp)->_IO_read_ptr >= (_fp)->_IO_read_end, 0) \ - ? __uflow (_fp) : *(unsigned char *) (_fp)->_IO_read_ptr++) -#define _IO_peekc_unlocked(_fp) \ - (_IO_BE ((_fp)->_IO_read_ptr >= (_fp)->_IO_read_end, 0) \ - && __underflow (_fp) == EOF ? EOF \ - : *(unsigned char *) (_fp)->_IO_read_ptr) -#define _IO_putc_unlocked(_ch, _fp) \ - (_IO_BE ((_fp)->_IO_write_ptr >= (_fp)->_IO_write_end, 0) \ - ? __overflow (_fp, (unsigned char) (_ch)) \ - : (unsigned char) (*(_fp)->_IO_write_ptr++ = (_ch))) - -#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T -# define _IO_getwc_unlocked(_fp) \ - (_IO_BE ((_fp)->_wide_data == NULL \ - || ((_fp)->_wide_data->_IO_read_ptr \ - >= (_fp)->_wide_data->_IO_read_end), 0) \ - ? __wuflow (_fp) : (_IO_wint_t) *(_fp)->_wide_data->_IO_read_ptr++) -# define _IO_putwc_unlocked(_wch, _fp) \ - (_IO_BE ((_fp)->_wide_data == NULL \ - || ((_fp)->_wide_data->_IO_write_ptr \ - >= (_fp)->_wide_data->_IO_write_end), 0) \ - ? __woverflow (_fp, _wch) \ - : (_IO_wint_t) (*(_fp)->_wide_data->_IO_write_ptr++ = (_wch))) +extern void _IO_flockfile (FILE *) __THROW; +extern void _IO_funlockfile (FILE *) __THROW; +extern int _IO_ftrylockfile (FILE *) __THROW; + +#define _IO_peekc(_fp) _IO_peekc_unlocked (_fp) +#define _IO_flockfile(_fp) /**/ +#define _IO_funlockfile(_fp) /**/ +#define _IO_ftrylockfile(_fp) /**/ +#ifndef _IO_cleanup_region_start +#define _IO_cleanup_region_start(_fct, _fp) /**/ +#endif +#ifndef _IO_cleanup_region_end +#define _IO_cleanup_region_end(_Doit) /**/ #endif -#define _IO_feof_unlocked(__fp) (((__fp)->_flags & _IO_EOF_SEEN) != 0) -#define _IO_ferror_unlocked(__fp) (((__fp)->_flags & _IO_ERR_SEEN) != 0) +#define _IO_need_lock(_fp) \ + (((_fp)->_flags2 & _IO_FLAGS2_NEED_LOCK) != 0) -extern int _IO_getc (_IO_FILE *__fp); -extern int _IO_putc (int __c, _IO_FILE *__fp); -extern int _IO_feof (_IO_FILE *__fp) __THROW; -extern int _IO_ferror (_IO_FILE *__fp) __THROW; +extern int _IO_vfscanf (FILE * __restrict, const char * __restrict, + __gnuc_va_list, int *__restrict); +extern int _IO_vfprintf (FILE *__restrict, const char *__restrict, + __gnuc_va_list); +extern __ssize_t _IO_padn (FILE *, int, __ssize_t); +extern size_t _IO_sgetn (FILE *, void *, size_t); -extern int _IO_peekc_locked (_IO_FILE *__fp); +extern off64_t _IO_seekoff (FILE *, off64_t, int, int); +extern off64_t _IO_seekpos (FILE *, off64_t, int); -/* This one is for Emacs. */ -#define _IO_PENDING_OUTPUT_COUNT(_fp) \ - ((_fp)->_IO_write_ptr - (_fp)->_IO_write_base) +extern void _IO_free_backup_area (FILE *) __THROW; -extern void _IO_flockfile (_IO_FILE *) __THROW; -extern void _IO_funlockfile (_IO_FILE *) __THROW; -extern int _IO_ftrylockfile (_IO_FILE *) __THROW; -#ifdef _IO_MTSAFE_IO -# define _IO_peekc(_fp) _IO_peekc_locked (_fp) -# define _IO_flockfile(_fp) \ - if (((_fp)->_flags & _IO_USER_LOCK) == 0) _IO_flockfile (_fp) -# define _IO_funlockfile(_fp) \ - if (((_fp)->_flags & _IO_USER_LOCK) == 0) _IO_funlockfile (_fp) -#else -# define _IO_peekc(_fp) _IO_peekc_unlocked (_fp) -# define _IO_flockfile(_fp) /**/ -# define _IO_funlockfile(_fp) /**/ -# define _IO_ftrylockfile(_fp) /**/ -# define _IO_cleanup_region_start(_fct, _fp) /**/ -# define _IO_cleanup_region_end(_Doit) /**/ -#endif /* !_IO_MTSAFE_IO */ - -extern int _IO_vfscanf (_IO_FILE * __restrict, const char * __restrict, - _IO_va_list, int *__restrict); -extern int _IO_vfprintf (_IO_FILE *__restrict, const char *__restrict, - _IO_va_list); -extern _IO_ssize_t _IO_padn (_IO_FILE *, int, _IO_ssize_t); -extern _IO_size_t _IO_sgetn (_IO_FILE *, void *, _IO_size_t); - -extern _IO_off64_t _IO_seekoff (_IO_FILE *, _IO_off64_t, int, int); -extern _IO_off64_t _IO_seekpos (_IO_FILE *, _IO_off64_t, int); - -extern void _IO_free_backup_area (_IO_FILE *) __THROW; - -#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T -extern _IO_wint_t _IO_getwc (_IO_FILE *__fp); -extern _IO_wint_t _IO_putwc (wchar_t __wc, _IO_FILE *__fp); -extern int _IO_fwide (_IO_FILE *__fp, int __mode) __THROW; -# if __GNUC__ >= 2 -/* While compiling glibc we have to handle compatibility with very old - versions. */ -# if defined _LIBC && defined SHARED -# include <shlib-compat.h> -# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) -# define _IO_fwide_maybe_incompatible \ - (__builtin_expect (&_IO_stdin_used == NULL, 0)) +extern wint_t _IO_getwc (FILE *__fp); +extern wint_t _IO_putwc (wchar_t __wc, FILE *__fp); +extern int _IO_fwide (FILE *__fp, int __mode) __THROW; + +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) +# define _IO_fwide_maybe_incompatible \ + (__glibc_unlikely (&_IO_stdin_used == NULL)) extern const int _IO_stdin_used; weak_extern (_IO_stdin_used); -# endif -# endif -# ifndef _IO_fwide_maybe_incompatible -# define _IO_fwide_maybe_incompatible (0) -# endif +#else +# define _IO_fwide_maybe_incompatible (0) +#endif + /* A special optimized version of the function above. It optimizes the case of initializing an unoriented byte stream. */ -# define _IO_fwide(__fp, __mode) \ +#define _IO_fwide(__fp, __mode) \ ({ int __result = (__mode); \ if (__result < 0 && ! _IO_fwide_maybe_incompatible) \ { \ @@ -503,22 +296,51 @@ weak_extern (_IO_stdin_used); else \ __result = _IO_fwide (__fp, __result); \ __result; }) -# endif -extern int _IO_vfwscanf (_IO_FILE * __restrict, const wchar_t * __restrict, - _IO_va_list, int *__restrict); -extern int _IO_vfwprintf (_IO_FILE *__restrict, const wchar_t *__restrict, - _IO_va_list); -extern _IO_ssize_t _IO_wpadn (_IO_FILE *, wint_t, _IO_ssize_t); -extern void _IO_free_wbackup_area (_IO_FILE *) __THROW; -#endif +extern int _IO_vfwscanf (FILE * __restrict, const wchar_t * __restrict, + __gnuc_va_list, int *__restrict); +extern int _IO_vfwprintf (FILE *__restrict, const wchar_t *__restrict, + __gnuc_va_list); +extern __ssize_t _IO_wpadn (FILE *, wint_t, __ssize_t); +extern void _IO_free_wbackup_area (FILE *) __THROW; #ifdef __LDBL_COMPAT -# include <bits/libio-ldbl.h> +__LDBL_REDIR_DECL (_IO_vfscanf) +__LDBL_REDIR_DECL (_IO_vfprintf) #endif -#ifdef __cplusplus -} -#endif +libc_hidden_proto (__overflow) +libc_hidden_proto (__underflow) +libc_hidden_proto (__uflow) +libc_hidden_proto (__woverflow) +libc_hidden_proto (__wunderflow) +libc_hidden_proto (__wuflow) +libc_hidden_proto (_IO_free_backup_area) +libc_hidden_proto (_IO_free_wbackup_area) +libc_hidden_proto (_IO_padn) +libc_hidden_proto (_IO_putc) +libc_hidden_proto (_IO_sgetn) +libc_hidden_proto (_IO_vfprintf) +libc_hidden_proto (_IO_vfscanf) + +#ifdef _IO_MTSAFE_IO +# undef _IO_peekc +# undef _IO_flockfile +# undef _IO_funlockfile +# undef _IO_ftrylockfile + +# define _IO_peekc(_fp) _IO_peekc_locked (_fp) +# if _IO_lock_inexpensive +# define _IO_flockfile(_fp) \ + if (((_fp)->_flags & _IO_USER_LOCK) == 0) _IO_lock_lock (*(_fp)->_lock) +# define _IO_funlockfile(_fp) \ + if (((_fp)->_flags & _IO_USER_LOCK) == 0) _IO_lock_unlock (*(_fp)->_lock) +# else +# define _IO_flockfile(_fp) \ + if (((_fp)->_flags & _IO_USER_LOCK) == 0) _IO_flockfile (_fp) +# define _IO_funlockfile(_fp) \ + if (((_fp)->_flags & _IO_USER_LOCK) == 0) _IO_funlockfile (_fp) +# endif +#endif /* _IO_MTSAFE_IO */ -#endif /* _IO_STDIO_H */ +#endif /* _LIBIO_H */ diff --git a/libio/libioP.h b/libio/libioP.h index 8706af2d90..df2633d858 100644 --- a/libio/libioP.h +++ b/libio/libioP.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -32,37 +32,25 @@ FIXME: All of the C++ cruft eventually needs to go away. */ +#ifndef _LIBIOP_H +#define _LIBIOP_H 1 + #include <stddef.h> #include <errno.h> -#ifndef __set_errno -# define __set_errno(Val) errno = (Val) -#endif -#if defined __GLIBC__ && __GLIBC__ >= 2 -# include <libc-lock.h> -#else -/*# include <comthread.h>*/ -#endif +#include <libc-lock.h> #include <math_ldbl_opt.h> +#include <stdio.h> +#include <libio/libio.h> #include "iolibio.h" -/* Control of exported symbols. Used in glibc. By default we don't - do anything. */ -#ifndef libc_hidden_proto -# define libc_hidden_proto(name) -#endif -#ifndef libc_hidden_def -# define libc_hidden_def(name) -#endif -#ifndef libc_hidden_weak -# define libc_hidden_weak(name) -#endif +#include <shlib-compat.h> -#ifdef __cplusplus -extern "C" { -#endif +/* For historical reasons this is the name of the sysdeps header that + adjusts the libio configuration. */ +#include <_G_config.h> #define _IO_seek_set 0 #define _IO_seek_cur 1 @@ -78,7 +66,7 @@ extern "C" { * with the _IO_JUMPS macro. The jump table has an eccentric format, * so as to be compatible with the layout of a C++ virtual function table. * (as implemented by g++). When a pointer to a streambuf object is - * coerced to an (_IO_FILE*), then _IO_JUMPS on the result just + * coerced to an (FILE*), then _IO_JUMPS on the result just * happens to point to the virtual function table of the streambuf. * Thus the _IO_JUMPS function table used for C stdio/libio does * double duty as the virtual function table for C++ streambuf. @@ -89,18 +77,10 @@ extern "C" { * object being acted on (i.e. the 'this' parameter). */ -#ifdef _LIBC -# include <shlib-compat.h> -# if !SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) - /* Setting this macro disables the use of the _vtable_offset - bias in _IO_JUMPS_FUNCS, below. That is only needed if we - want to support old binaries (see oldfileops.c). */ -# define _G_IO_NO_BACKWARD_COMPAT 1 -# endif -#endif - -#if (!defined _IO_USE_OLD_IO_FILE \ - && (!defined _G_IO_NO_BACKWARD_COMPAT || _G_IO_NO_BACKWARD_COMPAT == 0)) +/* Setting this macro to 1 enables the use of the _vtable_offset bias + in _IO_JUMPS_FUNCS, below. This is only needed for new-format + _IO_FILE in libc that must support old binaries (see oldfileops.c). */ +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) && !defined _IO_USE_OLD_IO_FILE # define _IO_JUMPS_OFFSET 1 #else # define _IO_JUMPS_OFFSET 0 @@ -125,11 +105,12 @@ extern "C" { #if _IO_JUMPS_OFFSET # define _IO_JUMPS_FUNC(THIS) \ - (*(struct _IO_jump_t **) ((void *) &_IO_JUMPS_FILE_plus (THIS) \ - + (THIS)->_vtable_offset)) + (IO_validate_vtable \ + (*(struct _IO_jump_t **) ((void *) &_IO_JUMPS_FILE_plus (THIS) \ + + (THIS)->_vtable_offset))) # define _IO_vtable_offset(THIS) (THIS)->_vtable_offset #else -# define _IO_JUMPS_FUNC(THIS) _IO_JUMPS_FILE_plus (THIS) +# define _IO_JUMPS_FUNC(THIS) (IO_validate_vtable (_IO_JUMPS_FILE_plus (THIS))) # define _IO_vtable_offset(THIS) 0 #endif #define _IO_WIDE_JUMPS_FUNC(THIS) _IO_WIDE_JUMPS(THIS) @@ -149,14 +130,14 @@ extern "C" { /* The 'finish' function does any final cleaning up of an _IO_FILE object. It does not delete (free) it, but does everything else to finalize it. It matches the streambuf::~streambuf virtual destructor. */ -typedef void (*_IO_finish_t) (_IO_FILE *, int); /* finalize */ +typedef void (*_IO_finish_t) (FILE *, int); /* finalize */ #define _IO_FINISH(FP) JUMP1 (__finish, FP, 0) #define _IO_WFINISH(FP) WJUMP1 (__finish, FP, 0) /* The 'overflow' hook flushes the buffer. The second argument is a character, or EOF. It matches the streambuf::overflow virtual function. */ -typedef int (*_IO_overflow_t) (_IO_FILE *, int); +typedef int (*_IO_overflow_t) (FILE *, int); #define _IO_OVERFLOW(FP, CH) JUMP1 (__overflow, FP, CH) #define _IO_WOVERFLOW(FP, CH) WJUMP1 (__overflow, FP, CH) @@ -164,7 +145,7 @@ typedef int (*_IO_overflow_t) (_IO_FILE *, int); It returns the next character (as an unsigned char) or EOF. The next character remains in the get buffer, and the get position is not changed. It matches the streambuf::underflow virtual function. */ -typedef int (*_IO_underflow_t) (_IO_FILE *); +typedef int (*_IO_underflow_t) (FILE *); #define _IO_UNDERFLOW(FP) JUMP0 (__underflow, FP) #define _IO_WUNDERFLOW(FP) WJUMP0 (__underflow, FP) @@ -178,22 +159,22 @@ typedef int (*_IO_underflow_t) (_IO_FILE *); /* The 'pbackfail' hook handles backing up. It matches the streambuf::pbackfail virtual function. */ -typedef int (*_IO_pbackfail_t) (_IO_FILE *, int); +typedef int (*_IO_pbackfail_t) (FILE *, int); #define _IO_PBACKFAIL(FP, CH) JUMP1 (__pbackfail, FP, CH) #define _IO_WPBACKFAIL(FP, CH) WJUMP1 (__pbackfail, FP, CH) /* The 'xsputn' hook writes upto N characters from buffer DATA. Returns EOF or the number of character actually written. It matches the streambuf::xsputn virtual function. */ -typedef _IO_size_t (*_IO_xsputn_t) (_IO_FILE *FP, const void *DATA, - _IO_size_t N); +typedef size_t (*_IO_xsputn_t) (FILE *FP, const void *DATA, + size_t N); #define _IO_XSPUTN(FP, DATA, N) JUMP2 (__xsputn, FP, DATA, N) #define _IO_WXSPUTN(FP, DATA, N) WJUMP2 (__xsputn, FP, DATA, N) /* The 'xsgetn' hook reads upto N characters into buffer DATA. Returns the number of character actually read. It matches the streambuf::xsgetn virtual function. */ -typedef _IO_size_t (*_IO_xsgetn_t) (_IO_FILE *FP, void *DATA, _IO_size_t N); +typedef size_t (*_IO_xsgetn_t) (FILE *FP, void *DATA, size_t N); #define _IO_XSGETN(FP, DATA, N) JUMP2 (__xsgetn, FP, DATA, N) #define _IO_WXSGETN(FP, DATA, N) WJUMP2 (__xsgetn, FP, DATA, N) @@ -202,7 +183,7 @@ typedef _IO_size_t (*_IO_xsgetn_t) (_IO_FILE *FP, void *DATA, _IO_size_t N); (MODE==1), or the end of the file (MODE==2). It matches the streambuf::seekoff virtual function. It is also used for the ANSI fseek function. */ -typedef _IO_off64_t (*_IO_seekoff_t) (_IO_FILE *FP, _IO_off64_t OFF, int DIR, +typedef off64_t (*_IO_seekoff_t) (FILE *FP, off64_t OFF, int DIR, int MODE); #define _IO_SEEKOFF(FP, OFF, DIR, MODE) JUMP3 (__seekoff, FP, OFF, DIR, MODE) #define _IO_WSEEKOFF(FP, OFF, DIR, MODE) WJUMP3 (__seekoff, FP, OFF, DIR, MODE) @@ -212,27 +193,27 @@ typedef _IO_off64_t (*_IO_seekoff_t) (_IO_FILE *FP, _IO_off64_t OFF, int DIR, It matches the streambuf::seekpos virtual function. It is also used for the ANSI fgetpos and fsetpos functions. */ /* The _IO_seek_cur and _IO_seek_end options are not allowed. */ -typedef _IO_off64_t (*_IO_seekpos_t) (_IO_FILE *, _IO_off64_t, int); +typedef off64_t (*_IO_seekpos_t) (FILE *, off64_t, int); #define _IO_SEEKPOS(FP, POS, FLAGS) JUMP2 (__seekpos, FP, POS, FLAGS) #define _IO_WSEEKPOS(FP, POS, FLAGS) WJUMP2 (__seekpos, FP, POS, FLAGS) /* The 'setbuf' hook gives a buffer to the file. It matches the streambuf::setbuf virtual function. */ -typedef _IO_FILE* (*_IO_setbuf_t) (_IO_FILE *, char *, _IO_ssize_t); +typedef FILE* (*_IO_setbuf_t) (FILE *, char *, ssize_t); #define _IO_SETBUF(FP, BUFFER, LENGTH) JUMP2 (__setbuf, FP, BUFFER, LENGTH) #define _IO_WSETBUF(FP, BUFFER, LENGTH) WJUMP2 (__setbuf, FP, BUFFER, LENGTH) /* The 'sync' hook attempts to synchronize the internal data structures of the file with the external state. It matches the streambuf::sync virtual function. */ -typedef int (*_IO_sync_t) (_IO_FILE *); +typedef int (*_IO_sync_t) (FILE *); #define _IO_SYNC(FP) JUMP0 (__sync, FP) #define _IO_WSYNC(FP) WJUMP0 (__sync, FP) /* The 'doallocate' hook is used to tell the file to allocate a buffer. It matches the streambuf::doallocate virtual function, which is not in the ANSI/ISO C++ standard, but is part traditional implementations. */ -typedef int (*_IO_doallocate_t) (_IO_FILE *); +typedef int (*_IO_doallocate_t) (FILE *); #define _IO_DOALLOCATE(FP) JUMP0 (__doallocate, FP) #define _IO_WDOALLOCATE(FP) WJUMP0 (__doallocate, FP) @@ -240,7 +221,7 @@ typedef int (*_IO_doallocate_t) (_IO_FILE *); sysstat) are low-level hooks specific to this implementation. There is no correspondence in the ANSI/ISO C++ standard library. The hooks basically correspond to the Unix system functions - (read, write, close, lseek, and stat) except that a _IO_FILE* + (read, write, close, lseek, and stat) except that a FILE* parameter is used instead of an integer file descriptor; the default implementation used for normal files just calls those functions. The advantage of overriding these functions instead of the higher-level @@ -251,7 +232,7 @@ typedef int (*_IO_doallocate_t) (_IO_FILE *); an existing buffer. It generalizes the Unix read(2) function. It matches the streambuf::sys_read virtual function, which is specific to this implementation. */ -typedef _IO_ssize_t (*_IO_read_t) (_IO_FILE *, void *, _IO_ssize_t); +typedef ssize_t (*_IO_read_t) (FILE *, void *, ssize_t); #define _IO_SYSREAD(FP, DATA, LEN) JUMP2 (__read, FP, DATA, LEN) #define _IO_WSYSREAD(FP, DATA, LEN) WJUMP2 (__read, FP, DATA, LEN) @@ -259,7 +240,7 @@ typedef _IO_ssize_t (*_IO_read_t) (_IO_FILE *, void *, _IO_ssize_t); to an external file. It generalizes the Unix write(2) function. It matches the streambuf::sys_write virtual function, which is specific to this implementation. */ -typedef _IO_ssize_t (*_IO_write_t) (_IO_FILE *, const void *, _IO_ssize_t); +typedef ssize_t (*_IO_write_t) (FILE *, const void *, ssize_t); #define _IO_SYSWRITE(FP, DATA, LEN) JUMP2 (__write, FP, DATA, LEN) #define _IO_WSYSWRITE(FP, DATA, LEN) WJUMP2 (__write, FP, DATA, LEN) @@ -267,7 +248,7 @@ typedef _IO_ssize_t (*_IO_write_t) (_IO_FILE *, const void *, _IO_ssize_t); It generalizes the Unix lseek(2) function. It matches the streambuf::sys_seek virtual function, which is specific to this implementation. */ -typedef _IO_off64_t (*_IO_seek_t) (_IO_FILE *, _IO_off64_t, int); +typedef off64_t (*_IO_seek_t) (FILE *, off64_t, int); #define _IO_SYSSEEK(FP, OFFSET, MODE) JUMP2 (__seek, FP, OFFSET, MODE) #define _IO_WSYSSEEK(FP, OFFSET, MODE) WJUMP2 (__seek, FP, OFFSET, MODE) @@ -275,7 +256,7 @@ typedef _IO_off64_t (*_IO_seek_t) (_IO_FILE *, _IO_off64_t, int); external file. It generalizes the Unix close(2) function. It matches the streambuf::sys_close virtual function, which is specific to this implementation. */ -typedef int (*_IO_close_t) (_IO_FILE *); /* finalize */ +typedef int (*_IO_close_t) (FILE *); /* finalize */ #define _IO_SYSCLOSE(FP) JUMP0 (__close, FP) #define _IO_WSYSCLOSE(FP) WJUMP0 (__close, FP) @@ -283,20 +264,20 @@ typedef int (*_IO_close_t) (_IO_FILE *); /* finalize */ into a struct stat buffer. It generalizes the Unix fstat(2) call. It matches the streambuf::sys_stat virtual function, which is specific to this implementation. */ -typedef int (*_IO_stat_t) (_IO_FILE *, void *); +typedef int (*_IO_stat_t) (FILE *, void *); #define _IO_SYSSTAT(FP, BUF) JUMP1 (__stat, FP, BUF) #define _IO_WSYSSTAT(FP, BUF) WJUMP1 (__stat, FP, BUF) /* The 'showmany' hook can be used to get an image how much input is available. In many cases the answer will be 0 which means unknown but some cases one can provide real information. */ -typedef int (*_IO_showmanyc_t) (_IO_FILE *); +typedef int (*_IO_showmanyc_t) (FILE *); #define _IO_SHOWMANYC(FP) JUMP0 (__showmanyc, FP) #define _IO_WSHOWMANYC(FP) WJUMP0 (__showmanyc, FP) /* The 'imbue' hook is used to get information about the currently installed locales. */ -typedef void (*_IO_imbue_t) (_IO_FILE *, void *); +typedef void (*_IO_imbue_t) (FILE *, void *); #define _IO_IMBUE(FP, LOCALE) JUMP1 (__imbue, FP, LOCALE) #define _IO_WIMBUE(FP, LOCALE) WJUMP1 (__imbue, FP, LOCALE) @@ -328,10 +309,6 @@ struct _IO_jump_t JUMP_FIELD(_IO_stat_t, __stat); JUMP_FIELD(_IO_showmanyc_t, __showmanyc); JUMP_FIELD(_IO_imbue_t, __imbue); -#if 0 - get_column; - set_column; -#endif }; /* We always allocate an extra word following an _IO_FILE. @@ -341,7 +318,7 @@ struct _IO_jump_t struct _IO_FILE_plus { - _IO_FILE file; + FILE file; const struct _IO_jump_t *vtable; }; @@ -361,72 +338,71 @@ struct _IO_cookie_file { struct _IO_FILE_plus __fp; void *__cookie; - _IO_cookie_io_functions_t __io_functions; + cookie_io_functions_t __io_functions; }; -_IO_FILE *_IO_fopencookie (void *cookie, const char *mode, - _IO_cookie_io_functions_t io_functions); +FILE *_IO_fopencookie (void *cookie, const char *mode, + cookie_io_functions_t io_functions); /* Iterator type for walking global linked list of _IO_FILE objects. */ -typedef struct _IO_FILE *_IO_ITER; +typedef FILE *_IO_ITER; /* Generic functions */ -extern void _IO_switch_to_main_get_area (_IO_FILE *) __THROW; -extern void _IO_switch_to_backup_area (_IO_FILE *) __THROW; -extern int _IO_switch_to_get_mode (_IO_FILE *); +extern void _IO_switch_to_main_get_area (FILE *) __THROW; +extern void _IO_switch_to_backup_area (FILE *) __THROW; +extern int _IO_switch_to_get_mode (FILE *); libc_hidden_proto (_IO_switch_to_get_mode) -extern void _IO_init (_IO_FILE *, int) __THROW; -libc_hidden_proto (_IO_init) -extern int _IO_sputbackc (_IO_FILE *, int) __THROW; +extern void _IO_init_internal (FILE *, int) attribute_hidden; +extern int _IO_sputbackc (FILE *, int) __THROW; libc_hidden_proto (_IO_sputbackc) -extern int _IO_sungetc (_IO_FILE *) __THROW; +extern int _IO_sungetc (FILE *) __THROW; extern void _IO_un_link (struct _IO_FILE_plus *) __THROW; libc_hidden_proto (_IO_un_link) extern void _IO_link_in (struct _IO_FILE_plus *) __THROW; libc_hidden_proto (_IO_link_in) -extern void _IO_doallocbuf (_IO_FILE *) __THROW; +extern void _IO_doallocbuf (FILE *) __THROW; libc_hidden_proto (_IO_doallocbuf) -extern void _IO_unsave_markers (_IO_FILE *) __THROW; +extern void _IO_unsave_markers (FILE *) __THROW; libc_hidden_proto (_IO_unsave_markers) -extern void _IO_setb (_IO_FILE *, char *, char *, int) __THROW; +extern void _IO_setb (FILE *, char *, char *, int) __THROW; libc_hidden_proto (_IO_setb) extern unsigned _IO_adjust_column (unsigned, const char *, int) __THROW; libc_hidden_proto (_IO_adjust_column) #define _IO_sputn(__fp, __s, __n) _IO_XSPUTN (__fp, __s, __n) -_IO_ssize_t _IO_least_wmarker (_IO_FILE *, wchar_t *) __THROW; +ssize_t _IO_least_wmarker (FILE *, wchar_t *) __THROW; libc_hidden_proto (_IO_least_wmarker) -extern void _IO_switch_to_main_wget_area (_IO_FILE *) __THROW; +extern void _IO_switch_to_main_wget_area (FILE *) __THROW; libc_hidden_proto (_IO_switch_to_main_wget_area) -extern void _IO_switch_to_wbackup_area (_IO_FILE *) __THROW; +extern void _IO_switch_to_wbackup_area (FILE *) __THROW; libc_hidden_proto (_IO_switch_to_wbackup_area) -extern int _IO_switch_to_wget_mode (_IO_FILE *); +extern int _IO_switch_to_wget_mode (FILE *); libc_hidden_proto (_IO_switch_to_wget_mode) -extern void _IO_wsetb (_IO_FILE *, wchar_t *, wchar_t *, int) __THROW; +extern void _IO_wsetb (FILE *, wchar_t *, wchar_t *, int) __THROW; libc_hidden_proto (_IO_wsetb) -extern wint_t _IO_sputbackwc (_IO_FILE *, wint_t) __THROW; +extern wint_t _IO_sputbackwc (FILE *, wint_t) __THROW; libc_hidden_proto (_IO_sputbackwc) -extern wint_t _IO_sungetwc (_IO_FILE *) __THROW; -extern void _IO_wdoallocbuf (_IO_FILE *) __THROW; +extern wint_t _IO_sungetwc (FILE *) __THROW; +extern void _IO_wdoallocbuf (FILE *) __THROW; libc_hidden_proto (_IO_wdoallocbuf) -extern void _IO_unsave_wmarkers (_IO_FILE *) __THROW; +extern void _IO_unsave_wmarkers (FILE *) __THROW; extern unsigned _IO_adjust_wcolumn (unsigned, const wchar_t *, int) __THROW; -extern _IO_off64_t get_file_offset (_IO_FILE *fp); +extern off64_t get_file_offset (FILE *fp); /* Marker-related function. */ -extern void _IO_init_marker (struct _IO_marker *, _IO_FILE *); -extern void _IO_init_wmarker (struct _IO_marker *, _IO_FILE *); +extern void _IO_init_marker (struct _IO_marker *, FILE *); +extern void _IO_init_wmarker (struct _IO_marker *, FILE *); extern void _IO_remove_marker (struct _IO_marker *) __THROW; extern int _IO_marker_difference (struct _IO_marker *, struct _IO_marker *) __THROW; extern int _IO_marker_delta (struct _IO_marker *) __THROW; extern int _IO_wmarker_delta (struct _IO_marker *) __THROW; -extern int _IO_seekmark (_IO_FILE *, struct _IO_marker *, int) __THROW; -extern int _IO_seekwmark (_IO_FILE *, struct _IO_marker *, int) __THROW; +extern int _IO_seekmark (FILE *, struct _IO_marker *, int) __THROW; +extern int _IO_seekwmark (FILE *, struct _IO_marker *, int) __THROW; /* Functions for iterating global list and dealing with its lock */ @@ -436,7 +412,7 @@ extern _IO_ITER _IO_iter_end (void) __THROW; libc_hidden_proto (_IO_iter_end) extern _IO_ITER _IO_iter_next (_IO_ITER) __THROW; libc_hidden_proto (_IO_iter_next) -extern _IO_FILE *_IO_iter_file (_IO_ITER) __THROW; +extern FILE *_IO_iter_file (_IO_ITER) __THROW; libc_hidden_proto (_IO_iter_file) extern void _IO_list_lock (void) __THROW; libc_hidden_proto (_IO_list_lock) @@ -444,46 +420,48 @@ extern void _IO_list_unlock (void) __THROW; libc_hidden_proto (_IO_list_unlock) extern void _IO_list_resetlock (void) __THROW; libc_hidden_proto (_IO_list_resetlock) +extern void _IO_enable_locks (void) __THROW; +libc_hidden_proto (_IO_enable_locks) /* Default jumptable functions. */ -extern int _IO_default_underflow (_IO_FILE *) __THROW; -extern int _IO_default_uflow (_IO_FILE *); +extern int _IO_default_underflow (FILE *) __THROW; +extern int _IO_default_uflow (FILE *); libc_hidden_proto (_IO_default_uflow) -extern wint_t _IO_wdefault_uflow (_IO_FILE *); +extern wint_t _IO_wdefault_uflow (FILE *); libc_hidden_proto (_IO_wdefault_uflow) -extern int _IO_default_doallocate (_IO_FILE *) __THROW; +extern int _IO_default_doallocate (FILE *) __THROW; libc_hidden_proto (_IO_default_doallocate) -extern int _IO_wdefault_doallocate (_IO_FILE *) __THROW; +extern int _IO_wdefault_doallocate (FILE *) __THROW; libc_hidden_proto (_IO_wdefault_doallocate) -extern void _IO_default_finish (_IO_FILE *, int) __THROW; +extern void _IO_default_finish (FILE *, int) __THROW; libc_hidden_proto (_IO_default_finish) -extern void _IO_wdefault_finish (_IO_FILE *, int) __THROW; +extern void _IO_wdefault_finish (FILE *, int) __THROW; libc_hidden_proto (_IO_wdefault_finish) -extern int _IO_default_pbackfail (_IO_FILE *, int) __THROW; +extern int _IO_default_pbackfail (FILE *, int) __THROW; libc_hidden_proto (_IO_default_pbackfail) -extern wint_t _IO_wdefault_pbackfail (_IO_FILE *, wint_t) __THROW; +extern wint_t _IO_wdefault_pbackfail (FILE *, wint_t) __THROW; libc_hidden_proto (_IO_wdefault_pbackfail) -extern _IO_FILE* _IO_default_setbuf (_IO_FILE *, char *, _IO_ssize_t); -extern _IO_size_t _IO_default_xsputn (_IO_FILE *, const void *, _IO_size_t); +extern FILE* _IO_default_setbuf (FILE *, char *, ssize_t); +extern size_t _IO_default_xsputn (FILE *, const void *, size_t); libc_hidden_proto (_IO_default_xsputn) -extern _IO_size_t _IO_wdefault_xsputn (_IO_FILE *, const void *, _IO_size_t); +extern size_t _IO_wdefault_xsputn (FILE *, const void *, size_t); libc_hidden_proto (_IO_wdefault_xsputn) -extern _IO_size_t _IO_default_xsgetn (_IO_FILE *, void *, _IO_size_t); +extern size_t _IO_default_xsgetn (FILE *, void *, size_t); libc_hidden_proto (_IO_default_xsgetn) -extern _IO_size_t _IO_wdefault_xsgetn (_IO_FILE *, void *, _IO_size_t); +extern size_t _IO_wdefault_xsgetn (FILE *, void *, size_t); libc_hidden_proto (_IO_wdefault_xsgetn) -extern _IO_off64_t _IO_default_seekoff (_IO_FILE *, _IO_off64_t, int, int) +extern off64_t _IO_default_seekoff (FILE *, off64_t, int, int) __THROW; -extern _IO_off64_t _IO_default_seekpos (_IO_FILE *, _IO_off64_t, int); -extern _IO_ssize_t _IO_default_write (_IO_FILE *, const void *, _IO_ssize_t); -extern _IO_ssize_t _IO_default_read (_IO_FILE *, void *, _IO_ssize_t); -extern int _IO_default_stat (_IO_FILE *, void *) __THROW; -extern _IO_off64_t _IO_default_seek (_IO_FILE *, _IO_off64_t, int) __THROW; -extern int _IO_default_sync (_IO_FILE *) __THROW; +extern off64_t _IO_default_seekpos (FILE *, off64_t, int); +extern ssize_t _IO_default_write (FILE *, const void *, ssize_t); +extern ssize_t _IO_default_read (FILE *, void *, ssize_t); +extern int _IO_default_stat (FILE *, void *) __THROW; +extern off64_t _IO_default_seek (FILE *, off64_t, int) __THROW; +extern int _IO_default_sync (FILE *) __THROW; #define _IO_default_close ((_IO_close_t) _IO_default_sync) -extern int _IO_default_showmanyc (_IO_FILE *) __THROW; -extern void _IO_default_imbue (_IO_FILE *, void *) __THROW; +extern int _IO_default_showmanyc (FILE *) __THROW; +extern void _IO_default_imbue (FILE *, void *) __THROW; extern const struct _IO_jump_t _IO_file_jumps; libc_hidden_proto (_IO_file_jumps) @@ -499,11 +477,11 @@ extern const struct _IO_jump_t _IO_old_proc_jumps attribute_hidden; extern const struct _IO_jump_t _IO_str_jumps attribute_hidden; extern const struct _IO_jump_t _IO_wstr_jumps attribute_hidden; extern const struct _IO_codecvt __libio_codecvt attribute_hidden; -extern int _IO_do_write (_IO_FILE *, const char *, _IO_size_t); +extern int _IO_do_write (FILE *, const char *, size_t); libc_hidden_proto (_IO_do_write) -extern int _IO_new_do_write (_IO_FILE *, const char *, _IO_size_t); -extern int _IO_old_do_write (_IO_FILE *, const char *, _IO_size_t); -extern int _IO_wdo_write (_IO_FILE *, const wchar_t *, _IO_size_t); +extern int _IO_new_do_write (FILE *, const char *, size_t); +extern int _IO_old_do_write (FILE *, const char *, size_t); +extern int _IO_wdo_write (FILE *, const wchar_t *, size_t); libc_hidden_proto (_IO_wdo_write) extern int _IO_flush_all_lockp (int); extern int _IO_flush_all (void); @@ -511,30 +489,24 @@ libc_hidden_proto (_IO_flush_all) extern int _IO_cleanup (void); extern void _IO_flush_all_linebuffered (void); libc_hidden_proto (_IO_flush_all_linebuffered) -extern int _IO_new_fgetpos (_IO_FILE *, _IO_fpos_t *); -extern int _IO_old_fgetpos (_IO_FILE *, _IO_fpos_t *); -extern int _IO_new_fsetpos (_IO_FILE *, const _IO_fpos_t *); -extern int _IO_old_fsetpos (_IO_FILE *, const _IO_fpos_t *); -extern int _IO_new_fgetpos64 (_IO_FILE *, _IO_fpos64_t *); -extern int _IO_old_fgetpos64 (_IO_FILE *, _IO_fpos64_t *); -extern int _IO_new_fsetpos64 (_IO_FILE *, const _IO_fpos64_t *); -extern int _IO_old_fsetpos64 (_IO_FILE *, const _IO_fpos64_t *); -extern void _IO_old_init (_IO_FILE *fp, int flags) __THROW; - - -#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T -# define _IO_do_flush(_f) \ +extern int _IO_new_fgetpos (FILE *, __fpos_t *); +extern int _IO_old_fgetpos (FILE *, __fpos_t *); +extern int _IO_new_fsetpos (FILE *, const __fpos_t *); +extern int _IO_old_fsetpos (FILE *, const __fpos_t *); +extern int _IO_new_fgetpos64 (FILE *, __fpos64_t *); +extern int _IO_old_fgetpos64 (FILE *, __fpos64_t *); +extern int _IO_new_fsetpos64 (FILE *, const __fpos64_t *); +extern int _IO_old_fsetpos64 (FILE *, const __fpos64_t *); +extern void _IO_old_init (FILE *fp, int flags) __THROW; + + +#define _IO_do_flush(_f) \ ((_f)->_mode <= 0 \ ? _IO_do_write(_f, (_f)->_IO_write_base, \ (_f)->_IO_write_ptr-(_f)->_IO_write_base) \ : _IO_wdo_write(_f, (_f)->_wide_data->_IO_write_base, \ ((_f)->_wide_data->_IO_write_ptr \ - (_f)->_wide_data->_IO_write_base))) -#else -# define _IO_do_flush(_f) \ - _IO_do_write(_f, (_f)->_IO_write_base, \ - (_f)->_IO_write_ptr-(_f)->_IO_write_base) -#endif #define _IO_old_do_flush(_f) \ _IO_old_do_write(_f, (_f)->_IO_write_base, \ (_f)->_IO_write_ptr-(_f)->_IO_write_base) @@ -563,148 +535,144 @@ extern void _IO_old_init (_IO_FILE *fp, int flags) __THROW; /* Jumptable functions for files. */ -extern int _IO_file_doallocate (_IO_FILE *) __THROW; +extern int _IO_file_doallocate (FILE *) __THROW; libc_hidden_proto (_IO_file_doallocate) -extern _IO_FILE* _IO_file_setbuf (_IO_FILE *, char *, _IO_ssize_t); +extern FILE* _IO_file_setbuf (FILE *, char *, ssize_t); libc_hidden_proto (_IO_file_setbuf) -extern _IO_off64_t _IO_file_seekoff (_IO_FILE *, _IO_off64_t, int, int); +extern off64_t _IO_file_seekoff (FILE *, off64_t, int, int); libc_hidden_proto (_IO_file_seekoff) -extern _IO_off64_t _IO_file_seekoff_mmap (_IO_FILE *, _IO_off64_t, int, int) +extern off64_t _IO_file_seekoff_mmap (FILE *, off64_t, int, int) __THROW; -extern _IO_size_t _IO_file_xsputn (_IO_FILE *, const void *, _IO_size_t); +extern size_t _IO_file_xsputn (FILE *, const void *, size_t); libc_hidden_proto (_IO_file_xsputn) -extern _IO_size_t _IO_file_xsgetn (_IO_FILE *, void *, _IO_size_t); +extern size_t _IO_file_xsgetn (FILE *, void *, size_t); libc_hidden_proto (_IO_file_xsgetn) -extern int _IO_file_stat (_IO_FILE *, void *) __THROW; +extern int _IO_file_stat (FILE *, void *) __THROW; libc_hidden_proto (_IO_file_stat) -extern int _IO_file_close (_IO_FILE *) __THROW; +extern int _IO_file_close (FILE *) __THROW; libc_hidden_proto (_IO_file_close) -extern int _IO_file_close_mmap (_IO_FILE *) __THROW; -extern int _IO_file_underflow (_IO_FILE *); +extern int _IO_file_close_mmap (FILE *) __THROW; +extern int _IO_file_underflow (FILE *); libc_hidden_proto (_IO_file_underflow) -extern int _IO_file_underflow_mmap (_IO_FILE *); -extern int _IO_file_underflow_maybe_mmap (_IO_FILE *); -extern int _IO_file_overflow (_IO_FILE *, int); +extern int _IO_file_underflow_mmap (FILE *); +extern int _IO_file_underflow_maybe_mmap (FILE *); +extern int _IO_file_overflow (FILE *, int); libc_hidden_proto (_IO_file_overflow) #define _IO_file_is_open(__fp) ((__fp)->_fileno != -1) -extern void _IO_file_init (struct _IO_FILE_plus *) __THROW; -libc_hidden_proto (_IO_file_init) -extern _IO_FILE* _IO_file_attach (_IO_FILE *, int); +extern FILE* _IO_file_attach (FILE *, int); libc_hidden_proto (_IO_file_attach) -extern _IO_FILE* _IO_file_open (_IO_FILE *, const char *, int, int, int, int); +extern FILE* _IO_file_open (FILE *, const char *, int, int, int, int); libc_hidden_proto (_IO_file_open) -extern _IO_FILE* _IO_file_fopen (_IO_FILE *, const char *, const char *, int); +extern FILE* _IO_file_fopen (FILE *, const char *, const char *, int); libc_hidden_proto (_IO_file_fopen) -extern _IO_ssize_t _IO_file_write (_IO_FILE *, const void *, _IO_ssize_t); -extern _IO_ssize_t _IO_file_read (_IO_FILE *, void *, _IO_ssize_t); +extern ssize_t _IO_file_write (FILE *, const void *, ssize_t); +extern ssize_t _IO_file_read (FILE *, void *, ssize_t); libc_hidden_proto (_IO_file_read) -extern int _IO_file_sync (_IO_FILE *); +extern int _IO_file_sync (FILE *); libc_hidden_proto (_IO_file_sync) -extern int _IO_file_close_it (_IO_FILE *); +extern int _IO_file_close_it (FILE *); libc_hidden_proto (_IO_file_close_it) -extern _IO_off64_t _IO_file_seek (_IO_FILE *, _IO_off64_t, int) __THROW; +extern off64_t _IO_file_seek (FILE *, off64_t, int) __THROW; libc_hidden_proto (_IO_file_seek) -extern void _IO_file_finish (_IO_FILE *, int); +extern void _IO_file_finish (FILE *, int); libc_hidden_proto (_IO_file_finish) -extern _IO_FILE* _IO_new_file_attach (_IO_FILE *, int); -extern int _IO_new_file_close_it (_IO_FILE *); -extern void _IO_new_file_finish (_IO_FILE *, int); -extern _IO_FILE* _IO_new_file_fopen (_IO_FILE *, const char *, const char *, +extern FILE* _IO_new_file_attach (FILE *, int); +extern int _IO_new_file_close_it (FILE *); +extern void _IO_new_file_finish (FILE *, int); +extern FILE* _IO_new_file_fopen (FILE *, const char *, const char *, int); -extern void _IO_no_init (_IO_FILE *, int, int, struct _IO_wide_data *, +extern void _IO_no_init (FILE *, int, int, struct _IO_wide_data *, const struct _IO_jump_t *) __THROW; -extern void _IO_new_file_init (struct _IO_FILE_plus *) __THROW; -extern _IO_FILE* _IO_new_file_setbuf (_IO_FILE *, char *, _IO_ssize_t); -extern _IO_FILE* _IO_file_setbuf_mmap (_IO_FILE *, char *, _IO_ssize_t); -extern int _IO_new_file_sync (_IO_FILE *); -extern int _IO_new_file_underflow (_IO_FILE *); -extern int _IO_new_file_overflow (_IO_FILE *, int); -extern _IO_off64_t _IO_new_file_seekoff (_IO_FILE *, _IO_off64_t, int, int); -extern _IO_ssize_t _IO_new_file_write (_IO_FILE *, const void *, _IO_ssize_t); -extern _IO_size_t _IO_new_file_xsputn (_IO_FILE *, const void *, _IO_size_t); - -extern _IO_FILE* _IO_old_file_setbuf (_IO_FILE *, char *, _IO_ssize_t); -extern _IO_off64_t _IO_old_file_seekoff (_IO_FILE *, _IO_off64_t, int, int); -extern _IO_size_t _IO_old_file_xsputn (_IO_FILE *, const void *, _IO_size_t); -extern int _IO_old_file_underflow (_IO_FILE *); -extern int _IO_old_file_overflow (_IO_FILE *, int); -extern void _IO_old_file_init (struct _IO_FILE_plus *) __THROW; -extern _IO_FILE* _IO_old_file_attach (_IO_FILE *, int); -extern _IO_FILE* _IO_old_file_fopen (_IO_FILE *, const char *, const char *); -extern _IO_ssize_t _IO_old_file_write (_IO_FILE *, const void *, _IO_ssize_t); -extern int _IO_old_file_sync (_IO_FILE *); -extern int _IO_old_file_close_it (_IO_FILE *); -extern void _IO_old_file_finish (_IO_FILE *, int); - -extern int _IO_wfile_doallocate (_IO_FILE *) __THROW; -extern _IO_size_t _IO_wfile_xsputn (_IO_FILE *, const void *, _IO_size_t); +extern void _IO_new_file_init_internal (struct _IO_FILE_plus *) + __THROW attribute_hidden; +extern FILE* _IO_new_file_setbuf (FILE *, char *, ssize_t); +extern FILE* _IO_file_setbuf_mmap (FILE *, char *, ssize_t); +extern int _IO_new_file_sync (FILE *); +extern int _IO_new_file_underflow (FILE *); +extern int _IO_new_file_overflow (FILE *, int); +extern off64_t _IO_new_file_seekoff (FILE *, off64_t, int, int); +extern ssize_t _IO_new_file_write (FILE *, const void *, ssize_t); +extern size_t _IO_new_file_xsputn (FILE *, const void *, size_t); + +extern FILE* _IO_old_file_setbuf (FILE *, char *, ssize_t); +extern off64_t _IO_old_file_seekoff (FILE *, off64_t, int, int); +extern size_t _IO_old_file_xsputn (FILE *, const void *, size_t); +extern int _IO_old_file_underflow (FILE *); +extern int _IO_old_file_overflow (FILE *, int); +extern void _IO_old_file_init_internal (struct _IO_FILE_plus *) + __THROW attribute_hidden; +extern FILE* _IO_old_file_attach (FILE *, int); +extern FILE* _IO_old_file_fopen (FILE *, const char *, const char *); +extern ssize_t _IO_old_file_write (FILE *, const void *, ssize_t); +extern int _IO_old_file_sync (FILE *); +extern int _IO_old_file_close_it (FILE *); +extern void _IO_old_file_finish (FILE *, int); + +extern int _IO_wfile_doallocate (FILE *) __THROW; +extern size_t _IO_wfile_xsputn (FILE *, const void *, size_t); libc_hidden_proto (_IO_wfile_xsputn) -extern _IO_FILE* _IO_wfile_setbuf (_IO_FILE *, wchar_t *, _IO_ssize_t); -extern wint_t _IO_wfile_sync (_IO_FILE *); +extern FILE* _IO_wfile_setbuf (FILE *, wchar_t *, ssize_t); +extern wint_t _IO_wfile_sync (FILE *); libc_hidden_proto (_IO_wfile_sync) -extern wint_t _IO_wfile_underflow (_IO_FILE *); +extern wint_t _IO_wfile_underflow (FILE *); libc_hidden_proto (_IO_wfile_underflow) -extern wint_t _IO_wfile_overflow (_IO_FILE *, wint_t); +extern wint_t _IO_wfile_overflow (FILE *, wint_t); libc_hidden_proto (_IO_wfile_overflow) -extern _IO_off64_t _IO_wfile_seekoff (_IO_FILE *, _IO_off64_t, int, int); +extern off64_t _IO_wfile_seekoff (FILE *, off64_t, int, int); libc_hidden_proto (_IO_wfile_seekoff) /* Jumptable functions for proc_files. */ -extern _IO_FILE* _IO_proc_open (_IO_FILE *, const char *, const char *) +extern FILE* _IO_proc_open (FILE *, const char *, const char *) __THROW; -extern _IO_FILE* _IO_new_proc_open (_IO_FILE *, const char *, const char *) +extern FILE* _IO_new_proc_open (FILE *, const char *, const char *) __THROW; -extern _IO_FILE* _IO_old_proc_open (_IO_FILE *, const char *, const char *); -extern int _IO_proc_close (_IO_FILE *) __THROW; -extern int _IO_new_proc_close (_IO_FILE *) __THROW; -extern int _IO_old_proc_close (_IO_FILE *); +extern FILE* _IO_old_proc_open (FILE *, const char *, const char *); +extern int _IO_proc_close (FILE *) __THROW; +extern int _IO_new_proc_close (FILE *) __THROW; +extern int _IO_old_proc_close (FILE *); /* Jumptable functions for strfiles. */ -extern int _IO_str_underflow (_IO_FILE *) __THROW; +extern int _IO_str_underflow (FILE *) __THROW; libc_hidden_proto (_IO_str_underflow) -extern int _IO_str_overflow (_IO_FILE *, int) __THROW; +extern int _IO_str_overflow (FILE *, int) __THROW; libc_hidden_proto (_IO_str_overflow) -extern int _IO_str_pbackfail (_IO_FILE *, int) __THROW; +extern int _IO_str_pbackfail (FILE *, int) __THROW; libc_hidden_proto (_IO_str_pbackfail) -extern _IO_off64_t _IO_str_seekoff (_IO_FILE *, _IO_off64_t, int, int) __THROW; +extern off64_t _IO_str_seekoff (FILE *, off64_t, int, int) __THROW; libc_hidden_proto (_IO_str_seekoff) -extern void _IO_str_finish (_IO_FILE *, int) __THROW; +extern void _IO_str_finish (FILE *, int) __THROW; /* Other strfile functions */ struct _IO_strfile_; -extern void _IO_str_init_static (struct _IO_strfile_ *, char *, int, char *) - __THROW; -extern void _IO_str_init_readonly (struct _IO_strfile_ *, const char *, int) - __THROW; -extern _IO_ssize_t _IO_str_count (_IO_FILE *) __THROW; +extern ssize_t _IO_str_count (FILE *) __THROW; /* And the wide character versions. */ -extern void _IO_wstr_init_static (_IO_FILE *, wchar_t *, _IO_size_t, wchar_t *) +extern void _IO_wstr_init_static (FILE *, wchar_t *, size_t, wchar_t *) __THROW; -extern _IO_ssize_t _IO_wstr_count (_IO_FILE *) __THROW; -extern _IO_wint_t _IO_wstr_overflow (_IO_FILE *, _IO_wint_t) __THROW; -extern _IO_wint_t _IO_wstr_underflow (_IO_FILE *) __THROW; -extern _IO_off64_t _IO_wstr_seekoff (_IO_FILE *, _IO_off64_t, int, int) +extern ssize_t _IO_wstr_count (FILE *) __THROW; +extern wint_t _IO_wstr_overflow (FILE *, wint_t) __THROW; +extern wint_t _IO_wstr_underflow (FILE *) __THROW; +extern off64_t _IO_wstr_seekoff (FILE *, off64_t, int, int) __THROW; -extern _IO_wint_t _IO_wstr_pbackfail (_IO_FILE *, _IO_wint_t) __THROW; -extern void _IO_wstr_finish (_IO_FILE *, int) __THROW; +extern wint_t _IO_wstr_pbackfail (FILE *, wint_t) __THROW; +extern void _IO_wstr_finish (FILE *, int) __THROW; extern int _IO_vasprintf (char **result_ptr, const char *format, - _IO_va_list args) __THROW; -extern int _IO_vdprintf (int d, const char *format, _IO_va_list arg); -extern int _IO_vsnprintf (char *string, _IO_size_t maxlen, - const char *format, _IO_va_list args) __THROW; + va_list args) __THROW; +extern int _IO_vdprintf (int d, const char *format, va_list arg); +extern int _IO_vsnprintf (char *string, size_t maxlen, + const char *format, va_list args) __THROW; -extern _IO_size_t _IO_getline (_IO_FILE *,char *, _IO_size_t, int, int); +extern size_t _IO_getline (FILE *,char *, size_t, int, int); libc_hidden_proto (_IO_getline) -extern _IO_size_t _IO_getline_info (_IO_FILE *,char *, _IO_size_t, +extern size_t _IO_getline_info (FILE *,char *, size_t, int, int, int *); libc_hidden_proto (_IO_getline_info) -extern _IO_ssize_t _IO_getdelim (char **, _IO_size_t *, int, _IO_FILE *); -extern _IO_size_t _IO_getwline (_IO_FILE *,wchar_t *, _IO_size_t, wint_t, int); -extern _IO_size_t _IO_getwline_info (_IO_FILE *,wchar_t *, _IO_size_t, +extern ssize_t _IO_getdelim (char **, size_t *, int, FILE *); +extern size_t _IO_getwline (FILE *,wchar_t *, size_t, wint_t, int); +extern size_t _IO_getwline_info (FILE *,wchar_t *, size_t, wint_t, int, wint_t *); extern struct _IO_FILE_plus *_IO_list_all; @@ -712,28 +680,12 @@ libc_hidden_proto (_IO_list_all) extern void (*_IO_cleanup_registration_needed) (void); extern void _IO_str_init_static_internal (struct _IO_strfile_ *, char *, - _IO_size_t, char *) __THROW; -extern _IO_off64_t _IO_seekoff_unlocked (_IO_FILE *, _IO_off64_t, int, int) + size_t, char *) __THROW; +extern off64_t _IO_seekoff_unlocked (FILE *, off64_t, int, int) attribute_hidden; -extern _IO_off64_t _IO_seekpos_unlocked (_IO_FILE *, _IO_off64_t, int) +extern off64_t _IO_seekpos_unlocked (FILE *, off64_t, int) attribute_hidden; -#ifndef EOF -# define EOF (-1) -#endif -#ifndef NULL -# if defined __GNUG__ && \ - (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)) -# define NULL (__null) -# else -# if !defined(__cplusplus) -# define NULL ((void*)0) -# else -# define NULL (0) -# endif -# endif -#endif - #if _G_HAVE_MMAP # include <unistd.h> @@ -752,126 +704,66 @@ extern _IO_off64_t _IO_seekpos_unlocked (_IO_FILE *, _IO_off64_t, int) #endif /* _G_HAVE_MMAP */ -#if _G_HAVE_MMAP - -# ifdef _LIBC -/* When using this code in the GNU libc we must not pollute the name space. */ -# define mmap __mmap -# define munmap __munmap -# define ftruncate __ftruncate -# endif -#endif /* _G_HAVE_MMAP */ - -#ifndef OS_FSTAT -# define OS_FSTAT fstat -#endif -extern int _IO_vscanf (const char *, _IO_va_list) __THROW; - -/* _IO_pos_BAD is an _IO_off64_t value indicating error, unknown, or EOF. */ -#ifndef _IO_pos_BAD -# define _IO_pos_BAD ((_IO_off64_t) -1) -#endif -/* _IO_pos_adjust adjust an _IO_off64_t by some number of bytes. */ -#ifndef _IO_pos_adjust -# define _IO_pos_adjust(pos, delta) ((pos) += (delta)) -#endif -/* _IO_pos_0 is an _IO_off64_t value indicating beginning of file. */ -#ifndef _IO_pos_0 -# define _IO_pos_0 ((_IO_off64_t) 0) -#endif - -#ifdef __cplusplus -} -#endif +extern int _IO_vscanf (const char *, va_list) __THROW; #ifdef _IO_MTSAFE_IO /* check following! */ # ifdef _IO_USE_OLD_IO_FILE # define FILEBUF_LITERAL(CHAIN, FLAGS, FD, WDP) \ { _IO_MAGIC+_IO_LINKED+_IO_IS_FILEBUF+FLAGS, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (_IO_FILE *) CHAIN, FD, \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (FILE *) CHAIN, FD, \ 0, _IO_pos_BAD, 0, 0, { 0 }, &_IO_stdfile_##FD##_lock } # else -# if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T -# define FILEBUF_LITERAL(CHAIN, FLAGS, FD, WDP) \ +# define FILEBUF_LITERAL(CHAIN, FLAGS, FD, WDP) \ { _IO_MAGIC+_IO_LINKED+_IO_IS_FILEBUF+FLAGS, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (_IO_FILE *) CHAIN, FD, \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (FILE *) CHAIN, FD, \ 0, _IO_pos_BAD, 0, 0, { 0 }, &_IO_stdfile_##FD##_lock, _IO_pos_BAD,\ NULL, WDP, 0 } -# else -# define FILEBUF_LITERAL(CHAIN, FLAGS, FD, WDP) \ - { _IO_MAGIC+_IO_LINKED+_IO_IS_FILEBUF+FLAGS, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (_IO_FILE *) CHAIN, FD, \ - 0, _IO_pos_BAD, 0, 0, { 0 }, &_IO_stdfile_##FD##_lock, _IO_pos_BAD,\ - 0 } -# endif # endif #else # ifdef _IO_USE_OLD_IO_FILE # define FILEBUF_LITERAL(CHAIN, FLAGS, FD, WDP) \ { _IO_MAGIC+_IO_LINKED+_IO_IS_FILEBUF+FLAGS, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (_IO_FILE *) CHAIN, FD, \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (FILE *) CHAIN, FD, \ 0, _IO_pos_BAD } # else -# if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T -# define FILEBUF_LITERAL(CHAIN, FLAGS, FD, WDP) \ +# define FILEBUF_LITERAL(CHAIN, FLAGS, FD, WDP) \ { _IO_MAGIC+_IO_LINKED+_IO_IS_FILEBUF+FLAGS, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (_IO_FILE *) CHAIN, FD, \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (FILE *) CHAIN, FD, \ 0, _IO_pos_BAD, 0, 0, { 0 }, 0, _IO_pos_BAD, \ NULL, WDP, 0 } -# else -# define FILEBUF_LITERAL(CHAIN, FLAGS, FD, WDP) \ - { _IO_MAGIC+_IO_LINKED+_IO_IS_FILEBUF+FLAGS, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (_IO_FILE *) CHAIN, FD, \ - 0, _IO_pos_BAD, 0, 0, { 0 }, 0, _IO_pos_BAD, \ - 0 } -# endif # endif #endif -#define _IO_va_start(args, last) va_start(args, last) - extern struct _IO_fake_stdiobuf _IO_stdin_buf, _IO_stdout_buf, _IO_stderr_buf; -#if 1 -# define COERCE_FILE(FILE) /* Nothing */ -#else -/* This is part of the kludge for binary compatibility with old stdio. */ -# define COERCE_FILE(FILE) \ - (((FILE)->_IO_file_flags & _IO_MAGIC_MASK) == _OLD_MAGIC_MASK \ - && (FILE) = *(FILE**)&((int*)fp)[1]) -#endif - -#ifdef EINVAL -# define MAYBE_SET_EINVAL __set_errno (EINVAL) -#else -# define MAYBE_SET_EINVAL /* nothing */ -#endif - #ifdef IO_DEBUG -# define CHECK_FILE(FILE, RET) \ - if ((FILE) == NULL) { MAYBE_SET_EINVAL; return RET; } \ - else { COERCE_FILE(FILE); \ - if (((FILE)->_IO_file_flags & _IO_MAGIC_MASK) != _IO_MAGIC) \ - { MAYBE_SET_EINVAL; return RET; }} +# define CHECK_FILE(FILE, RET) do { \ + if ((FILE) == NULL || \ + ((FILE)->_flags & _IO_MAGIC_MASK) != _IO_MAGIC) \ + { \ + __set_errno (EINVAL); \ + return RET; \ + } \ + } while (0) #else -# define CHECK_FILE(FILE, RET) COERCE_FILE (FILE) +# define CHECK_FILE(FILE, RET) do { } while (0) #endif static inline void __attribute__ ((__always_inline__)) -_IO_acquire_lock_fct (_IO_FILE **p) +_IO_acquire_lock_fct (FILE **p) { - _IO_FILE *fp = *p; + FILE *fp = *p; if ((fp->_flags & _IO_USER_LOCK) == 0) _IO_funlockfile (fp); } static inline void __attribute__ ((__always_inline__)) -_IO_acquire_lock_clear_flags2_fct (_IO_FILE **p) +_IO_acquire_lock_clear_flags2_fct (FILE **p) { - _IO_FILE *fp = *p; + FILE *fp = *p; fp->_flags2 &= ~(_IO_FLAGS2_FORTIFY | _IO_FLAGS2_SCANF_STD); if ((fp->_flags & _IO_USER_LOCK) == 0) _IO_funlockfile (fp); @@ -880,13 +772,71 @@ _IO_acquire_lock_clear_flags2_fct (_IO_FILE **p) #if !defined _IO_MTSAFE_IO && IS_IN (libc) # define _IO_acquire_lock(_fp) \ do { \ - _IO_FILE *_IO_acquire_lock_file = NULL + FILE *_IO_acquire_lock_file = NULL # define _IO_acquire_lock_clear_flags2(_fp) \ do { \ - _IO_FILE *_IO_acquire_lock_file = (_fp) + FILE *_IO_acquire_lock_file = (_fp) # define _IO_release_lock(_fp) \ if (_IO_acquire_lock_file != NULL) \ _IO_acquire_lock_file->_flags2 &= ~(_IO_FLAGS2_FORTIFY \ | _IO_FLAGS2_SCANF_STD); \ } while (0) #endif + +/* Collect all vtables in a special section for vtable verification. + These symbols cover the extent of this section. */ +symbol_set_declare (__libc_IO_vtables) + +/* libio vtables need to carry this attribute so that they pass + validation. */ +#define libio_vtable __attribute__ ((section ("__libc_IO_vtables"))) + +#ifdef SHARED +/* If equal to &_IO_vtable_check (with pointer guard protection), + unknown vtable pointers are valid. This function pointer is solely + used as a flag. */ +extern void (*IO_accept_foreign_vtables) (void) attribute_hidden; + +/* Assigns the passed function pointer (either NULL or + &_IO_vtable_check) to IO_accept_foreign_vtables. */ +static inline void +IO_set_accept_foreign_vtables (void (*flag) (void)) +{ +#ifdef PTR_MANGLE + PTR_MANGLE (flag); +#endif + atomic_store_relaxed (&IO_accept_foreign_vtables, flag); +} + +#else /* !SHARED */ + +/* The statically-linked version does nothing. */ +static inline void +IO_set_accept_foreign_vtables (void (*flag) (void)) +{ +} + +#endif + +/* Check if unknown vtable pointers are permitted; otherwise, + terminate the process. */ +void _IO_vtable_check (void) attribute_hidden; + +/* Perform vtable pointer validation. If validation fails, terminate + the process. */ +static inline const struct _IO_jump_t * +IO_validate_vtable (const struct _IO_jump_t *vtable) +{ + /* Fast path: The vtable pointer is within the __libc_IO_vtables + section. */ + uintptr_t section_length = __stop___libc_IO_vtables - __start___libc_IO_vtables; + uintptr_t ptr = (uintptr_t) vtable; + uintptr_t offset = ptr - (uintptr_t) __start___libc_IO_vtables; + if (__glibc_unlikely (offset >= section_length)) + /* The vtable pointer is not in the expected section. Use the + slow path, which will terminate the process if necessary. */ + _IO_vtable_check (); + return vtable; +} + +#endif /* libioP.h. */ diff --git a/libio/memstream.c b/libio/memstream.c index 7fa5245e72..b5eaa5476c 100644 --- a/libio/memstream.c +++ b/libio/memstream.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1995-2016 Free Software Foundation, Inc. +/* Copyright (C) 1995-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -25,15 +25,15 @@ struct _IO_FILE_memstream { _IO_strfile _sf; char **bufloc; - _IO_size_t *sizeloc; + size_t *sizeloc; }; -static int _IO_mem_sync (_IO_FILE* fp) __THROW; -static void _IO_mem_finish (_IO_FILE* fp, int) __THROW; +static int _IO_mem_sync (FILE* fp) __THROW; +static void _IO_mem_finish (FILE* fp, int) __THROW; -static const struct _IO_jump_t _IO_mem_jumps = +static const struct _IO_jump_t _IO_mem_jumps libio_vtable = { JUMP_INIT_DUMMY, JUMP_INIT (finish, _IO_mem_finish), @@ -60,8 +60,8 @@ static const struct _IO_jump_t _IO_mem_jumps = /* Open a stream that writes into a malloc'd buffer that is expanded as necessary. *BUFLOC and *SIZELOC are updated with the buffer's location and the number of characters written on fflush or fclose. */ -_IO_FILE * -__open_memstream (char **bufloc, _IO_size_t *sizeloc) +FILE * +__open_memstream (char **bufloc, size_t *sizeloc) { struct locked_FILE { @@ -80,30 +80,33 @@ __open_memstream (char **bufloc, _IO_size_t *sizeloc) new_f->fp._sf._sbf._f._lock = &new_f->lock; #endif - buf = calloc (1, _IO_BUFSIZ); + buf = calloc (1, BUFSIZ); if (buf == NULL) { free (new_f); return NULL; } - _IO_init (&new_f->fp._sf._sbf._f, 0); + _IO_init_internal (&new_f->fp._sf._sbf._f, 0); _IO_JUMPS_FILE_plus (&new_f->fp._sf._sbf) = &_IO_mem_jumps; - _IO_str_init_static_internal (&new_f->fp._sf, buf, _IO_BUFSIZ, buf); + _IO_str_init_static_internal (&new_f->fp._sf, buf, BUFSIZ, buf); new_f->fp._sf._sbf._f._flags &= ~_IO_USER_BUF; - new_f->fp._sf._s._allocate_buffer = (_IO_alloc_type) malloc; - new_f->fp._sf._s._free_buffer = (_IO_free_type) free; + new_f->fp._sf._s._allocate_buffer_unused = (_IO_alloc_type) malloc; + new_f->fp._sf._s._free_buffer_unused = (_IO_free_type) free; new_f->fp.bufloc = bufloc; new_f->fp.sizeloc = sizeloc; - return (_IO_FILE *) &new_f->fp._sf._sbf; + /* Disable single thread optimization. BZ 21735. */ + new_f->fp._sf._sbf._f._flags2 |= _IO_FLAGS2_NEED_LOCK; + + return (FILE *) &new_f->fp._sf._sbf; } libc_hidden_def (__open_memstream) weak_alias (__open_memstream, open_memstream) static int -_IO_mem_sync (_IO_FILE *fp) +_IO_mem_sync (FILE *fp) { struct _IO_FILE_memstream *mp = (struct _IO_FILE_memstream *) fp; @@ -112,8 +115,6 @@ _IO_mem_sync (_IO_FILE *fp) _IO_str_overflow (fp, '\0'); --fp->_IO_write_ptr; } - else - *fp->_IO_write_ptr = '\0'; *mp->bufloc = fp->_IO_write_base; *mp->sizeloc = fp->_IO_write_ptr - fp->_IO_write_base; @@ -123,7 +124,7 @@ _IO_mem_sync (_IO_FILE *fp) static void -_IO_mem_finish (_IO_FILE *fp, int dummy) +_IO_mem_finish (FILE *fp, int dummy) { struct _IO_FILE_memstream *mp = (struct _IO_FILE_memstream *) fp; diff --git a/libio/obprintf.c b/libio/obprintf.c index aa17b46da8..a74f9467a2 100644 --- a/libio/obprintf.c +++ b/libio/obprintf.c @@ -1,5 +1,5 @@ /* Print output of stream to given obstack. - Copyright (C) 1996-2016 Free Software Foundation, Inc. + Copyright (C) 1996-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. @@ -37,7 +37,7 @@ struct _IO_obstack_file static int -_IO_obstack_overflow (_IO_FILE *fp, int c) +_IO_obstack_overflow (FILE *fp, int c) { struct obstack *obstack = ((struct _IO_obstack_file *) fp)->obstack; int size; @@ -59,8 +59,8 @@ _IO_obstack_overflow (_IO_FILE *fp, int c) } -static _IO_size_t -_IO_obstack_xsputn (_IO_FILE *fp, const void *data, _IO_size_t n) +static size_t +_IO_obstack_xsputn (FILE *fp, const void *data, size_t n) { struct obstack *obstack = ((struct _IO_obstack_file *) fp)->obstack; @@ -91,7 +91,7 @@ _IO_obstack_xsputn (_IO_FILE *fp, const void *data, _IO_size_t n) /* the jump table. */ -const struct _IO_jump_t _IO_obstack_jumps attribute_hidden = +const struct _IO_jump_t _IO_obstack_jumps libio_vtable attribute_hidden = { JUMP_INIT_DUMMY, JUMP_INIT(finish, NULL), diff --git a/libio/oldfileops.c b/libio/oldfileops.c index 4f3bdfe489..5e60c8c168 100644 --- a/libio/oldfileops.c +++ b/libio/oldfileops.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Written by Per Bothner <bothner@cygnus.com>. @@ -30,9 +30,6 @@ #include <shlib-compat.h> #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) -#ifndef _POSIX_SOURCE -# define _POSIX_SOURCE -#endif #define _IO_USE_OLD_IO_FILE #include "libioP.h" #include <fcntl.h> @@ -42,21 +39,6 @@ #include <errno.h> #include <stdlib.h> #include <unistd.h> -#ifndef errno -extern int errno; -#endif -#ifndef __set_errno -# define __set_errno(Val) errno = (Val) -#endif - - -#ifdef _LIBC -# define open(Name, Flags, Prot) __open (Name, Flags, Prot) -# define close(FD) __close (FD) -# define lseek(FD, Offset, Whence) __lseek (FD, Offset, Whence) -# define read(FD, Buf, NBytes) __read (FD, Buf, NBytes) -# define write(FD, Buf, NBytes) __write (FD, Buf, NBytes) -#endif /* An fstream can be in at most one of put mode, get mode, or putback mode. Putback mode is a variant of get mode. @@ -114,20 +96,19 @@ extern int errno; void attribute_compat_text_section -_IO_old_file_init (struct _IO_FILE_plus *fp) +_IO_old_file_init_internal (struct _IO_FILE_plus *fp) { /* POSIX.1 allows another file handle to be used to change the position of our file descriptor. Hence we actually don't know the actual position before we do the first fseek (and until a following fflush). */ fp->file._old_offset = _IO_pos_BAD; - fp->file._IO_file_flags |= CLOSED_FILEBUF_FLAGS; + fp->file._flags |= CLOSED_FILEBUF_FLAGS; _IO_link_in (fp); fp->file._vtable_offset = ((int) sizeof (struct _IO_FILE) - (int) sizeof (struct _IO_FILE_complete)); fp->file._fileno = -1; -#if defined SHARED && defined _LIBC if (__builtin_expect (&_IO_stdin_used != NULL, 1) || (fp != (struct _IO_FILE_plus *) _IO_stdin && fp != (struct _IO_FILE_plus *) _IO_stdout @@ -135,12 +116,19 @@ _IO_old_file_init (struct _IO_FILE_plus *fp) /* The object is dynamically allocated and large enough. Initialize the _mode element as well. */ ((struct _IO_FILE_complete *) fp)->_mode = -1; -#endif +} + +void +attribute_compat_text_section +_IO_old_file_init (struct _IO_FILE_plus *fp) +{ + IO_set_accept_foreign_vtables (&_IO_vtable_check); + _IO_old_file_init_internal (fp); } int attribute_compat_text_section -_IO_old_file_close_it (_IO_FILE *fp) +_IO_old_file_close_it (FILE *fp) { int write_status, close_status; if (!_IO_file_is_open (fp)) @@ -168,7 +156,7 @@ _IO_old_file_close_it (_IO_FILE *fp) void attribute_compat_text_section -_IO_old_file_finish (_IO_FILE *fp, int dummy) +_IO_old_file_finish (FILE *fp, int dummy) { if (_IO_file_is_open (fp)) { @@ -179,9 +167,9 @@ _IO_old_file_finish (_IO_FILE *fp, int dummy) _IO_default_finish (fp, 0); } -_IO_FILE * +FILE * attribute_compat_text_section -_IO_old_file_fopen (_IO_FILE *fp, const char *filename, const char *mode) +_IO_old_file_fopen (FILE *fp, const char *filename, const char *mode) { int oflags = 0, omode; int read_write, fdesc; @@ -213,22 +201,22 @@ _IO_old_file_fopen (_IO_FILE *fp, const char *filename, const char *mode) omode = O_RDWR; read_write &= _IO_IS_APPENDING; } - fdesc = open (filename, omode|oflags, oprot); + fdesc = __open (filename, omode|oflags, oprot); if (fdesc < 0) return NULL; fp->_fileno = fdesc; _IO_mask_flags (fp, read_write,_IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING); if (read_write & _IO_IS_APPENDING) - if (_IO_SEEKOFF (fp, (_IO_off_t)0, _IO_seek_end, _IOS_INPUT|_IOS_OUTPUT) + if (_IO_SEEKOFF (fp, (off_t)0, _IO_seek_end, _IOS_INPUT|_IOS_OUTPUT) == _IO_pos_BAD && errno != ESPIPE) return NULL; _IO_link_in ((struct _IO_FILE_plus *) fp); return fp; } -_IO_FILE * +FILE * attribute_compat_text_section -_IO_old_file_attach (_IO_FILE *fp, int fd) +_IO_old_file_attach (FILE *fp, int fd) { if (_IO_file_is_open (fp)) return NULL; @@ -238,15 +226,15 @@ _IO_old_file_attach (_IO_FILE *fp, int fd) /* Get the current position of the file. */ /* We have to do that since that may be junk. */ fp->_old_offset = _IO_pos_BAD; - if (_IO_SEEKOFF (fp, (_IO_off_t)0, _IO_seek_cur, _IOS_INPUT|_IOS_OUTPUT) + if (_IO_SEEKOFF (fp, (off_t)0, _IO_seek_cur, _IOS_INPUT|_IOS_OUTPUT) == _IO_pos_BAD && errno != ESPIPE) return NULL; return fp; } -_IO_FILE * +FILE * attribute_compat_text_section -_IO_old_file_setbuf (_IO_FILE *fp, char *p, _IO_ssize_t len) +_IO_old_file_setbuf (FILE *fp, char *p, ssize_t len) { if (_IO_default_setbuf (fp, p, len) == NULL) return NULL; @@ -258,24 +246,24 @@ _IO_old_file_setbuf (_IO_FILE *fp, char *p, _IO_ssize_t len) return fp; } -static int old_do_write (_IO_FILE *, const char *, _IO_size_t); +static int old_do_write (FILE *, const char *, size_t); /* Write TO_DO bytes from DATA to FP. Then mark FP as having empty buffers. */ int attribute_compat_text_section -_IO_old_do_write (_IO_FILE *fp, const char *data, _IO_size_t to_do) +_IO_old_do_write (FILE *fp, const char *data, size_t to_do) { - return (to_do == 0 || (_IO_size_t) old_do_write (fp, data, to_do) == to_do) + return (to_do == 0 || (size_t) old_do_write (fp, data, to_do) == to_do) ? 0 : EOF; } static int attribute_compat_text_section -old_do_write (_IO_FILE *fp, const char *data, _IO_size_t to_do) +old_do_write (FILE *fp, const char *data, size_t to_do) { - _IO_size_t count; + size_t count; if (fp->_flags & _IO_IS_APPENDING) /* On a system without a proper O_APPEND implementation, you would need to sys_seek(0, SEEK_END) here, but is @@ -285,7 +273,7 @@ old_do_write (_IO_FILE *fp, const char *data, _IO_size_t to_do) fp->_old_offset = _IO_pos_BAD; else if (fp->_IO_read_end != fp->_IO_write_base) { - _IO_off_t new_pos + off_t new_pos = _IO_SYSSEEK (fp, fp->_IO_write_base - fp->_IO_read_end, 1); if (new_pos == _IO_pos_BAD) return 0; @@ -303,14 +291,13 @@ old_do_write (_IO_FILE *fp, const char *data, _IO_size_t to_do) int attribute_compat_text_section -_IO_old_file_underflow (_IO_FILE *fp) +_IO_old_file_underflow (FILE *fp) { - _IO_ssize_t count; -#if 0 - /* SysV does not make this test; take it out for compatibility */ + ssize_t count; + + /* C99 requires EOF to be "sticky". */ if (fp->_flags & _IO_EOF_SEEN) - return (EOF); -#endif + return EOF; if (fp->_flags & _IO_NO_READS) { @@ -367,7 +354,7 @@ _IO_old_file_underflow (_IO_FILE *fp) int attribute_compat_text_section -_IO_old_file_overflow (_IO_FILE *f, int ch) +_IO_old_file_overflow (FILE *f, int ch) { if (f->_flags & _IO_NO_WRITES) /* SET ERROR */ { @@ -417,9 +404,9 @@ _IO_old_file_overflow (_IO_FILE *f, int ch) int attribute_compat_text_section -_IO_old_file_sync (_IO_FILE *fp) +_IO_old_file_sync (FILE *fp) { - _IO_ssize_t delta; + ssize_t delta; int retval = 0; /* char* ptr = cur_ptr(); */ @@ -432,13 +419,11 @@ _IO_old_file_sync (_IO_FILE *fp) if (_IO_in_backup (fp)) delta -= eGptr () - Gbase (); #endif - _IO_off_t new_pos = _IO_SYSSEEK (fp, delta, 1); - if (new_pos != (_IO_off_t) EOF) + off_t new_pos = _IO_SYSSEEK (fp, delta, 1); + if (new_pos != (off_t) EOF) fp->_IO_read_end = fp->_IO_read_ptr; -#ifdef ESPIPE else if (errno == ESPIPE) ; /* Ignore error from unseekable devices. */ -#endif else retval = EOF; } @@ -449,12 +434,12 @@ _IO_old_file_sync (_IO_FILE *fp) return retval; } -_IO_off64_t +off64_t attribute_compat_text_section -_IO_old_file_seekoff (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode) +_IO_old_file_seekoff (FILE *fp, off64_t offset, int dir, int mode) { - _IO_off_t result; - _IO_off64_t delta, new_offset; + off_t result; + off64_t delta, new_offset; long count; /* POSIX.1 8.2.3.7 says that after a call the fflush() the file offset of the underlying file must be exact. */ @@ -526,14 +511,10 @@ _IO_old_file_seekoff (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode) && !_IO_in_backup (fp)) { /* Offset relative to start of main get area. */ - _IO_off_t rel_offset = (offset - fp->_old_offset - + (fp->_IO_read_end - fp->_IO_read_base)); + off_t rel_offset = (offset - fp->_old_offset + + (fp->_IO_read_end - fp->_IO_read_base)); if (rel_offset >= 0) { -#if 0 - if (_IO_in_backup (fp)) - _IO_switch_to_main_get_area (fp); -#endif if (rel_offset <= fp->_IO_read_end - fp->_IO_read_base) { _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + rel_offset, @@ -632,14 +613,14 @@ resync: return offset; } -_IO_ssize_t +ssize_t attribute_compat_text_section -_IO_old_file_write (_IO_FILE *f, const void *data, _IO_ssize_t n) +_IO_old_file_write (FILE *f, const void *data, ssize_t n) { - _IO_ssize_t to_do = n; + ssize_t to_do = n; while (to_do > 0) { - _IO_ssize_t count = write (f->_fileno, data, to_do); + ssize_t count = __write (f->_fileno, data, to_do); if (count == EOF) { f->_flags |= _IO_ERR_SEEN; @@ -654,14 +635,14 @@ _IO_old_file_write (_IO_FILE *f, const void *data, _IO_ssize_t n) return n; } -_IO_size_t +size_t attribute_compat_text_section -_IO_old_file_xsputn (_IO_FILE *f, const void *data, _IO_size_t n) +_IO_old_file_xsputn (FILE *f, const void *data, size_t n) { const char *s = (char *) data; - _IO_size_t to_do = n; + size_t to_do = n; int must_flush = 0; - _IO_size_t count = 0; + size_t count = 0; if (n <= 0) return 0; @@ -697,12 +678,7 @@ _IO_old_file_xsputn (_IO_FILE *f, const void *data, _IO_size_t n) count = to_do; if (count > 20) { -#ifdef _LIBC f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count); -#else - memcpy (f->_IO_write_ptr, s, count); - f->_IO_write_ptr += count; -#endif s += count; } else @@ -717,7 +693,7 @@ _IO_old_file_xsputn (_IO_FILE *f, const void *data, _IO_size_t n) } if (to_do + must_flush > 0) { - _IO_size_t block_size, do_write; + size_t block_size, do_write; /* Next flush the (full) buffer. */ if (__overflow (f, EOF) == EOF) return to_do == 0 ? EOF : n - to_do; @@ -745,7 +721,7 @@ _IO_old_file_xsputn (_IO_FILE *f, const void *data, _IO_size_t n) } -const struct _IO_jump_t _IO_old_file_jumps = +const struct _IO_jump_t _IO_old_file_jumps libio_vtable = { JUMP_INIT_DUMMY, JUMP_INIT(finish, _IO_old_file_finish), diff --git a/libio/oldfmemopen.c b/libio/oldfmemopen.c index 2678a5d6be..d7f0db3423 100644 --- a/libio/oldfmemopen.c +++ b/libio/oldfmemopen.c @@ -1,5 +1,5 @@ /* Fmemopen implementation. - Copyright (C) 2000-2016 Free Software Foundation, Inc. + Copyright (C) 2000-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Hanno Mueller, kontakt@hanno.de, 2000. @@ -71,7 +71,6 @@ #if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_22) #include <errno.h> -#include <libio.h> #include <stdio.h> #include <stdlib.h> #include <stdint.h> @@ -86,7 +85,7 @@ struct fmemopen_cookie_struct int mybuffer; int binmode; size_t size; - _IO_off64_t pos; + off64_t pos; size_t maxpos; }; @@ -150,9 +149,9 @@ fmemopen_write (void *cookie, const char *b, size_t s) static int -fmemopen_seek (void *cookie, _IO_off64_t *p, int w) +fmemopen_seek (void *cookie, off64_t *p, int w) { - _IO_off64_t np; + off64_t np; fmemopen_cookie_t *c; c = (fmemopen_cookie_t *) cookie; diff --git a/libio/oldiofclose.c b/libio/oldiofclose.c index 0c96cb4f6f..f414502fe0 100644 --- a/libio/oldiofclose.c +++ b/libio/oldiofclose.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -33,7 +33,7 @@ int attribute_compat_text_section -_IO_old_fclose (_IO_FILE *fp) +_IO_old_fclose (FILE *fp) { int status; @@ -46,11 +46,11 @@ _IO_old_fclose (_IO_FILE *fp) return _IO_new_fclose (fp); /* First unlink the stream. */ - if (fp->_IO_file_flags & _IO_IS_FILEBUF) + if (fp->_flags & _IO_IS_FILEBUF) _IO_un_link ((struct _IO_FILE_plus *) fp); _IO_acquire_lock (fp); - if (fp->_IO_file_flags & _IO_IS_FILEBUF) + if (fp->_flags & _IO_IS_FILEBUF) status = _IO_old_file_close_it (fp); else status = fp->_flags & _IO_ERR_SEEN ? -1 : 0; @@ -60,7 +60,7 @@ _IO_old_fclose (_IO_FILE *fp) _IO_free_backup_area (fp); if (fp != _IO_stdin && fp != _IO_stdout && fp != _IO_stderr) { - fp->_IO_file_flags = 0; + fp->_flags = 0; free(fp); } diff --git a/libio/oldiofdopen.c b/libio/oldiofdopen.c index 33406ff240..cec6642fc4 100644 --- a/libio/oldiofdopen.c +++ b/libio/oldiofdopen.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -32,11 +32,7 @@ #include "libioP.h" #include <fcntl.h> -#ifndef _IO_fcntl -# define _IO_fcntl __fcntl -#endif - -_IO_FILE * +FILE * attribute_compat_text_section _IO_old_fdopen (int fd, const char *mode) { @@ -64,16 +60,12 @@ _IO_old_fdopen (int fd, const char *mode) read_write = _IO_NO_READS|_IO_IS_APPENDING; break; default: - MAYBE_SET_EINVAL; + __set_errno (EINVAL); return NULL; } if (mode[0] == '+' || (mode[0] == 'b' && mode[1] == '+')) read_write &= _IO_IS_APPENDING; -#ifdef F_GETFL - fd_flags = _IO_fcntl (fd, F_GETFL); -#ifndef O_ACCMODE -#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) -#endif + fd_flags = __fcntl (fd, F_GETFL); 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))) @@ -97,12 +89,9 @@ _IO_old_fdopen (int fd, const char *mode) */ if ((posix_mode & O_APPEND) && !(fd_flags & O_APPEND)) { -#ifdef F_SETFL - if (_IO_fcntl (fd, F_SETFL, fd_flags | O_APPEND) == -1) -#endif + if (__fcntl (fd, F_SETFL, fd_flags | O_APPEND) == -1) return NULL; } -#endif new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE)); if (new_f == NULL) @@ -112,10 +101,7 @@ _IO_old_fdopen (int fd, const char *mode) #endif _IO_old_init (&new_f->fp.file._file, 0); _IO_JUMPS_FILE_plus (&new_f->fp) = &_IO_old_file_jumps; - _IO_old_file_init ((struct _IO_FILE_plus *) &new_f->fp); -#if !_IO_UNIFIED_JUMPTABLES - new_f->fp.vtable = NULL; -#endif + _IO_old_file_init_internal ((struct _IO_FILE_plus *) &new_f->fp); if (_IO_old_file_attach (&new_f->fp.file._file, fd) == NULL) { _IO_un_link ((struct _IO_FILE_plus *) &new_f->fp); @@ -127,7 +113,7 @@ _IO_old_fdopen (int fd, const char *mode) _IO_mask_flags (&new_f->fp.file._file, read_write, _IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING); - return (_IO_FILE *) &new_f->fp; + return (FILE *) &new_f->fp; } strong_alias (_IO_old_fdopen, __old_fdopen) diff --git a/libio/oldiofgetpos.c b/libio/oldiofgetpos.c index eab8c5f9b3..bf3753f86c 100644 --- a/libio/oldiofgetpos.c +++ b/libio/oldiofgetpos.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -32,9 +32,9 @@ int attribute_compat_text_section -_IO_old_fgetpos (_IO_FILE *fp, _IO_fpos_t *posp) +_IO_old_fgetpos (FILE *fp, __fpos_t *posp) { - _IO_off_t pos; + off_t pos; CHECK_FILE (fp, EOF); _IO_acquire_lock (fp); pos = _IO_seekoff_unlocked (fp, 0, _IO_seek_cur, 0); @@ -45,20 +45,16 @@ _IO_old_fgetpos (_IO_FILE *fp, _IO_fpos_t *posp) { /* ANSI explicitly requires setting errno to a positive value on failure. */ -#ifdef EIO if (errno == 0) __set_errno (EIO); -#endif return EOF; } posp->__pos = pos; return 0; } -#ifdef weak_alias compat_symbol (libc, _IO_old_fgetpos, _IO_fgetpos, GLIBC_2_0); strong_alias (_IO_old_fgetpos, __old_fgetpos) compat_symbol (libc, __old_fgetpos, fgetpos, GLIBC_2_0); -#endif #endif diff --git a/libio/oldiofgetpos64.c b/libio/oldiofgetpos64.c index d4e4861056..e542dbfd52 100644 --- a/libio/oldiofgetpos64.c +++ b/libio/oldiofgetpos64.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -32,9 +32,9 @@ int attribute_compat_text_section -_IO_old_fgetpos64 (_IO_FILE *fp, _IO_fpos64_t *posp) +_IO_old_fgetpos64 (FILE *fp, __fpos64_t *posp) { - _IO_off64_t pos; + off64_t pos; CHECK_FILE (fp, EOF); _IO_acquire_lock (fp); pos = _IO_seekoff_unlocked (fp, 0, _IO_seek_cur, 0); @@ -45,20 +45,16 @@ _IO_old_fgetpos64 (_IO_FILE *fp, _IO_fpos64_t *posp) { /* ANSI explicitly requires setting errno to a positive value on failure. */ -#ifdef EIO if (errno == 0) __set_errno (EIO); -#endif return EOF; } posp->__pos = pos; return 0; } -#ifdef weak_alias compat_symbol (libc, _IO_old_fgetpos64, _IO_fgetpos64, GLIBC_2_1); strong_alias (_IO_old_fgetpos64, __old_fgetpos64) compat_symbol (libc, __old_fgetpos64, fgetpos64, GLIBC_2_1); -#endif #endif diff --git a/libio/oldiofopen.c b/libio/oldiofopen.c index cc7c34282c..f0a67104fb 100644 --- a/libio/oldiofopen.c +++ b/libio/oldiofopen.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -32,7 +32,7 @@ #include <stdlib.h> -_IO_FILE * +FILE * attribute_compat_text_section _IO_old_fopen (const char *filename, const char *mode) { @@ -51,12 +51,9 @@ _IO_old_fopen (const char *filename, const char *mode) #endif _IO_old_init (&new_f->fp.file._file, 0); _IO_JUMPS_FILE_plus (&new_f->fp) = &_IO_old_file_jumps; - _IO_old_file_init ((struct _IO_FILE_plus *) &new_f->fp); -#if !_IO_UNIFIED_JUMPTABLES - new_f->fp.vtable = NULL; -#endif - if (_IO_old_file_fopen ((_IO_FILE *) &new_f->fp, filename, mode) != NULL) - return (_IO_FILE *) &new_f->fp; + _IO_old_file_init_internal ((struct _IO_FILE_plus *) &new_f->fp); + if (_IO_old_file_fopen ((FILE *) &new_f->fp, filename, mode) != NULL) + return (FILE *) &new_f->fp; _IO_un_link ((struct _IO_FILE_plus *) &new_f->fp); free (new_f); return NULL; diff --git a/libio/oldiofsetpos.c b/libio/oldiofsetpos.c index e931572717..6e80522b4a 100644 --- a/libio/oldiofsetpos.c +++ b/libio/oldiofsetpos.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -31,7 +31,7 @@ #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2) int attribute_compat_text_section -_IO_old_fsetpos (_IO_FILE *fp, const _IO_fpos_t *posp) +_IO_old_fsetpos (FILE *fp, const __fpos_t *posp) { int result; CHECK_FILE (fp, EOF); @@ -41,10 +41,8 @@ _IO_old_fsetpos (_IO_FILE *fp, const _IO_fpos_t *posp) { /* ANSI explicitly requires setting errno to a positive value on failure. */ -#ifdef EIO if (errno == 0) __set_errno (EIO); -#endif result = EOF; } else @@ -53,10 +51,8 @@ _IO_old_fsetpos (_IO_FILE *fp, const _IO_fpos_t *posp) return result; } -#ifdef weak_alias compat_symbol (libc, _IO_old_fsetpos, _IO_fsetpos, GLIBC_2_0); strong_alias (_IO_old_fsetpos, __old_fsetpos) compat_symbol (libc, __old_fsetpos, fsetpos, GLIBC_2_0); -#endif #endif diff --git a/libio/oldiofsetpos64.c b/libio/oldiofsetpos64.c index f1514c5792..c00931fdba 100644 --- a/libio/oldiofsetpos64.c +++ b/libio/oldiofsetpos64.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -32,7 +32,7 @@ int attribute_compat_text_section -_IO_old_fsetpos64 (_IO_FILE *fp, const _IO_fpos64_t *posp) +_IO_old_fsetpos64 (FILE *fp, const __fpos64_t *posp) { int result; CHECK_FILE (fp, EOF); @@ -42,10 +42,8 @@ _IO_old_fsetpos64 (_IO_FILE *fp, const _IO_fpos64_t *posp) { /* ANSI explicitly requires setting errno to a positive value on failure. */ -#ifdef EIO if (errno == 0) __set_errno (EIO); -#endif result = EOF; } else @@ -54,10 +52,8 @@ _IO_old_fsetpos64 (_IO_FILE *fp, const _IO_fpos64_t *posp) return result; } -#ifdef weak_alias compat_symbol (libc, _IO_old_fsetpos64, _IO_fsetpos64, GLIBC_2_1); strong_alias (_IO_old_fsetpos64, __old_fsetpos64) compat_symbol (libc, __old_fsetpos64, fsetpos64, GLIBC_2_1); -#endif #endif diff --git a/libio/oldiopopen.c b/libio/oldiopopen.c index ea75b4fb90..e47965db0a 100644 --- a/libio/oldiopopen.c +++ b/libio/oldiopopen.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1998-2016 Free Software Foundation, Inc. +/* Copyright (C) 1998-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Written by Per Bothner <bothner@cygnus.com>. @@ -26,77 +26,22 @@ in files containing the exception. */ #define _IO_USE_OLD_IO_FILE -#ifndef _POSIX_SOURCE -# define _POSIX_SOURCE -#endif #include "libioP.h" #include <signal.h> #include <unistd.h> #include <stdlib.h> -#ifdef _LIBC -# include <unistd.h> -#endif +#include <unistd.h> #include <sys/types.h> #include <sys/wait.h> -#ifndef _IO_fork -#ifdef _LIBC -#define _IO_fork __fork -#else -#define _IO_fork fork /* defined in libiberty, if needed */ -#endif -extern _IO_pid_t _IO_fork (void) __THROW; -#endif - #include <shlib-compat.h> #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) -#ifndef _IO_pipe -#ifdef _LIBC -#define _IO_pipe __pipe -#else -#define _IO_pipe pipe -#endif -extern int _IO_pipe (int des[2]) __THROW; -#endif - -#ifndef _IO_dup2 -#ifdef _LIBC -#define _IO_dup2 __dup2 -#else -#define _IO_dup2 dup2 -#endif -extern int _IO_dup2 (int fd, int fd2) __THROW; -#endif - -#ifndef _IO_waitpid -#ifdef _LIBC -#define _IO_waitpid __waitpid -#else -#define _IO_waitpid waitpid -#endif -#endif - -#ifndef _IO_execl -#define _IO_execl execl -#endif -#ifndef _IO__exit -#define _IO__exit _exit -#endif - -#ifndef _IO_close -#ifdef _LIBC -#define _IO_close __close -#else -#define _IO_close close -#endif -#endif - struct _IO_proc_file { struct _IO_FILE_complete_plus file; /* Following fields must match those in class procbuf (procbuf.h) */ - _IO_pid_t pid; + pid_t pid; struct _IO_proc_file *next; }; typedef struct _IO_proc_file _IO_proc_file; @@ -113,17 +58,17 @@ unlock (void *not_used) } #endif -_IO_FILE * +FILE * attribute_compat_text_section -_IO_old_proc_open (_IO_FILE *fp, const char *command, const char *mode) +_IO_old_proc_open (FILE *fp, const char *command, const char *mode) { volatile int read_or_write; volatile int parent_end, child_end; int pipe_fds[2]; - _IO_pid_t child_pid; + pid_t child_pid; if (_IO_file_is_open (fp)) return NULL; - if (_IO_pipe (pipe_fds) < 0) + if (__pipe (pipe_fds) < 0) return NULL; if (mode[0] == 'r' && mode[1] == '\0') { @@ -139,36 +84,36 @@ _IO_old_proc_open (_IO_FILE *fp, const char *command, const char *mode) } else { - _IO_close (pipe_fds[0]); - _IO_close (pipe_fds[1]); + __close (pipe_fds[0]); + __close (pipe_fds[1]); __set_errno (EINVAL); return NULL; } - ((_IO_proc_file *) fp)->pid = child_pid = _IO_fork (); + ((_IO_proc_file *) fp)->pid = child_pid = __fork (); if (child_pid == 0) { int child_std_end = mode[0] == 'r' ? 1 : 0; struct _IO_proc_file *p; - _IO_close (parent_end); + __close (parent_end); if (child_end != child_std_end) { - _IO_dup2 (child_end, child_std_end); - _IO_close (child_end); + __dup2 (child_end, child_std_end); + __close (child_end); } /* POSIX.2: "popen() shall ensure that any streams from previous popen() calls that remain open in the parent process are closed in the new child process." */ for (p = old_proc_file_chain; p; p = p->next) - _IO_close (_IO_fileno ((_IO_FILE *) p)); + __close (_IO_fileno ((FILE *) p)); - _IO_execl ("/bin/sh", "sh", "-c", command, (char *) 0); - _IO__exit (127); + execl ("/bin/sh", "sh", "-c", command, (char *) 0); + _exit (127); } - _IO_close (child_end); + __close (child_end); if (child_pid < 0) { - _IO_close (parent_end); + __close (parent_end); return NULL; } _IO_fileno (fp) = parent_end; @@ -189,7 +134,7 @@ _IO_old_proc_open (_IO_FILE *fp, const char *command, const char *mode) return fp; } -_IO_FILE * +FILE * attribute_compat_text_section _IO_old_popen (const char *command, const char *mode) { @@ -200,7 +145,7 @@ _IO_old_popen (const char *command, const char *mode) _IO_lock_t lock; #endif } *new_f; - _IO_FILE *fp; + FILE *fp; new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE)); if (new_f == NULL) @@ -211,10 +156,7 @@ _IO_old_popen (const char *command, const char *mode) fp = &new_f->fpx.file.file._file; _IO_old_init (fp, 0); _IO_JUMPS_FILE_plus (&new_f->fpx.file) = &_IO_old_proc_jumps; - _IO_old_file_init ((struct _IO_FILE_plus *) &new_f->fpx.file); -#if !_IO_UNIFIED_JUMPTABLES - new_f->fpx.file.vtable = NULL; -#endif + _IO_old_file_init_internal ((struct _IO_FILE_plus *) &new_f->fpx.file); if (_IO_old_proc_open (fp, command, mode) != NULL) return fp; _IO_un_link ((struct _IO_FILE_plus *) &new_f->fpx.file); @@ -224,12 +166,12 @@ _IO_old_popen (const char *command, const char *mode) int attribute_compat_text_section -_IO_old_proc_close (_IO_FILE *fp) +_IO_old_proc_close (FILE *fp) { /* This is not name-space clean. FIXME! */ int wstatus; _IO_proc_file **ptr = &old_proc_file_chain; - _IO_pid_t wait_pid; + pid_t wait_pid; int status = -1; /* Unlink from old_proc_file_chain. */ @@ -251,7 +193,7 @@ _IO_old_proc_close (_IO_FILE *fp) _IO_cleanup_region_end (0); #endif - if (status < 0 || _IO_close (_IO_fileno(fp)) < 0) + if (status < 0 || __close (_IO_fileno(fp)) < 0) return -1; /* POSIX.2 Rationale: "Some historical implementations either block or ignore the signals SIGINT, SIGQUIT, and SIGHUP while waiting @@ -259,7 +201,7 @@ _IO_old_proc_close (_IO_FILE *fp) described in POSIX.2, such implementations are not conforming." */ do { - wait_pid = _IO_waitpid (((_IO_proc_file *) fp)->pid, &wstatus, 0); + wait_pid = __waitpid (((_IO_proc_file *) fp)->pid, &wstatus, 0); } while (wait_pid == -1 && errno == EINTR); if (wait_pid == -1) @@ -267,7 +209,7 @@ _IO_old_proc_close (_IO_FILE *fp) return wstatus; } -const struct _IO_jump_t _IO_old_proc_jumps = { +const struct _IO_jump_t _IO_old_proc_jumps libio_vtable = { JUMP_INIT_DUMMY, JUMP_INIT(finish, _IO_old_file_finish), JUMP_INIT(overflow, _IO_old_file_overflow), diff --git a/libio/oldpclose.c b/libio/oldpclose.c index 13ee2558e7..5934861980 100644 --- a/libio/oldpclose.c +++ b/libio/oldpclose.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1998-2016 Free Software Foundation, Inc. +/* Copyright (C) 1998-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -32,16 +32,13 @@ #include "stdio.h" #include <errno.h> +/* POSIX does not require us to check that a stream passed to pclose() + was created by popen(). Instead we rely on _IO_SYSCLOSE to call + _proc_close when appropriate. */ int attribute_compat_text_section __old_pclose (FILE *fp) { -#if 0 - /* Does not actually test that stream was created by popen(). Instead, - it depends on the filebuf::sys_close() virtual to Do The Right Thing. */ - if (fp is not a proc_file) - return -1; -#endif return _IO_old_fclose (fp); } diff --git a/libio/oldstdfiles.c b/libio/oldstdfiles.c index 609b7d9ef2..f3dda89004 100644 --- a/libio/oldstdfiles.c +++ b/libio/oldstdfiles.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -78,9 +78,9 @@ _IO_check_libio (void) if (&_IO_stdin_used == NULL) { /* We are using the old one. */ - _IO_stdin = stdin = (_IO_FILE *) &_IO_stdin_; - _IO_stdout = stdout = (_IO_FILE *) &_IO_stdout_; - _IO_stderr = stderr = (_IO_FILE *) &_IO_stderr_; + _IO_stdin = stdin = (FILE *) &_IO_stdin_; + _IO_stdout = stdout = (FILE *) &_IO_stdout_; + _IO_stderr = stderr = (FILE *) &_IO_stderr_; _IO_list_all = &_IO_stderr_; _IO_stdin->_vtable_offset = _IO_stdout->_vtable_offset = _IO_stderr->_vtable_offset = stdin->_vtable_offset = diff --git a/libio/oldtmpfile.c b/libio/oldtmpfile.c index 00f14f7a8b..f3a266bced 100644 --- a/libio/oldtmpfile.c +++ b/libio/oldtmpfile.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-2016 Free Software Foundation, Inc. +/* Copyright (C) 1991-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/libio/pclose.c b/libio/pclose.c index 219be57dbd..be7b330ce7 100644 --- a/libio/pclose.c +++ b/libio/pclose.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -29,15 +29,12 @@ #include <errno.h> #include <shlib-compat.h> +/* POSIX does not require us to check that a stream passed to pclose() + was created by popen(). Instead we rely on _IO_SYSCLOSE to call + _proc_close when appropriate. */ int __new_pclose (FILE *fp) { -#if 0 - /* Does not actually test that stream was created by popen(). Instead, - it depends on the filebuf::sys_close() virtual to Do The Right Thing. */ - if (fp is not a proc_file) - return -1; -#endif return _IO_new_fclose (fp); } diff --git a/libio/peekc.c b/libio/peekc.c index 8f33fdeec3..7de76a7cea 100644 --- a/libio/peekc.c +++ b/libio/peekc.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -30,7 +30,7 @@ #undef _IO_peekc int -_IO_peekc_locked (_IO_FILE *fp) +_IO_peekc_locked (FILE *fp) { int result; CHECK_FILE (fp, EOF); diff --git a/libio/putc.c b/libio/putc.c index fd233917b3..13570f579b 100644 --- a/libio/putc.c +++ b/libio/putc.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-2016 Free Software Foundation, Inc. +/* Copyright (C) 1991-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -21,10 +21,12 @@ #undef _IO_putc int -_IO_putc (int c, _IO_FILE *fp) +_IO_putc (int c, FILE *fp) { int result; CHECK_FILE (fp, EOF); + if (!_IO_need_lock (fp)) + return _IO_putc_unlocked (c, fp); _IO_acquire_lock (fp); result = _IO_putc_unlocked (c, fp); _IO_release_lock (fp); @@ -34,11 +36,9 @@ libc_hidden_def (_IO_putc) #undef putc -#ifdef weak_alias weak_alias (_IO_putc, putc) #ifndef _IO_MTSAFE_IO #undef putc_unlocked weak_alias (_IO_putc, putc_unlocked) #endif -#endif diff --git a/libio/putc_u.c b/libio/putc_u.c index 540a6c4cdc..33431fb205 100644 --- a/libio/putc_u.c +++ b/libio/putc_u.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-2016 Free Software Foundation, Inc. +/* Copyright (C) 1991-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -21,8 +21,10 @@ #undef putc_unlocked int -putc_unlocked (int c, _IO_FILE *fp) +__putc_unlocked (int c, FILE *fp) { CHECK_FILE (fp, EOF); return _IO_putc_unlocked (c, fp); } +weak_alias (__putc_unlocked, putc_unlocked) +libc_hidden_weak (putc_unlocked) diff --git a/libio/putchar.c b/libio/putchar.c index 5df3decf57..5286fdccba 100644 --- a/libio/putchar.c +++ b/libio/putchar.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-2016 Free Software Foundation, Inc. +/* Copyright (C) 1991-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/libio/putchar_u.c b/libio/putchar_u.c index 8c41ca3218..869e034809 100644 --- a/libio/putchar_u.c +++ b/libio/putchar_u.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-2016 Free Software Foundation, Inc. +/* Copyright (C) 1991-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/libio/putwc.c b/libio/putwc.c index a5261ea8c4..f74346f3dc 100644 --- a/libio/putwc.c +++ b/libio/putwc.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-2016 Free Software Foundation, Inc. +/* Copyright (C) 1991-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -19,7 +19,7 @@ #include <wchar.h> wint_t -putwc (wchar_t wc, _IO_FILE *fp) +putwc (wchar_t wc, FILE *fp) { wint_t result; CHECK_FILE (fp, WEOF); diff --git a/libio/putwc_u.c b/libio/putwc_u.c index 31bc5f56aa..e73421f692 100644 --- a/libio/putwc_u.c +++ b/libio/putwc_u.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-2016 Free Software Foundation, Inc. +/* Copyright (C) 1991-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -19,7 +19,7 @@ #include <wchar.h> wint_t -putwc_unlocked (wchar_t wc, _IO_FILE *fp) +putwc_unlocked (wchar_t wc, FILE *fp) { CHECK_FILE (fp, WEOF); return _IO_putwc_unlocked (wc, fp); diff --git a/libio/putwchar.c b/libio/putwchar.c index 2534954b4f..44d4bb84e9 100644 --- a/libio/putwchar.c +++ b/libio/putwchar.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-2016 Free Software Foundation, Inc. +/* Copyright (C) 1991-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/libio/putwchar_u.c b/libio/putwchar_u.c index f3c9ef45be..45cf705d6d 100644 --- a/libio/putwchar_u.c +++ b/libio/putwchar_u.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-2016 Free Software Foundation, Inc. +/* Copyright (C) 1991-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/libio/readline.c b/libio/readline.c new file mode 100644 index 0000000000..3372ba2999 --- /dev/null +++ b/libio/readline.c @@ -0,0 +1,170 @@ +/* fgets with ERANGE error reporting and size_t buffer length. + Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <assert.h> +#include <errno.h> +#include <stdio.h> +#include <string.h> + +#include "libioP.h" + +/* Return -1 and set errno to EINVAL if it is ERANGE. */ +static ssize_t +fail_no_erange (void) +{ + if (errno == ERANGE) + __set_errno (EINVAL); + return -1; +} + +/* Slow path for reading the line. Called with no data in the stream + read buffer. Write data to [BUFFER, BUFFER_END). */ +static ssize_t +readline_slow (FILE *fp, char *buffer, char *buffer_end) +{ + char *start = buffer; + + while (buffer < buffer_end) + { + if (__underflow (fp) == EOF) + { + if (_IO_ferror_unlocked (fp)) + /* If the EOF was caused by a read error, report it. */ + return fail_no_erange (); + *buffer = '\0'; + /* Do not include the null terminator. */ + return buffer - start; + } + + /* __underflow has filled the buffer. */ + char *readptr = fp->_IO_read_ptr; + ssize_t readlen = fp->_IO_read_end - readptr; + /* Make sure that __underflow really has acquired some data. */ + assert (readlen > 0); + char *pnl = memchr (readptr, '\n', readlen); + if (pnl != NULL) + { + /* We found the terminator. */ + size_t line_length = pnl - readptr; + if (line_length + 2 > buffer_end - buffer) + /* Not enough room in the caller-supplied buffer. */ + break; + memcpy (buffer, readptr, line_length + 1); + buffer[line_length + 1] = '\0'; + fp->_IO_read_ptr = pnl + 1; + /* Do not include the null terminator. */ + return buffer - start + line_length + 1; + } + + if (readlen >= buffer_end - buffer) + /* Not enough room in the caller-supplied buffer. */ + break; + + /* Save and consume the stream buffer. */ + memcpy (buffer, readptr, readlen); + fp->_IO_read_ptr = fp->_IO_read_end; + buffer += readlen; + } + + /* The line does not fit into the buffer. */ + __set_errno (ERANGE); + return -1; +} + +ssize_t +__libc_readline_unlocked (FILE *fp, char *buffer, size_t buffer_length) +{ + char *buffer_end = buffer + buffer_length; + + /* Orient the stream. */ + if (__builtin_expect (fp->_mode, -1) == 0) + _IO_fwide (fp, -1); + + /* Fast path: The line terminator is found in the buffer. */ + char *readptr = fp->_IO_read_ptr; + ssize_t readlen = fp->_IO_read_end - readptr; + off64_t start_offset; /* File offset before reading anything. */ + if (readlen > 0) + { + char *pnl = memchr (readptr, '\n', readlen); + if (pnl != NULL) + { + size_t line_length = pnl - readptr; + /* Account for line and null terminators. */ + if (line_length + 2 > buffer_length) + { + __set_errno (ERANGE); + return -1; + } + memcpy (buffer, readptr, line_length + 1); + buffer[line_length + 1] = '\0'; + /* Consume the entire line. */ + fp->_IO_read_ptr = pnl + 1; + return line_length + 1; + } + + /* If the buffer does not have enough space for what is pending + in the stream (plus a NUL terminator), the buffer is too + small. */ + if (readlen + 1 > buffer_length) + { + __set_errno (ERANGE); + return -1; + } + + /* End of line not found. We need all the buffered data. Fall + through to the slow path. */ + memcpy (buffer, readptr, readlen); + buffer += readlen; + /* The original length is invalid after this point. Use + buffer_end instead. */ +#pragma GCC poison buffer_length + /* Read the old offset before updating the read pointer. */ + start_offset = __ftello64 (fp); + fp->_IO_read_ptr = fp->_IO_read_end; + } + else + { + readlen = 0; + start_offset = __ftello64 (fp); + } + + /* Slow path: Read more data from the underlying file. We need to + restore the file pointer if the buffer is too small. First, + check if the __ftello64 call above failed. */ + if (start_offset < 0) + return fail_no_erange (); + + ssize_t result = readline_slow (fp, buffer, buffer_end); + if (result < 0) + { + if (errno == ERANGE) + { + /* Restore the file pointer so that the caller may read the + same line again. */ + if (__fseeko64 (fp, start_offset, SEEK_SET) < 0) + return fail_no_erange (); + __set_errno (ERANGE); + } + /* Do not restore the file position on other errors; it is + likely that the __fseeko64 call would fail, too. */ + return -1; + } + return readlen + result; +} +libc_hidden_def (__libc_readline_unlocked) diff --git a/libio/rewind.c b/libio/rewind.c index c93c2e7993..bfb73f1cd7 100644 --- a/libio/rewind.c +++ b/libio/rewind.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -28,7 +28,7 @@ #include <stdio.h> void -rewind (_IO_FILE *fp) +rewind (FILE *fp) { CHECK_FILE (fp, ); _IO_acquire_lock (fp); diff --git a/libio/setbuf.c b/libio/setbuf.c index ae8ca8aaec..fa65e26ef0 100644 --- a/libio/setbuf.c +++ b/libio/setbuf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -28,7 +28,7 @@ #include "stdio.h" void -setbuf (_IO_FILE *fp, char *buf) +setbuf (FILE *fp, char *buf) { - _IO_setbuffer (fp, buf, _IO_BUFSIZ); + _IO_setbuffer (fp, buf, BUFSIZ); } diff --git a/libio/setlinebuf.c b/libio/setlinebuf.c index 1e1bc7d975..a6035b808d 100644 --- a/libio/setlinebuf.c +++ b/libio/setlinebuf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -30,7 +30,7 @@ #undef setlinebuf void -setlinebuf (_IO_FILE *stream) +setlinebuf (FILE *stream) { _IO_setvbuf (stream, NULL, 1, 0); } diff --git a/libio/stdfiles.c b/libio/stdfiles.c index 1f583ed97d..8d96f0b65c 100644 --- a/libio/stdfiles.c +++ b/libio/stdfiles.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -34,35 +34,20 @@ #include "libioP.h" #ifdef _IO_MTSAFE_IO -# if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T -# define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \ +# define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \ static _IO_lock_t _IO_stdfile_##FD##_lock = _IO_lock_initializer; \ static struct _IO_wide_data _IO_wide_data_##FD \ = { ._wide_vtable = &_IO_wfile_jumps }; \ struct _IO_FILE_plus NAME \ = {FILEBUF_LITERAL(CHAIN, FLAGS, FD, &_IO_wide_data_##FD), \ &_IO_file_jumps}; -# else -# define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \ - static _IO_lock_t _IO_stdfile_##FD##_lock = _IO_lock_initializer; \ - struct _IO_FILE_plus NAME \ - = {FILEBUF_LITERAL(CHAIN, FLAGS, FD, NULL), \ - &_IO_file_jumps}; -# endif #else -# if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T -# define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \ +# define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \ static struct _IO_wide_data _IO_wide_data_##FD \ = { ._wide_vtable = &_IO_wfile_jumps }; \ struct _IO_FILE_plus NAME \ = {FILEBUF_LITERAL(CHAIN, FLAGS, FD, &_IO_wide_data_##FD), \ &_IO_file_jumps}; -# else -# define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \ - struct _IO_FILE_plus NAME \ - = {FILEBUF_LITERAL(CHAIN, FLAGS, FD, NULL), \ - &_IO_file_jumps}; -# endif #endif DEF_STDFILE(_IO_2_1_stdin_, 0, 0, _IO_NO_WRITES); diff --git a/libio/stdio.c b/libio/stdio.c index 6de85e88fb..1b7a1bc2e0 100644 --- a/libio/stdio.c +++ b/libio/stdio.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -30,19 +30,17 @@ #undef stdin #undef stdout #undef stderr -_IO_FILE *stdin = (FILE *) &_IO_2_1_stdin_; -_IO_FILE *stdout = (FILE *) &_IO_2_1_stdout_; -_IO_FILE *stderr = (FILE *) &_IO_2_1_stderr_; +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 -#ifdef _LIBC -# define AL(name) AL2 (name, _IO_##name) -# define AL2(name, al) \ +#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); -#endif diff --git a/libio/stdio.h b/libio/stdio.h index d8d7fa0611..739e08610d 100644 --- a/libio/stdio.h +++ b/libio/stdio.h @@ -1,5 +1,5 @@ /* Define ISO C stdio on top of C++ iostreams. - Copyright (C) 1991-2016 Free Software Foundation, Inc. + Copyright (C) 1991-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -21,62 +21,35 @@ */ #ifndef _STDIO_H +#define _STDIO_H 1 -#if !defined __need_FILE && !defined __need___FILE -# define _STDIO_H 1 -# include <features.h> +#define __GLIBC_INTERNAL_STARTING_HEADER_IMPLEMENTATION +#include <bits/libc-header-start.h> __BEGIN_DECLS -# define __need_size_t -# define __need_NULL -# include <stddef.h> +#define __need_size_t +#define __need_NULL +#include <stddef.h> -# include <bits/types.h> -# define __need_FILE -# define __need___FILE -#endif /* Don't need FILE. */ +#define __need___va_list +#include <stdarg.h> +#include <bits/types.h> +#include <bits/types/__fpos_t.h> +#include <bits/types/__fpos64_t.h> +#include <bits/types/__FILE.h> +#include <bits/types/FILE.h> +#include <bits/types/struct_FILE.h> -#if !defined __FILE_defined && defined __need_FILE - -/* Define outside of namespace so the C++ is happy. */ -struct _IO_FILE; - -__BEGIN_NAMESPACE_STD -/* The opaque type of streams. This is the definition used elsewhere. */ -typedef struct _IO_FILE FILE; -__END_NAMESPACE_STD -#if defined __USE_LARGEFILE64 || defined __USE_POSIX \ - || defined __USE_ISOC99 || defined __USE_XOPEN \ - || defined __USE_POSIX2 -__USING_NAMESPACE_STD(FILE) +#ifdef __USE_GNU +# include <bits/types/cookie_io_functions_t.h> #endif -# define __FILE_defined 1 -#endif /* FILE not defined. */ -#undef __need_FILE - - -#if !defined ____FILE_defined && defined __need___FILE - -/* The opaque type of streams. This is the definition used elsewhere. */ -typedef struct _IO_FILE __FILE; - -# define ____FILE_defined 1 -#endif /* __FILE not defined. */ -#undef __need___FILE - - -#ifdef _STDIO_H -#define _STDIO_USES_IOSTREAM - -#include <libio.h> - #if defined __USE_XOPEN || defined __USE_XOPEN2K8 # ifdef __GNUC__ # ifndef _VA_LIST_DEFINED -typedef _G_va_list va_list; +typedef __gnuc_va_list va_list; # define _VA_LIST_DEFINED # endif # else @@ -84,7 +57,7 @@ typedef _G_va_list va_list; # endif #endif -#ifdef __USE_XOPEN2K8 +#if defined __USE_UNIX98 || defined __USE_XOPEN2K # ifndef __off_t_defined # ifndef __USE_FILE_OFFSET64 typedef __off_t off_t; @@ -97,7 +70,9 @@ typedef __off64_t off_t; typedef __off64_t off64_t; # define __off64_t_defined # endif +#endif +#ifdef __USE_XOPEN2K8 # ifndef __ssize_t_defined typedef __ssize_t ssize_t; # define __ssize_t_defined @@ -105,15 +80,13 @@ typedef __ssize_t ssize_t; #endif /* The type of the second argument to `fgetpos' and `fsetpos'. */ -__BEGIN_NAMESPACE_STD #ifndef __USE_FILE_OFFSET64 -typedef _G_fpos_t fpos_t; +typedef __fpos_t fpos_t; #else -typedef _G_fpos64_t fpos_t; +typedef __fpos64_t fpos_t; #endif -__END_NAMESPACE_STD #ifdef __USE_LARGEFILE64 -typedef _G_fpos64_t fpos64_t; +typedef __fpos64_t fpos64_t; #endif /* The possibilities for the third argument to `setvbuf'. */ @@ -123,16 +96,12 @@ typedef _G_fpos64_t fpos64_t; /* Default buffer size. */ -#ifndef BUFSIZ -# define BUFSIZ _IO_BUFSIZ -#endif +#define BUFSIZ 8192 -/* End of file character. - Some things throughout the library rely on this being -1. */ -#ifndef EOF -# define EOF (-1) -#endif +/* The value returned by fgetc and similar functions to indicate the + end of the file. */ +#define EOF (-1) /* The possibilities for the third argument to `fseek'. @@ -165,20 +134,18 @@ typedef _G_fpos64_t fpos64_t; /* Standard streams. */ -extern struct _IO_FILE *stdin; /* Standard input stream. */ -extern struct _IO_FILE *stdout; /* Standard output stream. */ -extern struct _IO_FILE *stderr; /* Standard error output stream. */ +extern FILE *stdin; /* Standard input stream. */ +extern FILE *stdout; /* Standard output stream. */ +extern FILE *stderr; /* Standard error output stream. */ /* C89/C99 say they're macros. Make them happy. */ #define stdin stdin #define stdout stdout #define stderr stderr -__BEGIN_NAMESPACE_STD /* Remove file FILENAME. */ extern int remove (const char *__filename) __THROW; /* Rename file OLD to NEW. */ extern int rename (const char *__old, const char *__new) __THROW; -__END_NAMESPACE_STD #ifdef __USE_ATFILE /* Rename file OLD relative to OLDFD to NEW relative to NEWFD. */ @@ -186,7 +153,18 @@ extern int renameat (int __oldfd, const char *__old, int __newfd, const char *__new) __THROW; #endif -__BEGIN_NAMESPACE_STD +#ifdef __USE_GNU +/* Flags for renameat2. */ +# define RENAME_NOREPLACE (1 << 0) +# define RENAME_EXCHANGE (1 << 1) +# define RENAME_WHITEOUT (1 << 2) + +/* Rename file OLD relative to OLDFD to NEW relative to NEWFD, with + additional flags. */ +extern int renameat2 (int __oldfd, const char *__old, int __newfd, + const char *__new, unsigned int __flags) __THROW; +#endif + /* Create a temporary file and open it read/write. This function is a possible cancellation point and therefore not @@ -207,7 +185,6 @@ extern FILE *tmpfile64 (void) __wur; /* Generate a temporary filename. */ extern char *tmpnam (char *__s) __THROW __wur; -__END_NAMESPACE_STD #ifdef __USE_MISC /* This is the reentrant variant of `tmpnam'. The only difference is @@ -229,7 +206,6 @@ extern char *tempnam (const char *__dir, const char *__pfx) #endif -__BEGIN_NAMESPACE_STD /* Close STREAM. This function is a possible cancellation point and therefore not @@ -240,7 +216,6 @@ extern int fclose (FILE *__stream); This function is a possible cancellation point and therefore not marked with __THROW. */ extern int fflush (FILE *__stream); -__END_NAMESPACE_STD #ifdef __USE_MISC /* Faster versions when locking is not required. @@ -263,7 +238,6 @@ extern int fcloseall (void); #endif -__BEGIN_NAMESPACE_STD #ifndef __USE_FILE_OFFSET64 /* Open a file and create a new stream for it. @@ -292,7 +266,6 @@ extern FILE *__REDIRECT (freopen, (const char *__restrict __filename, # define freopen freopen64 # endif #endif -__END_NAMESPACE_STD #ifdef __USE_LARGEFILE64 extern FILE *fopen64 (const char *__restrict __filename, const char *__restrict __modes) __wur; @@ -311,10 +284,10 @@ extern FILE *fdopen (int __fd, const char *__modes) __THROW __wur; and uses the given functions for input and output. */ extern FILE *fopencookie (void *__restrict __magic_cookie, const char *__restrict __modes, - _IO_cookie_io_functions_t __io_funcs) __THROW __wur; + cookie_io_functions_t __io_funcs) __THROW __wur; #endif -#ifdef __USE_XOPEN2K8 +#if defined __USE_XOPEN2K8 || __GLIBC_USE (LIB_EXT2) /* Create a new stream that refers to a memory buffer. */ extern FILE *fmemopen (void *__s, size_t __len, const char *__modes) __THROW __wur; @@ -326,7 +299,6 @@ extern FILE *open_memstream (char **__bufloc, size_t *__sizeloc) __THROW __wur; #endif -__BEGIN_NAMESPACE_STD /* If BUF is NULL, make STREAM unbuffered. Else make it use buffer BUF, of size BUFSIZ. */ extern void setbuf (FILE *__restrict __stream, char *__restrict __buf) __THROW; @@ -335,7 +307,6 @@ extern void setbuf (FILE *__restrict __stream, char *__restrict __buf) __THROW; else allocate an internal buffer N bytes long. */ extern int setvbuf (FILE *__restrict __stream, char *__restrict __buf, int __modes, size_t __n) __THROW; -__END_NAMESPACE_STD #ifdef __USE_MISC /* If BUF is NULL, make STREAM unbuffered. @@ -348,7 +319,6 @@ extern void setlinebuf (FILE *__stream) __THROW; #endif -__BEGIN_NAMESPACE_STD /* Write formatted output to STREAM. This function is a possible cancellation point and therefore not @@ -369,35 +339,32 @@ extern int sprintf (char *__restrict __s, This function is a possible cancellation point and therefore not marked with __THROW. */ extern int vfprintf (FILE *__restrict __s, const char *__restrict __format, - _G_va_list __arg); + __gnuc_va_list __arg); /* Write formatted output to stdout from argument list ARG. This function is a possible cancellation point and therefore not marked with __THROW. */ -extern int vprintf (const char *__restrict __format, _G_va_list __arg); +extern int vprintf (const char *__restrict __format, __gnuc_va_list __arg); /* Write formatted output to S from argument list ARG. */ extern int vsprintf (char *__restrict __s, const char *__restrict __format, - _G_va_list __arg) __THROWNL; -__END_NAMESPACE_STD + __gnuc_va_list __arg) __THROWNL; #if defined __USE_ISOC99 || defined __USE_UNIX98 -__BEGIN_NAMESPACE_C99 /* Maximum chars of output to write in MAXLEN. */ extern int snprintf (char *__restrict __s, size_t __maxlen, const char *__restrict __format, ...) __THROWNL __attribute__ ((__format__ (__printf__, 3, 4))); extern int vsnprintf (char *__restrict __s, size_t __maxlen, - const char *__restrict __format, _G_va_list __arg) + const char *__restrict __format, __gnuc_va_list __arg) __THROWNL __attribute__ ((__format__ (__printf__, 3, 0))); -__END_NAMESPACE_C99 #endif -#ifdef __USE_GNU +#if __GLIBC_USE (LIB_EXT2) /* Write formatted output to a string dynamically allocated with `malloc'. Store the address of the string in *PTR. */ extern int vasprintf (char **__restrict __ptr, const char *__restrict __f, - _G_va_list __arg) + __gnuc_va_list __arg) __THROWNL __attribute__ ((__format__ (__printf__, 2, 0))) __wur; extern int __asprintf (char **__restrict __ptr, const char *__restrict __fmt, ...) @@ -410,14 +377,13 @@ extern int asprintf (char **__restrict __ptr, #ifdef __USE_XOPEN2K8 /* Write formatted output to a file descriptor. */ extern int vdprintf (int __fd, const char *__restrict __fmt, - _G_va_list __arg) + __gnuc_va_list __arg) __attribute__ ((__format__ (__printf__, 2, 0))); extern int dprintf (int __fd, const char *__restrict __fmt, ...) __attribute__ ((__format__ (__printf__, 2, 3))); #endif -__BEGIN_NAMESPACE_STD /* Read formatted input from STREAM. This function is a possible cancellation point and therefore not @@ -460,28 +426,25 @@ extern int __isoc99_sscanf (const char *__restrict __s, # endif #endif -__END_NAMESPACE_STD - #ifdef __USE_ISOC99 -__BEGIN_NAMESPACE_C99 /* Read formatted input from S into argument list ARG. This function is a possible cancellation point and therefore not marked with __THROW. */ extern int vfscanf (FILE *__restrict __s, const char *__restrict __format, - _G_va_list __arg) + __gnuc_va_list __arg) __attribute__ ((__format__ (__scanf__, 2, 0))) __wur; /* Read formatted input from stdin into argument list ARG. This function is a possible cancellation point and therefore not marked with __THROW. */ -extern int vscanf (const char *__restrict __format, _G_va_list __arg) +extern int vscanf (const char *__restrict __format, __gnuc_va_list __arg) __attribute__ ((__format__ (__scanf__, 1, 0))) __wur; /* Read formatted input from S into argument list ARG. */ extern int vsscanf (const char *__restrict __s, - const char *__restrict __format, _G_va_list __arg) + const char *__restrict __format, __gnuc_va_list __arg) __THROW __attribute__ ((__format__ (__scanf__, 2, 0))); # if !defined __USE_GNU \ @@ -493,37 +456,34 @@ extern int vsscanf (const char *__restrict __s, s, S or [. */ extern int __REDIRECT (vfscanf, (FILE *__restrict __s, - const char *__restrict __format, _G_va_list __arg), + const char *__restrict __format, __gnuc_va_list __arg), __isoc99_vfscanf) __attribute__ ((__format__ (__scanf__, 2, 0))) __wur; extern int __REDIRECT (vscanf, (const char *__restrict __format, - _G_va_list __arg), __isoc99_vscanf) + __gnuc_va_list __arg), __isoc99_vscanf) __attribute__ ((__format__ (__scanf__, 1, 0))) __wur; extern int __REDIRECT_NTH (vsscanf, (const char *__restrict __s, const char *__restrict __format, - _G_va_list __arg), __isoc99_vsscanf) + __gnuc_va_list __arg), __isoc99_vsscanf) __attribute__ ((__format__ (__scanf__, 2, 0))); # else extern int __isoc99_vfscanf (FILE *__restrict __s, const char *__restrict __format, - _G_va_list __arg) __wur; + __gnuc_va_list __arg) __wur; extern int __isoc99_vscanf (const char *__restrict __format, - _G_va_list __arg) __wur; + __gnuc_va_list __arg) __wur; extern int __isoc99_vsscanf (const char *__restrict __s, const char *__restrict __format, - _G_va_list __arg) __THROW; + __gnuc_va_list __arg) __THROW; # define vfscanf __isoc99_vfscanf # define vscanf __isoc99_vscanf # define vsscanf __isoc99_vsscanf # endif # endif - -__END_NAMESPACE_C99 #endif /* Use ISO C9x. */ -__BEGIN_NAMESPACE_STD /* Read a character from STREAM. These functions are possible cancellation points and therefore not @@ -536,13 +496,8 @@ extern int getc (FILE *__stream); This function is a possible cancellation point and therefore not marked with __THROW. */ extern int getchar (void); -__END_NAMESPACE_STD - -/* The C standard explicitly says this is a macro, so we always do the - optimization for it. */ -#define getc(_fp) _IO_getc (_fp) -#ifdef __USE_POSIX +#ifdef __USE_POSIX199506 /* These are defined in POSIX.1:1996. These functions are possible cancellation points and therefore not @@ -562,7 +517,6 @@ extern int fgetc_unlocked (FILE *__stream); #endif /* Use MISC. */ -__BEGIN_NAMESPACE_STD /* Write a character to STREAM. These functions are possible cancellation points and therefore not @@ -578,11 +532,6 @@ extern int putc (int __c, FILE *__stream); This function is a possible cancellation point and therefore not marked with __THROW. */ extern int putchar (int __c); -__END_NAMESPACE_STD - -/* The C standard explicitly says this can be a macro, - so we always do the optimization for it. */ -#define putc(_ch, _fp) _IO_putc (_ch, _fp) #ifdef __USE_MISC /* Faster version when locking is not necessary. @@ -594,7 +543,7 @@ __END_NAMESPACE_STD extern int fputc_unlocked (int __c, FILE *__stream); #endif /* Use MISC. */ -#ifdef __USE_POSIX +#ifdef __USE_POSIX199506 /* These are defined in POSIX.1:1996. These functions are possible cancellation points and therefore not @@ -614,7 +563,6 @@ extern int putw (int __w, FILE *__stream); #endif -__BEGIN_NAMESPACE_STD /* Get a newline-terminated string of finite length from STREAM. This function is a possible cancellation point and therefore not @@ -622,22 +570,18 @@ __BEGIN_NAMESPACE_STD extern char *fgets (char *__restrict __s, int __n, FILE *__restrict __stream) __wur; -#if !defined __USE_ISOC11 \ - || (defined __cplusplus && __cplusplus <= 201103L) +#if __GLIBC_USE (DEPRECATED_GETS) /* Get a newline-terminated string from stdin, removing the newline. - DO NOT USE THIS FUNCTION!! There is no limit on how much it will read. - The function has been officially removed in ISO C11. This opportunity - is used to also remove it from the GNU feature list. It is now only - available when explicitly using an old ISO C, Unix, or POSIX standard. - GCC defines _GNU_SOURCE when building C++ code and the function is still - in C++11, so it is also available for C++. + This function is impossible to use safely. It has been officially + removed from ISO C11 and ISO C++14, and we have also removed it + from the _GNU_SOURCE feature list. It remains available when + explicitly using an old ISO C, Unix, or POSIX standard. This function is a possible cancellation point and therefore not marked with __THROW. */ extern char *gets (char *__s) __wur __attribute_deprecated__; #endif -__END_NAMESPACE_STD #ifdef __USE_GNU /* This function does the same as `fgets' but does not lock the stream. @@ -651,7 +595,7 @@ extern char *fgets_unlocked (char *__restrict __s, int __n, #endif -#ifdef __USE_XOPEN2K8 +#if defined __USE_XOPEN2K8 || __GLIBC_USE (LIB_EXT2) /* Read up to (and including) a DELIMITER from STREAM into *LINEPTR (and null-terminate it). *LINEPTR is a pointer returned from malloc (or NULL), pointing to *N characters of space. It is realloc'd as @@ -662,12 +606,12 @@ extern char *fgets_unlocked (char *__restrict __s, int __n, cancellation point. But due to similarity with an POSIX interface or due to the implementation they are cancellation points and therefore not marked with __THROW. */ -extern _IO_ssize_t __getdelim (char **__restrict __lineptr, - size_t *__restrict __n, int __delimiter, - FILE *__restrict __stream) __wur; -extern _IO_ssize_t getdelim (char **__restrict __lineptr, - size_t *__restrict __n, int __delimiter, - FILE *__restrict __stream) __wur; +extern __ssize_t __getdelim (char **__restrict __lineptr, + size_t *__restrict __n, int __delimiter, + FILE *__restrict __stream) __wur; +extern __ssize_t getdelim (char **__restrict __lineptr, + size_t *__restrict __n, int __delimiter, + FILE *__restrict __stream) __wur; /* Like `getdelim', but reads up to a newline. @@ -675,13 +619,12 @@ extern _IO_ssize_t getdelim (char **__restrict __lineptr, cancellation point. But due to similarity with an POSIX interface or due to the implementation it is a cancellation point and therefore not marked with __THROW. */ -extern _IO_ssize_t getline (char **__restrict __lineptr, - size_t *__restrict __n, - FILE *__restrict __stream) __wur; +extern __ssize_t getline (char **__restrict __lineptr, + size_t *__restrict __n, + FILE *__restrict __stream) __wur; #endif -__BEGIN_NAMESPACE_STD /* Write a string to STREAM. This function is a possible cancellation point and therefore not @@ -714,7 +657,6 @@ extern size_t fread (void *__restrict __ptr, size_t __size, marked with __THROW. */ extern size_t fwrite (const void *__restrict __ptr, size_t __size, size_t __n, FILE *__restrict __s); -__END_NAMESPACE_STD #ifdef __USE_GNU /* This function does the same as `fputs' but does not lock the stream. @@ -741,7 +683,6 @@ extern size_t fwrite_unlocked (const void *__restrict __ptr, size_t __size, #endif -__BEGIN_NAMESPACE_STD /* Seek to a certain position on STREAM. This function is a possible cancellation point and therefore not @@ -757,7 +698,6 @@ extern long int ftell (FILE *__stream) __wur; This function is a possible cancellation point and therefore not marked with __THROW. */ extern void rewind (FILE *__stream); -__END_NAMESPACE_STD /* The Single Unix Specification, Version 2, specifies an alternative, more adequate interface for the two functions above which deal with @@ -789,7 +729,6 @@ extern __off64_t __REDIRECT (ftello, (FILE *__stream), ftello64); # endif #endif -__BEGIN_NAMESPACE_STD #ifndef __USE_FILE_OFFSET64 /* Get STREAM's position. @@ -812,7 +751,6 @@ extern int __REDIRECT (fsetpos, # define fsetpos fsetpos64 # endif #endif -__END_NAMESPACE_STD #ifdef __USE_LARGEFILE64 extern int fseeko64 (FILE *__stream, __off64_t __off, int __whence); @@ -821,14 +759,12 @@ extern int fgetpos64 (FILE *__restrict __stream, fpos64_t *__restrict __pos); extern int fsetpos64 (FILE *__stream, const fpos64_t *__pos); #endif -__BEGIN_NAMESPACE_STD /* Clear the error and EOF indicators for STREAM. */ extern void clearerr (FILE *__stream) __THROW; /* Return the EOF indicator for STREAM. */ extern int feof (FILE *__stream) __THROW __wur; /* Return the error indicator for STREAM. */ extern int ferror (FILE *__stream) __THROW __wur; -__END_NAMESPACE_STD #ifdef __USE_MISC /* Faster versions when locking is not required. */ @@ -838,13 +774,11 @@ extern int ferror_unlocked (FILE *__stream) __THROW __wur; #endif -__BEGIN_NAMESPACE_STD /* Print a message describing the meaning of the value of errno. This function is a possible cancellation point and therefore not marked with __THROW. */ extern void perror (const char *__s); -__END_NAMESPACE_STD /* Provide the declarations for `sys_errlist' and `sys_nerr' if they are available on this system. Even if available, these variables @@ -885,7 +819,7 @@ extern char *ctermid (char *__s) __THROW; #endif /* Use POSIX. */ -#ifdef __USE_XOPEN +#if (defined __USE_XOPEN && !defined __USE_XOPEN2K) || defined __USE_GNU /* Return the name of the current user. */ extern char *cuserid (char *__s); #endif /* Use X/Open, but not issue 6. */ @@ -900,12 +834,12 @@ extern int obstack_printf (struct obstack *__restrict __obstack, __THROWNL __attribute__ ((__format__ (__printf__, 2, 3))); extern int obstack_vprintf (struct obstack *__restrict __obstack, const char *__restrict __format, - _G_va_list __args) + __gnuc_va_list __args) __THROWNL __attribute__ ((__format__ (__printf__, 2, 0))); #endif /* Use GNU. */ -#ifdef __USE_POSIX +#ifdef __USE_POSIX199506 /* These are defined in POSIX.1:1996. */ /* Acquire ownership of STREAM. */ @@ -920,12 +854,15 @@ extern void funlockfile (FILE *__stream) __THROW; #endif /* POSIX */ #if defined __USE_XOPEN && !defined __USE_XOPEN2K && !defined __USE_GNU -/* The X/Open standard requires some functions and variables to be - declared here which do not belong into this header. But we have to - follow. In GNU mode we don't do this nonsense. */ -# define __need_getopt -# include <getopt.h> -#endif /* X/Open, but not issue 6 and not for GNU. */ +/* X/Open Issues 1-5 required getopt to be declared in this + header. It was removed in Issue 6. GNU follows Issue 6. */ +# include <bits/getopt_posix.h> +#endif + +/* Slow-path routines used by the optimized inline functions in + bits/stdio.h. */ +extern int __uflow (FILE *); +extern int __overflow (FILE *, int); /* If we are compiling with optimizing read this file. It contains several optimizing inline functions and macros. */ @@ -942,5 +879,3 @@ extern void funlockfile (FILE *__stream) __THROW; __END_DECLS #endif /* <stdio.h> included. */ - -#endif /* !_STDIO_H */ diff --git a/libio/strfile.h b/libio/strfile.h index f7ada8eb22..75caac2af5 100644 --- a/libio/strfile.h +++ b/libio/strfile.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -24,18 +24,19 @@ This exception applies to code released by its copyright holders in files containing the exception. */ -#include <libio.h> -#ifdef TODO -Merge into libio.h ? -#endif +#include <stdio.h> +#include "libioP.h" -typedef void *(*_IO_alloc_type) (_IO_size_t); +typedef void *(*_IO_alloc_type) (size_t); typedef void (*_IO_free_type) (void*); struct _IO_str_fields { - _IO_alloc_type _allocate_buffer; - _IO_free_type _free_buffer; + /* These members are preserved for ABI compatibility. The glibc + implementation always calls malloc/free for user buffers if + _IO_USER_BUF or _IO_FLAGS2_USER_WBUF are not set. */ + _IO_alloc_type _allocate_buffer_unused; + _IO_free_type _free_buffer_unused; }; /* This is needed for the Irix6 N32 ABI, which has a 64 bit off_t type, @@ -45,7 +46,7 @@ struct _IO_str_fields struct _IO_streambuf { - struct _IO_FILE _f; + FILE _f; const struct _IO_jump_t *vtable; }; @@ -55,13 +56,9 @@ typedef struct _IO_strfile_ struct _IO_str_fields _s; } _IO_strfile; -/* dynamic: set when the array object is allocated (or reallocated) as - necessary to hold a character sequence that can change in length. */ -#define _IO_STR_DYNAMIC(FP) ((FP)->_s._allocate_buffer != (_IO_alloc_type)0) - /* frozen: set when the program has requested that the array object not be altered, reallocated, or freed. */ -#define _IO_STR_FROZEN(FP) ((FP)->_f._IO_file_flags & _IO_USER_BUF) +#define _IO_STR_FROZEN(FP) ((FP)->_f._flags & _IO_USER_BUF) typedef struct { diff --git a/libio/strops.c b/libio/strops.c index 0932d4c1b1..df8268b7ab 100644 --- a/libio/strops.c +++ b/libio/strops.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -31,15 +31,15 @@ #include <stdio_ext.h> void -_IO_str_init_static_internal (_IO_strfile *sf, char *ptr, _IO_size_t size, +_IO_str_init_static_internal (_IO_strfile *sf, char *ptr, size_t size, char *pstart) { - _IO_FILE *fp = &sf->_sbf._f; + FILE *fp = &sf->_sbf._f; char *end; if (size == 0) end = __rawmemchr (ptr, '\0'); - else if ((_IO_size_t) ptr + size > (_IO_size_t) ptr) + else if ((size_t) ptr + size > (size_t) ptr) end = ptr + size; else end = (char *) -1; @@ -61,7 +61,7 @@ _IO_str_init_static_internal (_IO_strfile *sf, char *ptr, _IO_size_t size, fp->_IO_read_end = end; } /* A null _allocate_buffer function flags the strfile as being static. */ - sf->_s._allocate_buffer = (_IO_alloc_type) 0; + sf->_s._allocate_buffer_unused = (_IO_alloc_type) 0; } void @@ -74,14 +74,14 @@ void _IO_str_init_readonly (_IO_strfile *sf, const char *ptr, int size) { _IO_str_init_static_internal (sf, (char *) ptr, size < 0 ? -1 : size, NULL); - sf->_sbf._f._IO_file_flags |= _IO_NO_WRITES; + sf->_sbf._f._flags |= _IO_NO_WRITES; } int -_IO_str_overflow (_IO_FILE *fp, int c) +_IO_str_overflow (FILE *fp, int c) { int flush_only = c == EOF; - _IO_size_t pos; + size_t pos; if (fp->_flags & _IO_NO_WRITES) return flush_only ? 0 : EOF; if ((fp->_flags & _IO_TIED_PUT_GET) && !(fp->_flags & _IO_CURRENTLY_PUTTING)) @@ -91,7 +91,7 @@ _IO_str_overflow (_IO_FILE *fp, int c) fp->_IO_read_ptr = fp->_IO_read_end; } pos = fp->_IO_write_ptr - fp->_IO_write_base; - if (pos >= (_IO_size_t) (_IO_blen (fp) + flush_only)) + if (pos >= (size_t) (_IO_blen (fp) + flush_only)) { if (fp->_flags & _IO_USER_BUF) /* not allowed to enlarge */ return EOF; @@ -100,11 +100,10 @@ _IO_str_overflow (_IO_FILE *fp, int c) char *new_buf; char *old_buf = fp->_IO_buf_base; size_t old_blen = _IO_blen (fp); - _IO_size_t new_size = 2 * old_blen + 100; + size_t new_size = 2 * old_blen + 100; if (new_size < old_blen) return EOF; - new_buf - = (char *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (new_size); + new_buf = malloc (new_size); if (new_buf == NULL) { /* __ferror(fp) = 1; */ @@ -113,7 +112,7 @@ _IO_str_overflow (_IO_FILE *fp, int c) if (old_buf) { memcpy (new_buf, old_buf, old_blen); - (*((_IO_strfile *) fp)->_s._free_buffer) (old_buf); + free (old_buf); /* Make sure _IO_setb won't try to delete _IO_buf_base. */ fp->_IO_buf_base = NULL; } @@ -139,7 +138,7 @@ _IO_str_overflow (_IO_FILE *fp, int c) libc_hidden_def (_IO_str_overflow) int -_IO_str_underflow (_IO_FILE *fp) +_IO_str_underflow (FILE *fp) { if (fp->_IO_write_ptr > fp->_IO_read_end) fp->_IO_read_end = fp->_IO_write_ptr; @@ -158,8 +157,8 @@ libc_hidden_def (_IO_str_underflow) /* The size of the valid part of the buffer. */ -_IO_ssize_t -_IO_str_count (_IO_FILE *fp) +ssize_t +_IO_str_count (FILE *fp) { return ((fp->_IO_write_ptr > fp->_IO_read_end ? fp->_IO_write_ptr : fp->_IO_read_end) @@ -168,29 +167,28 @@ _IO_str_count (_IO_FILE *fp) static int -enlarge_userbuf (_IO_FILE *fp, _IO_off64_t offset, int reading) +enlarge_userbuf (FILE *fp, off64_t offset, int reading) { - if ((_IO_ssize_t) offset <= _IO_blen (fp)) + if ((ssize_t) offset <= _IO_blen (fp)) return 0; - _IO_ssize_t oldend = fp->_IO_write_end - fp->_IO_write_base; + ssize_t oldend = fp->_IO_write_end - fp->_IO_write_base; /* Try to enlarge the buffer. */ if (fp->_flags & _IO_USER_BUF) /* User-provided buffer. */ return 1; - _IO_size_t newsize = offset + 100; + size_t newsize = offset + 100; char *oldbuf = fp->_IO_buf_base; - char *newbuf - = (char *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (newsize); + char *newbuf = malloc (newsize); if (newbuf == NULL) return 1; if (oldbuf != NULL) { memcpy (newbuf, oldbuf, _IO_blen (fp)); - (*((_IO_strfile *) fp)->_s._free_buffer) (oldbuf); + free (oldbuf); /* Make sure _IO_setb won't try to delete _IO_buf_base. */ fp->_IO_buf_base = NULL; @@ -230,74 +228,103 @@ enlarge_userbuf (_IO_FILE *fp, _IO_off64_t offset, int reading) return 0; } +static void +_IO_str_switch_to_get_mode (FILE *fp) +{ + if (_IO_in_backup (fp)) + fp->_IO_read_base = fp->_IO_backup_base; + else + { + fp->_IO_read_base = fp->_IO_buf_base; + if (fp->_IO_write_ptr > fp->_IO_read_end) + fp->_IO_read_end = fp->_IO_write_ptr; + } + fp->_IO_read_ptr = fp->_IO_read_end = fp->_IO_write_ptr; -_IO_off64_t -_IO_str_seekoff (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode) + fp->_flags &= ~_IO_CURRENTLY_PUTTING; +} + +off64_t +_IO_str_seekoff (FILE *fp, off64_t offset, int dir, int mode) { - _IO_off64_t new_pos; + off64_t new_pos; if (mode == 0 && (fp->_flags & _IO_TIED_PUT_GET)) mode = (fp->_flags & _IO_CURRENTLY_PUTTING ? _IOS_OUTPUT : _IOS_INPUT); + bool was_writing = (fp->_IO_write_ptr > fp->_IO_write_base + || _IO_in_put_mode (fp)); + if (was_writing) + _IO_str_switch_to_get_mode (fp); + if (mode == 0) { - /* Don't move any pointers. But there is no clear indication what - mode FP is in. Let's guess. */ - if (fp->_IO_file_flags & _IO_NO_WRITES) - new_pos = fp->_IO_read_ptr - fp->_IO_read_base; - else - new_pos = fp->_IO_write_ptr - fp->_IO_write_base; + new_pos = fp->_IO_read_ptr - fp->_IO_read_base; } else { - _IO_ssize_t cur_size = _IO_str_count(fp); + ssize_t cur_size = _IO_str_count(fp); new_pos = EOF; /* Move the get pointer, if requested. */ if (mode & _IOS_INPUT) { + ssize_t base; switch (dir) { - case _IO_seek_end: - offset += cur_size; + case _IO_seek_set: + base = 0; break; case _IO_seek_cur: - offset += fp->_IO_read_ptr - fp->_IO_read_base; + base = fp->_IO_read_ptr - fp->_IO_read_base; break; - default: /* case _IO_seek_set: */ + default: /* case _IO_seek_end: */ + base = cur_size; break; } - if (offset < 0) - return EOF; - if ((_IO_ssize_t) offset > cur_size - && enlarge_userbuf (fp, offset, 1) != 0) + ssize_t maxval = SSIZE_MAX - base; + if (offset < -base || offset > maxval) + { + __set_errno (EINVAL); + return EOF; + } + base += offset; + if (base > cur_size + && enlarge_userbuf (fp, base, 1) != 0) return EOF; - fp->_IO_read_ptr = fp->_IO_read_base + offset; + fp->_IO_read_ptr = fp->_IO_read_base + base; fp->_IO_read_end = fp->_IO_read_base + cur_size; - new_pos = offset; + new_pos = base; } /* Move the put pointer, if requested. */ if (mode & _IOS_OUTPUT) { + ssize_t base; switch (dir) { - case _IO_seek_end: - offset += cur_size; + case _IO_seek_set: + base = 0; break; case _IO_seek_cur: - offset += fp->_IO_write_ptr - fp->_IO_write_base; + base = fp->_IO_write_ptr - fp->_IO_write_base; break; - default: /* case _IO_seek_set: */ + default: /* case _IO_seek_end: */ + base = cur_size; break; } - if (offset < 0) - return EOF; - if ((_IO_ssize_t) offset > cur_size - && enlarge_userbuf (fp, offset, 0) != 0) + ssize_t maxval = SSIZE_MAX - base; + if (offset < -base || offset > maxval) + { + __set_errno (EINVAL); + return EOF; + } + base += offset; + if (base > cur_size + && enlarge_userbuf (fp, base, 0) != 0) return EOF; - fp->_IO_write_ptr = fp->_IO_write_base + offset; - new_pos = offset; + fp->_IO_write_ptr = fp->_IO_write_base + base; + new_pos = base; } } return new_pos; @@ -305,7 +332,7 @@ _IO_str_seekoff (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode) libc_hidden_def (_IO_str_seekoff) int -_IO_str_pbackfail (_IO_FILE *fp, int c) +_IO_str_pbackfail (FILE *fp, int c) { if ((fp->_flags & _IO_NO_WRITES) && c != EOF) return EOF; @@ -314,16 +341,16 @@ _IO_str_pbackfail (_IO_FILE *fp, int c) libc_hidden_def (_IO_str_pbackfail) void -_IO_str_finish (_IO_FILE *fp, int dummy) +_IO_str_finish (FILE *fp, int dummy) { if (fp->_IO_buf_base && !(fp->_flags & _IO_USER_BUF)) - (((_IO_strfile *) fp)->_s._free_buffer) (fp->_IO_buf_base); + free (fp->_IO_buf_base); fp->_IO_buf_base = NULL; _IO_default_finish (fp, 0); } -const struct _IO_jump_t _IO_str_jumps = +const struct _IO_jump_t _IO_str_jumps libio_vtable = { JUMP_INIT_DUMMY, JUMP_INIT(finish, _IO_str_finish), diff --git a/libio/swprintf.c b/libio/swprintf.c index 398d7f201f..10f722d035 100644 --- a/libio/swprintf.c +++ b/libio/swprintf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-2016 Free Software Foundation, Inc. +/* Copyright (C) 1991-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/libio/swscanf.c b/libio/swscanf.c index 8d71c5834e..c8686bcbaf 100644 --- a/libio/swscanf.c +++ b/libio/swscanf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-2016 Free Software Foundation, Inc. +/* Copyright (C) 1991-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/libio/test-fmemopen.c b/libio/test-fmemopen.c index 1e52e86ce5..fbc9f51a62 100644 --- a/libio/test-fmemopen.c +++ b/libio/test-fmemopen.c @@ -1,5 +1,5 @@ /* Test for fmemopen implementation. - Copyright (C) 2000-2016 Free Software Foundation, Inc. + Copyright (C) 2000-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Hanno Mueller, kontakt@hanno.de, 2000. diff --git a/libio/test-freopen.c b/libio/test-freopen.c index 9d36326d2b..2e274f4899 100644 --- a/libio/test-freopen.c +++ b/libio/test-freopen.c @@ -1,5 +1,5 @@ /* Test for freopen implementation. - Copyright (C) 2000-2016 Free Software Foundation, Inc. + Copyright (C) 2000-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/libio/test-freopen.sh b/libio/test-freopen.sh index 5db163fb4b..190a7a4dfe 100755 --- a/libio/test-freopen.sh +++ b/libio/test-freopen.sh @@ -1,6 +1,6 @@ #!/bin/sh # Test of freopen. -# Copyright (C) 2000-2016 Free Software Foundation, Inc. +# Copyright (C) 2000-2018 Free Software Foundation, Inc. # This file is part of the GNU C Library. # The GNU C Library is free software; you can redistribute it and/or diff --git a/libio/tst-bz22415.c b/libio/tst-bz22415.c new file mode 100644 index 0000000000..dd163997c3 --- /dev/null +++ b/libio/tst-bz22415.c @@ -0,0 +1,97 @@ +/* Check static buffer handling with setvbuf (BZ #22415) + + Copyright (C) 2017-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdio.h> +#include <stdlib.h> +#include <wchar.h> +#include <mcheck.h> + +#include <support/check.h> +#include <support/temp_file.h> + +static int +do_test (void) +{ + mtrace (); + + char *temp_file; + TEST_VERIFY_EXIT (create_temp_file ("tst-bz22145.", &temp_file)); + + char buf[BUFSIZ]; + + { + /* Check if backup buffer is correctly freed and changing back + to normal buffer does not trigger an invalid free in case of + static buffer set by setvbuf. */ + + FILE *f = fopen (temp_file, "w+b"); + TEST_VERIFY_EXIT (f != NULL); + + TEST_VERIFY_EXIT (setvbuf (f, buf, _IOFBF, BUFSIZ) == 0); + TEST_VERIFY_EXIT (ungetc ('x', f) == 'x'); + TEST_VERIFY_EXIT (fseek (f, 0L, SEEK_SET) == 0); + TEST_VERIFY_EXIT (fputc ('y', f) == 'y'); + + TEST_VERIFY_EXIT (fclose (f) == 0); + } + + { + /* Check if backup buffer is correctly freed and changing back + to normal buffer does not trigger an invalid free in case of + static buffer set by setvbuf. */ + + FILE *f = fopen (temp_file, "w+b"); + TEST_VERIFY_EXIT (f != NULL); + + TEST_VERIFY_EXIT (setvbuf (f, buf, _IOFBF, BUFSIZ) == 0); + TEST_VERIFY_EXIT (ungetc ('x', f) == 'x'); + TEST_VERIFY_EXIT (fputc ('y', f) == 'y'); + + TEST_VERIFY_EXIT (fclose (f) == 0); + } + + { + FILE *f = fopen (temp_file, "w+b"); + TEST_VERIFY_EXIT (f != NULL); + + TEST_VERIFY_EXIT (setvbuf (f, buf, _IOFBF, BUFSIZ) == 0); + TEST_VERIFY_EXIT (ungetwc (L'x', f) == L'x'); + TEST_VERIFY_EXIT (fseek (f, 0L, SEEK_SET) == 0); + TEST_VERIFY_EXIT (fputwc (L'y', f) == L'y'); + + TEST_VERIFY_EXIT (fclose (f) == 0); + } + + { + FILE *f = fopen (temp_file, "w+b"); + TEST_VERIFY_EXIT (f != NULL); + + TEST_VERIFY_EXIT (setvbuf (f, buf, _IOFBF, BUFSIZ) == 0); + TEST_VERIFY_EXIT (ungetwc (L'x', f) == L'x'); + TEST_VERIFY_EXIT (fputwc (L'y', f) == L'y'); + + TEST_VERIFY_EXIT (fclose (f) == 0); + } + + free (temp_file); + + return 0; +} + +#include <support/test-driver.c> diff --git a/libio/tst-fgetc-after-eof.c b/libio/tst-fgetc-after-eof.c new file mode 100644 index 0000000000..81c9cc9940 --- /dev/null +++ b/libio/tst-fgetc-after-eof.c @@ -0,0 +1,109 @@ +/* Bug 1190: EOF conditions are supposed to be sticky. + Copyright (C) 2018 Free Software Foundation. + Copying and distribution of this file, with or without modification, + are permitted in any medium without royalty provided the copyright + notice and this notice are preserved. This file is offered as-is, + without any warranty. */ + +/* ISO C1999 specification of fgetc: + + #include <stdio.h> + int fgetc (FILE *stream); + + Description + + If the end-of-file indicator for the input stream pointed to by + stream is not set and a next character is present, the fgetc + function obtains that character as an unsigned char converted to + an int and advances the associated file position indicator for + the stream (if defined). + + Returns + + If the end-of-file indicator for the stream is set, or if the + stream is at end-of-file, the end-of-file indicator for the + stream is set and the fgetc function returns EOF. Otherwise, the + fgetc function returns the next character from the input stream + pointed to by stream. If a read error occurs, the error indicator + for the stream is set and the fgetc function returns EOF. + + The requirement to return EOF "if the end-of-file indicator for the + stream is set" was new in C99; the language in the 1989 edition of + the standard was ambiguous. Historically, BSD-derived Unix always + had the C99 behavior, whereas in System V fgetc would attempt to + call read() again before returning EOF again. Prior to version 2.28, + glibc followed the System V behavior even though this does not + comply with C99. + + See + <https://sourceware.org/bugzilla/show_bug.cgi?id=1190>, + <https://sourceware.org/bugzilla/show_bug.cgi?id=19476>, + and the thread at + <https://sourceware.org/ml/libc-alpha/2012-09/msg00343.html> + for more detail. */ + +#include <support/tty.h> +#include <support/check.h> + +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#define XWRITE(fd, s, msg) do { \ + if (write (fd, s, sizeof s - 1) != sizeof s - 1) \ + { \ + perror ("write " msg); \ + return 1; \ + } \ + } while (0) + +int +do_test (void) +{ + /* The easiest way to set up the conditions under which you can + notice whether the end-of-file indicator is sticky, is with a + pseudo-tty. This is also the case which applications are most + likely to care about. And it avoids any question of whether and + how it is legitimate to access the same physical file with two + independent FILE objects. */ + int outer_fd, inner_fd; + FILE *fp; + + support_openpty (&outer_fd, &inner_fd, 0, 0, 0); + fp = fdopen (inner_fd, "r+"); + if (!fp) + { + perror ("fdopen"); + return 1; + } + + XWRITE (outer_fd, "abc\n\004", "first line + EOF"); + TEST_COMPARE (fgetc (fp), 'a'); + TEST_COMPARE (fgetc (fp), 'b'); + TEST_COMPARE (fgetc (fp), 'c'); + TEST_COMPARE (fgetc (fp), '\n'); + TEST_COMPARE (fgetc (fp), EOF); + + TEST_VERIFY_EXIT (feof (fp)); + TEST_VERIFY_EXIT (!ferror (fp)); + + XWRITE (outer_fd, "d\n", "second line"); + + /* At this point, there is a new full line of input waiting in the + kernelside input buffer, but we should still observe EOF from + stdio, because the end-of-file indicator has not been cleared. */ + TEST_COMPARE (fgetc (fp), EOF); + + /* Clearing EOF should reveal the next line of input. */ + clearerr (fp); + TEST_COMPARE (fgetc (fp), 'd'); + TEST_COMPARE (fgetc (fp), '\n'); + + fclose (fp); + close (outer_fd); + return 0; +} + +#include <support/test-driver.c> diff --git a/libio/tst-fopenloc.c b/libio/tst-fopenloc.c index 0f7edb64e9..59f63d27fc 100644 --- a/libio/tst-fopenloc.c +++ b/libio/tst-fopenloc.c @@ -1,5 +1,5 @@ /* Test for ,ccs= handling in fopen. - Copyright (C) 2001-2016 Free Software Foundation, Inc. + Copyright (C) 2001-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 2001. @@ -26,9 +26,13 @@ #include <wchar.h> #include <sys/resource.h> - static const char inputfile[] = "../iconvdata/testdata/ISO-8859-1"; +static int do_test(void); + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" + static int do_bz17916 (void) { @@ -39,7 +43,7 @@ do_bz17916 (void) setrlimit (RLIMIT_STACK, &rl); const size_t sz = 2 * 1024 * 1024; - char *ccs = malloc (sz); + char *ccs = xmalloc (sz); strcpy (ccs, "r,ccs="); memset (ccs + 6, 'A', sz - 6 - 1); ccs[sz - 1] = '\0'; @@ -85,6 +89,3 @@ do_test (void) return do_bz17916 (); } - -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" diff --git a/libio/tst-fputws.c b/libio/tst-fputws.c index dc4e870576..7ee5762c83 100644 --- a/libio/tst-fputws.c +++ b/libio/tst-fputws.c @@ -1,5 +1,5 @@ /* Test that we can write a multibyte character to an unbuffered stream. - Copyright (C) 2014-2016 Free Software Foundation, Inc. + Copyright (C) 2014-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/libio/tst-freopen.c b/libio/tst-freopen.c index a1579bbd57..772aef29a0 100644 --- a/libio/tst-freopen.c +++ b/libio/tst-freopen.c @@ -1,5 +1,5 @@ /* Test freopen with mmap stdio. - Copyright (C) 2002-2016 Free Software Foundation, Inc. + Copyright (C) 2002-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Jakub Jelinek <jakub@redhat.com>, 2002. @@ -22,84 +22,91 @@ #include <string.h> #include <unistd.h> -static int -do_test (void) +#include <support/check.h> +#include <support/temp_file.h> + +static int fd; +static char *name; + +static void +do_prepare (int argc, char *argv[]) +{ + fd = create_temp_file ("tst-freopen.", &name); + TEST_VERIFY_EXIT (fd != -1); +} + +#define PREPARE do_prepare + +/* Basic tests for freopen. */ +static void +do_test_basic (void) { - char name[] = "/tmp/tst-freopen.XXXXXX"; const char * const test = "Let's test freopen.\n"; char temp[strlen (test) + 1]; - int fd = mkstemp (name); - FILE *f; - - if (fd == -1) - { - printf ("%u: cannot open temporary file: %m\n", __LINE__); - exit (1); - } - f = fdopen (fd, "w"); + FILE *f = fdopen (fd, "w"); if (f == NULL) - { - printf ("%u: cannot fdopen temporary file: %m\n", __LINE__); - exit (1); - } + FAIL_EXIT1 ("fdopen: %m"); fputs (test, f); fclose (f); f = fopen (name, "r"); if (f == NULL) - { - printf ("%u: cannot fopen temporary file: %m\n", __LINE__); - exit (1); - } + FAIL_EXIT1 ("fopen: %m"); if (fread (temp, 1, strlen (test), f) != strlen (test)) - { - printf ("%u: couldn't read the file back: %m\n", __LINE__); - exit (1); - } + FAIL_EXIT1 ("fread: %m"); temp [strlen (test)] = '\0'; if (strcmp (test, temp)) - { - printf ("%u: read different string than was written:\n%s%s", - __LINE__, test, temp); - exit (1); - } + FAIL_EXIT1 ("read different string than was written: (%s, %s)", + test, temp); f = freopen (name, "r+", f); if (f == NULL) - { - printf ("%u: cannot freopen temporary file: %m\n", __LINE__); - exit (1); - } + FAIL_EXIT1 ("freopen: %m"); if (fseek (f, 0, SEEK_SET) != 0) - { - printf ("%u: couldn't fseek to start: %m\n", __LINE__); - exit (1); - } + FAIL_EXIT1 ("fseek: %m"); if (fread (temp, 1, strlen (test), f) != strlen (test)) - { - printf ("%u: couldn't read the file back: %m\n", __LINE__); - exit (1); - } + FAIL_EXIT1 ("fread: %m"); temp [strlen (test)] = '\0'; if (strcmp (test, temp)) - { - printf ("%u: read different string than was written:\n%s%s", - __LINE__, test, temp); - exit (1); - } + FAIL_EXIT1 ("read different string than was written: (%s, %s)", + test, temp); fclose (f); +} + +/* Test for BZ#21398, where it tries to freopen stdio after the close + of its file descriptor. */ +static void +do_test_bz21398 (void) +{ + (void) close (STDIN_FILENO); + + FILE *f = freopen (name, "r", stdin); + if (f == NULL) + FAIL_EXIT1 ("freopen: %m"); + + TEST_VERIFY_EXIT (ferror (f) == 0); + + char buf[128]; + char *ret = fgets (buf, sizeof (buf), stdin); + TEST_VERIFY_EXIT (ret != NULL); + TEST_VERIFY_EXIT (ferror (f) == 0); +} + +static int +do_test (void) +{ + do_test_basic (); + do_test_bz21398 (); - unlink (name); - exit (0); + return 0; } -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" +#include <support/test-driver.c> diff --git a/libio/tst-fseek.c b/libio/tst-fseek.c index 9bb0d7f707..7831527593 100644 --- a/libio/tst-fseek.c +++ b/libio/tst-fseek.c @@ -1,5 +1,5 @@ /* Verify that fseek/ftell combination works for wide chars. - Copyright (C) 2012-2016 Free Software Foundation, Inc. + Copyright (C) 2012-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -24,9 +24,7 @@ #include <unistd.h> #include <string.h> -/* Defined in test-skeleton.c. */ -static int create_temp_file (const char *base, char **filename); - +#include <support/temp_file.h> static int do_seek_end (FILE *fp) @@ -168,6 +166,4 @@ do_test (void) return ret; } - -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" +#include <support/test-driver.c> diff --git a/libio/tst-ftell-active-handler.c b/libio/tst-ftell-active-handler.c index 0620895260..7840d5d73e 100644 --- a/libio/tst-ftell-active-handler.c +++ b/libio/tst-ftell-active-handler.c @@ -1,6 +1,6 @@ /* Verify that ftell returns the correct value at various points before and after the handler on which it is called becomes active. - Copyright (C) 2014-2016 Free Software Foundation, Inc. + Copyright (C) 2014-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/libio/tst-ftell-append.c b/libio/tst-ftell-append.c index 1fd949e60a..07a2f234d2 100644 --- a/libio/tst-ftell-append.c +++ b/libio/tst-ftell-append.c @@ -1,6 +1,6 @@ /* Verify that ftell returns the correct value after a read and a write on a file opened in a+ mode. - Copyright (C) 2014-2016 Free Software Foundation, Inc. + Copyright (C) 2014-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/libio/tst-ftell-partial-wide.c b/libio/tst-ftell-partial-wide.c index f694f1f1b7..5b2f8af0f9 100644 --- a/libio/tst-ftell-partial-wide.c +++ b/libio/tst-ftell-partial-wide.c @@ -1,6 +1,6 @@ /* Verify that ftell does not go into an infinite loop when a conversion fails due to insufficient space in the buffer. - Copyright (C) 2014-2016 Free Software Foundation, Inc. + Copyright (C) 2014-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/libio/tst-fwrite-error.c b/libio/tst-fwrite-error.c index 9bc740eed3..a8d91d9160 100644 --- a/libio/tst-fwrite-error.c +++ b/libio/tst-fwrite-error.c @@ -1,5 +1,5 @@ /* Test of fwrite() function, adapted from gnulib-tests in grep. - Copyright (C) 2011-2016 Free Software Foundation, Inc. + Copyright (C) 2011-2018 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -18,6 +18,7 @@ #include <fcntl.h> #include <unistd.h> #include <stdio.h> +#include <stdlib.h> static int do_test (void) diff --git a/libio/tst-memstream1.c b/libio/tst-memstream1.c index d18f5cc22a..adc2aec257 100644 --- a/libio/tst-memstream1.c +++ b/libio/tst-memstream1.c @@ -1,5 +1,6 @@ #include <mcheck.h> #include <stdio.h> +#include <stdlib.h> #ifndef CHAR_T diff --git a/libio/tst-memstream2.c b/libio/tst-memstream2.c index cbea4b2f97..d3874faaad 100644 --- a/libio/tst-memstream2.c +++ b/libio/tst-memstream2.c @@ -1,5 +1,6 @@ #include <mcheck.h> #include <stdio.h> +#include <stdlib.h> #ifndef CHAR_T diff --git a/libio/tst-memstream3.c b/libio/tst-memstream3.c new file mode 100644 index 0000000000..bb3300dc57 --- /dev/null +++ b/libio/tst-memstream3.c @@ -0,0 +1,167 @@ +/* Test for open_memstream implementation. + Copyright (C) 2016-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <mcheck.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> +#include <errno.h> + + +#ifndef CHAR_T +# define CHAR_T char +# define W(o) o +# define OPEN_MEMSTREAM open_memstream +# define PRINTF printf +# define FWRITE_FUNC fwrite +# define FPUTC fputc +# define STRCMP strcmp +#endif + +#define S(s) S1 (s) +#define S1(s) #s + +static void +mcheck_abort (enum mcheck_status ev) +{ + printf ("mecheck failed with status %d\n", (int) ev); + exit (1); +} + +static void +error_printf (int line, const char *fmt, ...) +{ + va_list ap; + + printf ("error: %s:%i: ", __FILE__, line); + va_start (ap, fmt); + vprintf (fmt, ap); + va_end (ap); +} + +#define ERROR_RET1(...) \ + { error_printf(__LINE__, __VA_ARGS__); return 1; } + +static int +do_test_bz18241 (void) +{ + CHAR_T *buf; + size_t size; + + FILE *fp = OPEN_MEMSTREAM (&buf, &size); + if (fp == NULL) + ERROR_RET1 ("%s failed\n", S(OPEN_MEMSTREAM)); + + if (FPUTC (W('a'), fp) != W('a')) + ERROR_RET1 ("%s failed (errno = %d)\n", S(FPUTC), errno); + if (fflush (fp) != 0) + ERROR_RET1 ("fflush failed (errno = %d)\n", errno); + if (fseek (fp, -2, SEEK_SET) != -1) + ERROR_RET1 ("fseek failed (errno = %d)\n", errno); + if (errno != EINVAL) + ERROR_RET1 ("errno != EINVAL\n"); + if (ftell (fp) != 1) + ERROR_RET1 ("ftell failed (errno = %d)\n", errno); + if (ferror (fp) != 0) + ERROR_RET1 ("ferror != 0\n"); + + if (fseek (fp, -1, SEEK_CUR) == -1) + ERROR_RET1 ("fseek failed (errno = %d)\n", errno); + if (ftell (fp) != 0) + ERROR_RET1 ("ftell failed (errno = %d)\n", errno); + if (ferror (fp) != 0) + ERROR_RET1 ("ferror != 0\n"); + if (FPUTC (W('b'), fp) != W('b')) + ERROR_RET1 ("%s failed (errno = %d)\n", S(FPUTC), errno); + if (fflush (fp) != 0) + ERROR_RET1 ("fflush failed (errno = %d)\n", errno); + + if (fclose (fp) != 0) + ERROR_RET1 ("fclose failed (errno = %d\n", errno); + + if (STRCMP (buf, W("b")) != 0) + ERROR_RET1 ("%s failed\n", S(STRCMP)); + + free (buf); + + return 0; +} + +static int +do_test_bz20181 (void) +{ + CHAR_T *buf; + size_t size; + size_t ret; + + FILE *fp = OPEN_MEMSTREAM (&buf, &size); + if (fp == NULL) + ERROR_RET1 ("%s failed\n", S(OPEN_MEMSTREAM)); + + if ((ret = FWRITE_FUNC (W("abc"), 1, 3, fp)) != 3) + ERROR_RET1 ("%s failed (errno = %d)\n", S(FWRITE_FUNC), errno); + + if (fseek (fp, 0, SEEK_SET) != 0) + ERROR_RET1 ("fseek failed (errno = %d)\n", errno); + + if (FWRITE_FUNC (W("z"), 1, 1, fp) != 1) + ERROR_RET1 ("%s failed (errno = %d)\n", S(FWRITE_FUNC), errno); + + if (fflush (fp) != 0) + ERROR_RET1 ("fflush failed (errno = %d)\n", errno); + + /* Avoid truncating the buffer on close. */ + if (fseek (fp, 3, SEEK_SET) != 0) + ERROR_RET1 ("fseek failed (errno = %d)\n", errno); + + if (fclose (fp) != 0) + ERROR_RET1 ("fclose failed (errno = %d\n", errno); + + if (size != 3) + ERROR_RET1 ("size != 3\n"); + + if (buf[0] != W('z') + || buf[1] != W('b') + || buf[2] != W('c')) + { + PRINTF (W("error: buf {%c,%c,%c} != {z,b,c}\n"), + buf[0], buf[1], buf[2]); + return 1; + } + + free (buf); + + return 0; +} + +static int +do_test (void) +{ + int ret = 0; + + mcheck_pedantic (mcheck_abort); + + ret += do_test_bz18241 (); + ret += do_test_bz20181 (); + + return ret; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/libio/tst-mmap-eofsync.c b/libio/tst-mmap-eofsync.c index e8ef727148..0c568e8eb5 100644 --- a/libio/tst-mmap-eofsync.c +++ b/libio/tst-mmap-eofsync.c @@ -60,7 +60,6 @@ do_test (void) printf ("feof = %d, ferror = %d immediately after fgets\n", feof (f), ferror (f)); -#if 1 c = fgetc (f); if (c == EOF) printf ("fgetc -> EOF (feof = %d, ferror = %d)\n", @@ -71,7 +70,6 @@ do_test (void) c, feof (f), ferror (f)); result = 1; } -#endif c = write (temp_fd, text2, sizeof text2 - 1); if (c == sizeof text2 - 1) diff --git a/libio/tst-mmap-setvbuf.c b/libio/tst-mmap-setvbuf.c index 33d60b7bd4..dcbc62e057 100644 --- a/libio/tst-mmap-setvbuf.c +++ b/libio/tst-mmap-setvbuf.c @@ -1,5 +1,5 @@ /* Test setvbuf on readonly fopen (using mmap stdio). - Copyright (C) 2002-2016 Free Software Foundation, Inc. + Copyright (C) 2002-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Jakub Jelinek <jakub@redhat.com>, 2002. diff --git a/libio/tst-mmap2-eofsync.c b/libio/tst-mmap2-eofsync.c index f3699656ab..05dedb8c20 100644 --- a/libio/tst-mmap2-eofsync.c +++ b/libio/tst-mmap2-eofsync.c @@ -20,7 +20,7 @@ static char *pages; static void do_prepare (void) { - pages = malloc (getpagesize () * 2); + pages = xmalloc (getpagesize () * 2); memset (pages, 'a', getpagesize ()); memset (pages + getpagesize (), 'b', getpagesize ()); diff --git a/libio/tst-readline.c b/libio/tst-readline.c new file mode 100644 index 0000000000..9322ef68da --- /dev/null +++ b/libio/tst-readline.c @@ -0,0 +1,236 @@ +/* Test the __libc_readline_unlocked function. + Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +/* Exercise __libc_readline_unlocked with various combinations of line + lengths, stdio buffer sizes, and line read buffer sizes. */ + +#include <errno.h> +#include <stdbool.h> +#include <stdio.h> +#include <string.h> +#include <support/check.h> +#include <support/support.h> +#include <support/temp_file.h> +#include <support/test-driver.h> +#include <support/xmemstream.h> +#include <support/xstdio.h> +#include <support/xunistd.h> + +enum + { + maximum_line_length = 7, + number_of_lines = 3, + }; + +/* -1: Do not set buffer size. 0: unbuffered. Otherwise, use this as + the size of the buffer. */ +static int buffer_size; + +/* These size of the buffer used for reading. Must be at least 2. */ +static int read_size; + +/* If a read files with ERANGE, increase the buffer size by this + amount. Must be positive. */ +static int read_size_increment; + +/* If non-zero, do not reset the read size after an ERANGE error. */ +static int read_size_preserve; + +/* If non-zero, no '\n' at the end of the file. */ +static int no_newline_at_eof; + +/* Length of the line, or -1 if the line is not present. */ +static int line_lengths[number_of_lines]; + +/* The name of the test file. */ +static char *test_file_path; + +/* The contents of the test file. */ +static char expected_contents[(maximum_line_length + 2) * number_of_lines + 1]; +static size_t expected_length; + +/* Returns a random byte which is not zero or the line terminator. */ +static char +random_char (void) +{ + static unsigned int rand_state = 1; + while (true) + { + char result = rand_r (&rand_state) >> 16; + if (result != 0 && result != '\n') + return result; + } +} + +/* Create the test file. */ +static void +prepare (int argc, char **argv) +{ + int fd = create_temp_file ("tst-readline-", &test_file_path); + TEST_VERIFY_EXIT (fd >= 0); + xclose (fd); +} + +/* Prepare the test file. Return false if the test parameters are + incongruent and the test should be skipped. */ +static bool +write_test_file (void) +{ + expected_length = 0; + char *p = expected_contents; + for (int lineno = 0; lineno < number_of_lines; ++lineno) + for (int i = 0; i < line_lengths[lineno]; ++i) + *p++ = random_char (); + expected_length = p - &expected_contents[0]; + if (no_newline_at_eof) + { + if (expected_length == 0) + return false; + --expected_length; + --p; + } + if (test_verbose > 0) + { + printf ("info: writing test file of %zu bytes:\n", expected_length); + for (int i = 0; i < number_of_lines; ++i) + printf (" line %d: %d\n", i, line_lengths[i]); + if (no_newline_at_eof) + puts (" (no newline at EOF)"); + } + TEST_VERIFY_EXIT (expected_length < sizeof (expected_contents)); + *p++ = '\0'; + support_write_file_string (test_file_path, expected_contents); + return true; +} + +/* Run a single test (a combination of a test file and read + parameters). */ +static void +run_test (void) +{ + TEST_VERIFY_EXIT (read_size_increment > 0); + if (test_verbose > 0) + { + printf ("info: running test: buffer_size=%d read_size=%d\n" + " read_size_increment=%d read_size_preserve=%d\n", + buffer_size, read_size, read_size_increment, read_size_preserve); + } + + struct xmemstream result; + xopen_memstream (&result); + + FILE *fp = xfopen (test_file_path, "rce"); + char *fp_buffer = NULL; + if (buffer_size == 0) + TEST_VERIFY_EXIT (setvbuf (fp, NULL, _IONBF, 0) == 0); + if (buffer_size > 0) + { + fp_buffer = xmalloc (buffer_size); + TEST_VERIFY_EXIT (setvbuf (fp, fp_buffer, _IOFBF, buffer_size) == 0); + } + + char *line_buffer = xmalloc (read_size); + size_t line_buffer_size = read_size; + + while (true) + { + ssize_t ret = __libc_readline_unlocked + (fp, line_buffer, line_buffer_size); + if (ret < 0) + { + TEST_VERIFY (ret == -1); + if (errno != ERANGE) + FAIL_EXIT1 ("__libc_readline_unlocked: %m"); + line_buffer_size += read_size_increment; + free (line_buffer); + line_buffer = xmalloc (line_buffer_size); + /* Try reading this line again. */ + } + else if (ret == 0) + break; + else + { + /* A line has been read. Save it. */ + TEST_VERIFY (ret == strlen (line_buffer)); + const char *pnl = strchr (line_buffer, '\n'); + /* If there is a \n, it must be at the end. */ + TEST_VERIFY (pnl == NULL || pnl == line_buffer + ret - 1); + fputs (line_buffer, result.out); + + /* Restore the original read size if required. */ + if (line_buffer_size > read_size && !read_size_preserve) + { + line_buffer_size = read_size; + free (line_buffer); + line_buffer = xmalloc (line_buffer_size); + } + } + } + + xfclose (fp); + free (fp_buffer); + free (line_buffer); + + xfclose_memstream (&result); + TEST_VERIFY (result.length == expected_length); + TEST_VERIFY (strcmp (result.buffer, expected_contents) == 0); + if (test_verbose > 0) + { + printf ("info: expected (%zu): [[%s]]\n", + expected_length, expected_contents); + printf ("info: actual (%zu): [[%s]]\n", result.length, result.buffer); + } + free (result.buffer); +} + +/* Test one test file with multiple read parameters. */ +static void +test_one_file (void) +{ + for (buffer_size = -1; buffer_size <= maximum_line_length + 1; ++buffer_size) + for (read_size = 2; read_size <= maximum_line_length + 2; ++read_size) + for (read_size_increment = 1; read_size_increment <= 4; + ++read_size_increment) + for (read_size_preserve = 0; read_size_preserve < 2; + ++read_size_preserve) + run_test (); +} + + +static int +do_test (void) +{ + /* Set up the test file contents. */ + for (line_lengths[0] = -1; line_lengths[0] <= maximum_line_length; + ++line_lengths[0]) + for (line_lengths[1] = -1; line_lengths[1] <= maximum_line_length; + ++line_lengths[1]) + for (line_lengths[2] = -1; line_lengths[2] <= maximum_line_length; + ++line_lengths[2]) + for (no_newline_at_eof = 0; no_newline_at_eof < 2; ++no_newline_at_eof) + { + if (!write_test_file ()) + continue; + test_one_file (); + } + free (test_file_path); + return 0; +} + +#define PREPARE prepare +#include <support/test-driver.c> diff --git a/libio/tst-vtables-common.c b/libio/tst-vtables-common.c new file mode 100644 index 0000000000..5e31012069 --- /dev/null +++ b/libio/tst-vtables-common.c @@ -0,0 +1,513 @@ +/* Test for libio vtables and their validation. Common code. + Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +/* This test provides some coverage for how various stdio functions + use the vtables in FILE * objects. The focus is mostly on which + functions call which methods, not so much on validating data + processing. An initial series of tests check that custom vtables + do not work without activation through _IO_init. + + Note: libio vtables are deprecated feature. Do not use this test + as a documentation source for writing custom vtables. See + fopencookie for a different way of creating custom stdio + streams. */ + +#include <stdbool.h> +#include <string.h> +#include <support/capture_subprocess.h> +#include <support/check.h> +#include <support/namespace.h> +#include <support/support.h> +#include <support/test-driver.h> +#include <support/xunistd.h> + +#include "libioP.h" + +/* Data shared between the test subprocess and the test driver in the + parent. Note that *shared is reset at the start of the check_call + function. */ +struct shared +{ + /* Expected file pointer for method calls. */ + FILE *fp; + + /* If true, assume that a call to _IO_init is needed to enable + custom vtables. */ + bool initially_disabled; + + /* Requested return value for the methods which have one. */ + int return_value; + + /* A value (usually a character) recorded by some of the methods + below. */ + int value; + + /* Likewise, for some data. */ + char buffer[16]; + size_t buffer_length; + + /* Total number of method calls. */ + unsigned int calls; + + /* Individual method call counts. */ + unsigned int calls_finish; + unsigned int calls_overflow; + unsigned int calls_underflow; + unsigned int calls_uflow; + unsigned int calls_pbackfail; + unsigned int calls_xsputn; + unsigned int calls_xsgetn; + unsigned int calls_seekoff; + unsigned int calls_seekpos; + unsigned int calls_setbuf; + unsigned int calls_sync; + unsigned int calls_doallocate; + unsigned int calls_read; + unsigned int calls_write; + unsigned int calls_seek; + unsigned int calls_close; + unsigned int calls_stat; + unsigned int calls_showmanyc; + unsigned int calls_imbue; +} *shared; + +/* Method implementations which increment the counters in *shared. */ + +static void +log_method (FILE *fp, const char *name) +{ + if (test_verbose > 0) + printf ("info: %s (%p) called\n", name, fp); +} + +static void +method_finish (FILE *fp, int dummy) +{ + log_method (fp, __func__); + TEST_VERIFY (fp == shared->fp); + ++shared->calls; + ++shared->calls_finish; +} + +static int +method_overflow (FILE *fp, int ch) +{ + log_method (fp, __func__); + TEST_VERIFY (fp == shared->fp); + ++shared->calls; + ++shared->calls_overflow; + shared->value = ch; + return shared->return_value; +} + +static int +method_underflow (FILE *fp) +{ + log_method (fp, __func__); + TEST_VERIFY (fp == shared->fp); + ++shared->calls; + ++shared->calls_underflow; + return shared->return_value; +} + +static int +method_uflow (FILE *fp) +{ + log_method (fp, __func__); + TEST_VERIFY (fp == shared->fp); + ++shared->calls; + ++shared->calls_uflow; + return shared->return_value; +} + +static int +method_pbackfail (FILE *fp, int ch) +{ + log_method (fp, __func__); + TEST_VERIFY (fp == shared->fp); + ++shared->calls; + ++shared->calls_pbackfail; + shared->value = ch; + return shared->return_value; +} + +static size_t +method_xsputn (FILE *fp, const void *data, size_t n) +{ + log_method (fp, __func__); + TEST_VERIFY (fp == shared->fp); + ++shared->calls; + ++shared->calls_xsputn; + + size_t to_copy = n; + if (n > sizeof (shared->buffer)) + to_copy = sizeof (shared->buffer); + memcpy (shared->buffer, data, to_copy); + shared->buffer_length = to_copy; + return to_copy; +} + +static size_t +method_xsgetn (FILE *fp, void *data, size_t n) +{ + log_method (fp, __func__); + TEST_VERIFY (fp == shared->fp); + ++shared->calls; + ++shared->calls_xsgetn; + return 0; +} + +static off64_t +method_seekoff (FILE *fp, off64_t offset, int dir, int mode) +{ + log_method (fp, __func__); + TEST_VERIFY (fp == shared->fp); + ++shared->calls; + ++shared->calls_seekoff; + return shared->return_value; +} + +static off64_t +method_seekpos (FILE *fp, off64_t offset, int mode) +{ + log_method (fp, __func__); + TEST_VERIFY (fp == shared->fp); + ++shared->calls; + ++shared->calls_seekpos; + return shared->return_value; +} + +static FILE * +method_setbuf (FILE *fp, char *buffer, ssize_t length) +{ + log_method (fp, __func__); + TEST_VERIFY (fp == shared->fp); + ++shared->calls; + ++shared->calls_setbuf; + return fp; +} + +static int +method_sync (FILE *fp) +{ + log_method (fp, __func__); + TEST_VERIFY (fp == shared->fp); + ++shared->calls; + ++shared->calls_sync; + return shared->return_value; +} + +static int +method_doallocate (FILE *fp) +{ + log_method (fp, __func__); + TEST_VERIFY (fp == shared->fp); + ++shared->calls; + ++shared->calls_doallocate; + return shared->return_value; +} + +static ssize_t +method_read (FILE *fp, void *data, ssize_t length) +{ + log_method (fp, __func__); + TEST_VERIFY (fp == shared->fp); + ++shared->calls; + ++shared->calls_read; + return shared->return_value; +} + +static ssize_t +method_write (FILE *fp, const void *data, ssize_t length) +{ + log_method (fp, __func__); + TEST_VERIFY (fp == shared->fp); + ++shared->calls; + ++shared->calls_write; + return shared->return_value; +} + +static off64_t +method_seek (FILE *fp, off64_t offset, int mode) +{ + log_method (fp, __func__); + TEST_VERIFY (fp == shared->fp); + ++shared->calls; + ++shared->calls_seek; + return shared->return_value; +} + +static int +method_close (FILE *fp) +{ + log_method (fp, __func__); + TEST_VERIFY (fp == shared->fp); + ++shared->calls; + ++shared->calls_close; + return shared->return_value; +} + +static int +method_stat (FILE *fp, void *buffer) +{ + log_method (fp, __func__); + TEST_VERIFY (fp == shared->fp); + ++shared->calls; + ++shared->calls_stat; + return shared->return_value; +} + +static int +method_showmanyc (FILE *fp) +{ + log_method (fp, __func__); + TEST_VERIFY (fp == shared->fp); + ++shared->calls; + ++shared->calls_showmanyc; + return shared->return_value; +} + +static void +method_imbue (FILE *fp, void *locale) +{ + log_method (fp, __func__); + TEST_VERIFY (fp == shared->fp); + ++shared->calls; + ++shared->calls_imbue; +} + +/* Our custom vtable. */ + +static const struct _IO_jump_t jumps = +{ + JUMP_INIT_DUMMY, + JUMP_INIT (finish, method_finish), + JUMP_INIT (overflow, method_overflow), + JUMP_INIT (underflow, method_underflow), + JUMP_INIT (uflow, method_uflow), + JUMP_INIT (pbackfail, method_pbackfail), + JUMP_INIT (xsputn, method_xsputn), + JUMP_INIT (xsgetn, method_xsgetn), + JUMP_INIT (seekoff, method_seekoff), + JUMP_INIT (seekpos, method_seekpos), + JUMP_INIT (setbuf, method_setbuf), + JUMP_INIT (sync, method_sync), + JUMP_INIT (doallocate, method_doallocate), + JUMP_INIT (read, method_read), + JUMP_INIT (write, method_write), + JUMP_INIT (seek, method_seek), + JUMP_INIT (close, method_close), + JUMP_INIT (stat, method_stat), + JUMP_INIT (showmanyc, method_showmanyc), + JUMP_INIT (imbue, method_imbue) +}; + +/* Our file implementation. */ + +struct my_file +{ + FILE f; + const struct _IO_jump_t *vtable; +}; + +struct my_file +my_file_create (void) +{ + return (struct my_file) + { + /* Disable locking, so that we do not have to set up a lock + pointer. */ + .f._flags = _IO_USER_LOCK, + + /* Copy the offset from the an initialized handle, instead of + figuring it out from scratch. */ + .f._vtable_offset = stdin->_vtable_offset, + + .vtable = &jumps, + }; +} + +/* Initial tests which do not enable vtable compatibility. */ + +/* Inhibit GCC optimization of fprintf. */ +typedef int (*fprintf_type) (FILE *, const char *, ...); +static const volatile fprintf_type fprintf_ptr = &fprintf; + +static void +without_compatibility_fprintf (void *closure) +{ + /* This call should abort. */ + fprintf_ptr (shared->fp, " "); + _exit (1); +} + +static void +without_compatibility_fputc (void *closure) +{ + /* This call should abort. */ + fputc (' ', shared->fp); + _exit (1); +} + +static void +without_compatibility_fgetc (void *closure) +{ + /* This call should abort. */ + fgetc (shared->fp); + _exit (1); +} + +static void +without_compatibility_fflush (void *closure) +{ + /* This call should abort. */ + fflush (shared->fp); + _exit (1); +} + +/* Exit status after abnormal termination. */ +static int termination_status; + +static void +init_termination_status (void) +{ + pid_t pid = xfork (); + if (pid == 0) + abort (); + xwaitpid (pid, &termination_status, 0); + + TEST_VERIFY (WIFSIGNALED (termination_status)); + TEST_COMPARE (WTERMSIG (termination_status), SIGABRT); +} + +static void +check_for_termination (const char *name, void (*callback) (void *)) +{ + struct my_file file = my_file_create (); + shared->fp = &file.f; + shared->return_value = -1; + shared->calls = 0; + struct support_capture_subprocess proc + = support_capture_subprocess (callback, NULL); + support_capture_subprocess_check (&proc, name, termination_status, + sc_allow_stderr); + const char *message + = "Fatal error: glibc detected an invalid stdio handle\n"; + TEST_COMPARE_BLOB (proc.err.buffer, proc.err.length, + message, strlen (message)); + TEST_COMPARE (shared->calls, 0); + support_capture_subprocess_free (&proc); +} + +/* The test with vtable validation disabled. */ + +/* This function does not have a prototype in libioP.h to prevent + accidental use from within the library (which would disable vtable + verification). */ +void _IO_init (FILE *fp, int flags); + +static void +with_compatibility_fprintf (void *closure) +{ + TEST_COMPARE (fprintf_ptr (shared->fp, "A%sCD", "B"), 4); + TEST_COMPARE (shared->calls, 3); + TEST_COMPARE (shared->calls_xsputn, 3); + TEST_COMPARE_BLOB (shared->buffer, shared->buffer_length, + "CD", 2); +} + +static void +with_compatibility_fputc (void *closure) +{ + shared->return_value = '@'; + TEST_COMPARE (fputc ('@', shared->fp), '@'); + TEST_COMPARE (shared->calls, 1); + TEST_COMPARE (shared->calls_overflow, 1); + TEST_COMPARE (shared->value, '@'); +} + +static void +with_compatibility_fgetc (void *closure) +{ + shared->return_value = 'X'; + TEST_COMPARE (fgetc (shared->fp), 'X'); + TEST_COMPARE (shared->calls, 1); + TEST_COMPARE (shared->calls_uflow, 1); +} + +static void +with_compatibility_fflush (void *closure) +{ + TEST_COMPARE (fflush (shared->fp), 0); + TEST_COMPARE (shared->calls, 1); + TEST_COMPARE (shared->calls_sync, 1); +} + +/* Call CALLBACK in a subprocess, after setting up a custom file + object and updating shared->fp. */ +static void +check_call (const char *name, void (*callback) (void *), + bool initially_disabled) +{ + *shared = (struct shared) + { + .initially_disabled = initially_disabled, + }; + + /* Set up a custom file object. */ + struct my_file file = my_file_create (); + shared->fp = &file.f; + if (shared->initially_disabled) + _IO_init (shared->fp, file.f._flags); + + if (test_verbose > 0) + printf ("info: calling test %s\n", name); + support_isolate_in_subprocess (callback, NULL); +} + +/* Run the tests. INITIALLY_DISABLED indicates whether custom vtables + are disabled when the test starts. */ +static int +run_tests (bool initially_disabled) +{ + /* The test relies on fatal error messages being printed to standard + error. */ + setenv ("LIBC_FATAL_STDERR_", "1", 1); + + shared = support_shared_allocate (sizeof (*shared)); + shared->initially_disabled = initially_disabled; + init_termination_status (); + + if (initially_disabled) + { + check_for_termination ("fprintf", without_compatibility_fprintf); + check_for_termination ("fputc", without_compatibility_fputc); + check_for_termination ("fgetc", without_compatibility_fgetc); + check_for_termination ("fflush", without_compatibility_fflush); + } + + check_call ("fprintf", with_compatibility_fprintf, initially_disabled); + check_call ("fputc", with_compatibility_fputc, initially_disabled); + check_call ("fgetc", with_compatibility_fgetc, initially_disabled); + check_call ("fflush", with_compatibility_fflush, initially_disabled); + + support_shared_free (shared); + shared = NULL; + + return 0; +} diff --git a/libio/tst-vtables-interposed.c b/libio/tst-vtables-interposed.c new file mode 100644 index 0000000000..aaa5a84e0a --- /dev/null +++ b/libio/tst-vtables-interposed.c @@ -0,0 +1,36 @@ +/* Test for libio vtables and their validation. Enabled through interposition. + Copyright (C) 2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include "tst-vtables-common.c" + +/* Provide an interposed definition of the standard file handles with + our own vtable. stdout/stdin/stderr will not work as a result, but + a succesful test does not print anything, so this is fine. */ +#define _IO_file_jumps jumps +#include "stdfiles.c" + +static int +do_test (void) +{ + return run_tests (false); +} + +/* Calling setvbuf in the test driver is not supported with our + interposed file handles. */ +#define TEST_NO_SETVBUF +#include <support/test-driver.c> diff --git a/libio/bits/libio-ldbl.h b/libio/tst-vtables.c index 15c5af9b78..c31a552f61 100644 --- a/libio/bits/libio-ldbl.h +++ b/libio/tst-vtables.c @@ -1,5 +1,5 @@ -/* -mlong-double-64 compatibility mode for libio functions. - Copyright (C) 2006-2016 Free Software Foundation, Inc. +/* Test for libio vtables and their validation. Initially disabled case. + Copyright (C) 2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -16,9 +16,12 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ -#ifndef _IO_STDIO_H -# error "Never include <bits/libio-ldbl.h> directly; use <libio.h> instead." -#endif +#include "tst-vtables-common.c" -__LDBL_REDIR_DECL (_IO_vfscanf) -__LDBL_REDIR_DECL (_IO_vfprintf) +static int +do_test (void) +{ + return run_tests (true); +} + +#include <support/test-driver.c> diff --git a/libio/tst-widetext.c b/libio/tst-widetext.c index 0f934370f8..82eb217b31 100644 --- a/libio/tst-widetext.c +++ b/libio/tst-widetext.c @@ -1,6 +1,6 @@ /* Test program for the wide character stream functions handling larger amounts of text. - Copyright (C) 2000-2016 Free Software Foundation, Inc. + Copyright (C) 2000-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>. diff --git a/libio/tst-widetext.input b/libio/tst-widetext.input index b4382c0008..1ff1bf6083 100644 --- a/libio/tst-widetext.input +++ b/libio/tst-widetext.input @@ -111,7 +111,7 @@ Devanagari (U+0900-U+097F): ऀ◌ँ◌ंःऄअआइईउऊऋऌऍऎएऐऑऒओऔकखगघङचछजझञटठडढणतथदधनऩपफबभमयरऱलळऴवशषसहऺऻ◌़ऽाि ी◌ु◌ू◌ृ◌ॄ◌ॅ◌ॆ◌े◌ैॉॊोौ◌्ॎॏॐ◌॑◌॒◌॓◌॔ॕॖॗक़ख़ग़ज़ड़ढ़फ़य़ॠॡ◌ॢ◌ॣ।॥०१२३४५६७८९॰ॱॲॳॴॵॶॷॸॹॺॻॼॽॾॿ -Bengali (U+0980-U+09FF): +Bangla (U+0980-U+09FF): ঀ◌ঁংঃঅআইঈউঊঋঌএঐওঔকখগঘঙচছজঝঞটঠডঢণতথদধনপফবভমযরলশষসহ◌়ঽাি ী◌ু◌ূ◌ৃ◌ৄেৈোৌ◌্ৎৗড়ঢ়য়ৠৡ◌ৢ◌ৣ০১২৩৪৫৬৭৮৯ৰৱ৲৳৴৵৶৷৸৹৺৻ৼ৽৾ diff --git a/libio/tst-wmemstream3.c b/libio/tst-wmemstream3.c new file mode 100644 index 0000000000..f24f0facc6 --- /dev/null +++ b/libio/tst-wmemstream3.c @@ -0,0 +1,44 @@ +/* Test for open_memstream implementation. + Copyright (C) 2016-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <wchar.h> + +/* Straighforward implementation so tst-memstream3 could use check + fwrite on open_memstream. */ +static size_t +fwwrite (const void *ptr, size_t size, size_t nmemb, FILE *arq) +{ + const wchar_t *wcs = (const wchar_t*) (ptr); + for (size_t s = 0; s < size; s++) + { + for (size_t n = 0; n < nmemb; n++) + if (fputwc (wcs[n], arq) == WEOF) + return n; + } + return size * nmemb; +} + +#define CHAR_T wchar_t +#define W(o) L##o +#define OPEN_MEMSTREAM open_wmemstream +#define PRINTF wprintf +#define FWRITE_FUNC fwwrite +#define FPUTC fputwc +#define STRCMP wcscmp + +#include "tst-memstream3.c" diff --git a/libio/tst_getwc.c b/libio/tst_getwc.c index b36b07f6ff..f37c7ae9e3 100644 --- a/libio/tst_getwc.c +++ b/libio/tst_getwc.c @@ -1,5 +1,5 @@ /* Simple test of getwc in the C locale. - Copyright (C) 2000-2016 Free Software Foundation, Inc. + Copyright (C) 2000-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 2000. diff --git a/libio/tst_putwc.c b/libio/tst_putwc.c index d4ac2cf330..18765601ed 100644 --- a/libio/tst_putwc.c +++ b/libio/tst_putwc.c @@ -1,5 +1,5 @@ /* Simple test of putwc in the C locale. - Copyright (C) 2000-2016 Free Software Foundation, Inc. + Copyright (C) 2000-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 2000. diff --git a/libio/vasprintf.c b/libio/vasprintf.c index 7460f1efe1..6c35d2b108 100644 --- a/libio/vasprintf.c +++ b/libio/vasprintf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1995-2016 Free Software Foundation, Inc. +/* Copyright (C) 1995-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -32,16 +32,16 @@ #include "strfile.h" int -_IO_vasprintf (char **result_ptr, const char *format, _IO_va_list args) +_IO_vasprintf (char **result_ptr, const char *format, va_list args) { /* Initial size of the buffer to be used. Will be doubled each time an overflow occurs. */ - const _IO_size_t init_string_size = 100; + const size_t init_string_size = 100; char *string; _IO_strfile sf; int ret; - _IO_size_t needed; - _IO_size_t allocated; + size_t needed; + size_t allocated; /* No need to clear the memory here (unlike for open_memstream) since we know we will never seek on the stream. */ string = (char *) malloc (init_string_size); @@ -54,8 +54,8 @@ _IO_vasprintf (char **result_ptr, const char *format, _IO_va_list args) _IO_JUMPS (&sf._sbf) = &_IO_str_jumps; _IO_str_init_static_internal (&sf, string, init_string_size, string); sf._sbf._f._flags &= ~_IO_USER_BUF; - sf._s._allocate_buffer = (_IO_alloc_type) malloc; - sf._s._free_buffer = (_IO_free_type) free; + sf._s._allocate_buffer_unused = (_IO_alloc_type) malloc; + sf._s._free_buffer_unused = (_IO_free_type) free; ret = _IO_vfprintf (&sf._sbf._f, format, args); if (ret < 0) { diff --git a/libio/vscanf.c b/libio/vscanf.c index b3a0f11832..9c27122c27 100644 --- a/libio/vscanf.c +++ b/libio/vscanf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -30,7 +30,7 @@ #undef vscanf int -_IO_vscanf (const char *format, _IO_va_list args) +_IO_vscanf (const char *format, va_list args) { return _IO_vfscanf (_IO_stdin, format, args, NULL); } diff --git a/libio/vsnprintf.c b/libio/vsnprintf.c index f1063a17be..39b5500528 100644 --- a/libio/vsnprintf.c +++ b/libio/vsnprintf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1994-2016 Free Software Foundation, Inc. +/* Copyright (C) 1994-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -27,10 +27,10 @@ #include "libioP.h" #include "strfile.h" -static int _IO_strn_overflow (_IO_FILE *fp, int c) __THROW; +static int _IO_strn_overflow (FILE *fp, int c) __THROW; static int -_IO_strn_overflow (_IO_FILE *fp, int c) +_IO_strn_overflow (FILE *fp, int c) { /* When we come to here this means the user supplied buffer is filled. But since we must return the number of characters which @@ -64,7 +64,7 @@ _IO_strn_overflow (_IO_FILE *fp, int c) } -const struct _IO_jump_t _IO_strn_jumps attribute_hidden = +const struct _IO_jump_t _IO_strn_jumps libio_vtable attribute_hidden = { JUMP_INIT_DUMMY, JUMP_INIT(finish, _IO_str_finish), @@ -90,8 +90,8 @@ const struct _IO_jump_t _IO_strn_jumps attribute_hidden = int -_IO_vsnprintf (char *string, _IO_size_t maxlen, const char *format, - _IO_va_list args) +_IO_vsnprintf (char *string, size_t maxlen, const char *format, + va_list args) { _IO_strnfile sf; int ret; diff --git a/libio/vswprintf.c b/libio/vswprintf.c index b90441ad77..bcc473d115 100644 --- a/libio/vswprintf.c +++ b/libio/vswprintf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1994-2016 Free Software Foundation, Inc. +/* Copyright (C) 1994-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -28,10 +28,10 @@ #include "strfile.h" -static wint_t _IO_wstrn_overflow (_IO_FILE *fp, wint_t c) __THROW; +static wint_t _IO_wstrn_overflow (FILE *fp, wint_t c) __THROW; static wint_t -_IO_wstrn_overflow (_IO_FILE *fp, wint_t c) +_IO_wstrn_overflow (FILE *fp, wint_t c) { /* When we come to here this means the user supplied buffer is filled. But since we must return the number of characters which @@ -63,7 +63,7 @@ _IO_wstrn_overflow (_IO_FILE *fp, wint_t c) } -const struct _IO_jump_t _IO_wstrn_jumps attribute_hidden = +const struct _IO_jump_t _IO_wstrn_jumps libio_vtable attribute_hidden = { JUMP_INIT_DUMMY, JUMP_INIT(finish, _IO_wstr_finish), @@ -89,8 +89,8 @@ const struct _IO_jump_t _IO_wstrn_jumps attribute_hidden = int -_IO_vswprintf (wchar_t *string, _IO_size_t maxlen, const wchar_t *format, - _IO_va_list args) +_IO_vswprintf (wchar_t *string, size_t maxlen, const wchar_t *format, + va_list args) { _IO_wstrnfile sf; int ret; @@ -108,7 +108,7 @@ _IO_vswprintf (wchar_t *string, _IO_size_t maxlen, const wchar_t *format, _IO_fwide (&sf.f._sbf._f, 1); string[0] = L'\0'; _IO_wstr_init_static (&sf.f._sbf._f, string, maxlen - 1, string); - ret = _IO_vfwprintf ((_IO_FILE *) &sf.f._sbf, format, args); + ret = _IO_vfwprintf ((FILE *) &sf.f._sbf, format, args); if (sf.f._sbf._f._wide_data->_IO_buf_base == sf.overflow_buf) /* ISO C99 requires swprintf/vswprintf to return an error if the diff --git a/libio/vtables.c b/libio/vtables.c new file mode 100644 index 0000000000..9df75668c8 --- /dev/null +++ b/libio/vtables.c @@ -0,0 +1,89 @@ +/* libio vtable validation. + Copyright (C) 2016-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <dlfcn.h> +#include <libioP.h> +#include <stdio.h> +#include <ldsodefs.h> + +#ifdef SHARED + +void (*IO_accept_foreign_vtables) (void) attribute_hidden; + +/* Used to detected multiple libcs. */ +extern struct dl_open_hook *_dl_open_hook; +libc_hidden_proto (_dl_open_hook); + +#else /* !SHARED */ + +/* Used to check whether static dlopen support is needed. */ +# pragma weak __dlopen + +#endif + +void attribute_hidden +_IO_vtable_check (void) +{ +#ifdef SHARED + /* Honor the compatibility flag. */ + void (*flag) (void) = atomic_load_relaxed (&IO_accept_foreign_vtables); +#ifdef PTR_DEMANGLE + PTR_DEMANGLE (flag); +#endif + if (flag == &_IO_vtable_check) + return; + + /* In case this libc copy is in a non-default namespace, we always + need to accept foreign vtables because there is always a + possibility that FILE * objects are passed across the linking + boundary. */ + { + Dl_info di; + struct link_map *l; + if (!rtld_active () + || (_dl_addr (_IO_vtable_check, &di, &l, NULL) != 0 + && l->l_ns != LM_ID_BASE)) + return; + } + +#else /* !SHARED */ + /* We cannot perform vtable validation in the static dlopen case + because FILE * handles might be passed back and forth across the + boundary. Therefore, we disable checking in this case. */ + if (__dlopen != NULL) + return; +#endif + + __libc_fatal ("Fatal error: glibc detected an invalid stdio handle\n"); +} + +/* Some variants of libstdc++ interpose _IO_2_1_stdin_ etc. and + install their own vtables directly, without calling _IO_init or + other functions. Detect this by looking at the vtables values + during startup, and disable vtable validation in this case. */ +#ifdef SHARED +__attribute__ ((constructor)) +static void +check_stdfiles_vtables (void) +{ + if (_IO_2_1_stdin_.vtable != &_IO_file_jumps + || _IO_2_1_stdout_.vtable != &_IO_file_jumps + || _IO_2_1_stderr_.vtable != &_IO_file_jumps) + IO_set_accept_foreign_vtables (&_IO_vtable_check); +} +#endif diff --git a/libio/vwprintf.c b/libio/vwprintf.c index b1794a5d71..72ebfec92d 100644 --- a/libio/vwprintf.c +++ b/libio/vwprintf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-2016 Free Software Foundation, Inc. +/* Copyright (C) 1991-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/libio/vwscanf.c b/libio/vwscanf.c index e951ae7baa..0d5f558758 100644 --- a/libio/vwscanf.c +++ b/libio/vwscanf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -28,7 +28,7 @@ #include <wchar.h> int -__vwscanf (const wchar_t *format, _IO_va_list args) +__vwscanf (const wchar_t *format, va_list args) { return _IO_vfwscanf (_IO_stdin, format, args, NULL); } diff --git a/libio/wfiledoalloc.c b/libio/wfiledoalloc.c index 28c10b6d0d..c3f4ba8cd4 100644 --- a/libio/wfiledoalloc.c +++ b/libio/wfiledoalloc.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -55,32 +55,14 @@ /* Modified for GNU iostream by Per Bothner 1991, 1992. */ -#ifndef _POSIX_SOURCE -# define _POSIX_SOURCE -#endif #include "libioP.h" -#include <sys/types.h> -#include <sys/stat.h> #include <stdlib.h> -#include <unistd.h> - -#ifdef _LIBC -# undef isatty -# define isatty(Fd) __isatty (Fd) -#endif - -/* - * Allocate a file buffer, or switch to unbuffered I/O. - * Per the ANSI C standard, ALL tty devices default to line buffered. - * - * As a side effect, we set __SOPT or __SNPT (en/dis-able fseek - * optimisation) right after the _fstat() that finds the buffer size. - */ +/* Allocate a file buffer, or switch to unbuffered I/O. */ int -_IO_wfile_doallocate (_IO_FILE *fp) +_IO_wfile_doallocate (FILE *fp) { - _IO_size_t size; + size_t size; wchar_t *p; /* Allocate room for the external buffer. */ diff --git a/libio/wfileops.c b/libio/wfileops.c index df1fbdaf8b..63cb687652 100644 --- a/libio/wfileops.c +++ b/libio/wfileops.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Written by Ulrich Drepper <drepper@cygnus.com>. Based on the single byte version by Per Bothner <bothner@cygnus.com>. @@ -33,28 +33,10 @@ #include <stdlib.h> #include <string.h> - -#ifndef _LIBC -# define _IO_new_do_write _IO_do_write -# define _IO_new_file_attach _IO_file_attach -# define _IO_new_file_close_it _IO_file_close_it -# define _IO_new_file_finish _IO_file_finish -# define _IO_new_file_fopen _IO_file_fopen -# define _IO_new_file_init _IO_file_init -# define _IO_new_file_setbuf _IO_file_setbuf -# define _IO_new_file_sync _IO_file_sync -# define _IO_new_file_overflow _IO_file_overflow -# define _IO_new_file_seekoff _IO_file_seekoff -# define _IO_new_file_underflow _IO_file_underflow -# define _IO_new_file_write _IO_file_write -# define _IO_new_file_xsputn _IO_file_xsputn -#endif - - /* Convert TO_DO wide character from DATA to FP. Then mark FP as having empty buffers. */ int -_IO_wdo_write (_IO_FILE *fp, const wchar_t *data, _IO_size_t to_do) +_IO_wdo_write (FILE *fp, const wchar_t *data, size_t to_do) { struct _IO_codecvt *cc = fp->_codecvt; @@ -128,11 +110,15 @@ libc_hidden_def (_IO_wdo_write) wint_t -_IO_wfile_underflow (_IO_FILE *fp) +_IO_wfile_underflow (FILE *fp) { struct _IO_codecvt *cd; enum __codecvt_result status; - _IO_ssize_t count; + ssize_t count; + + /* C99 requires EOF to be "sticky". */ + if (fp->_flags & _IO_EOF_SEEN) + return WEOF; if (__glibc_unlikely (fp->_flags & _IO_NO_READS)) { @@ -214,13 +200,9 @@ _IO_wfile_underflow (_IO_FILE *fp) _IO_wdoallocbuf (fp); } - /* Flush all line buffered files before reading. */ /* FIXME This can/should be moved to genops ?? */ if (fp->_flags & (_IO_LINE_BUF | _IO_UNBUFFERED)) { -#if 0 - _IO_flush_all_linebuffered (); -#else /* We used to flush all line-buffered stream. This really isn't required by any standard. My recollection is that traditional Unix systems did this for stdout. stderr better @@ -233,7 +215,6 @@ _IO_wfile_underflow (_IO_FILE *fp) _IO_OVERFLOW (_IO_stdout, EOF); _IO_release_lock (_IO_stdout); -#endif } _IO_switch_to_get_mode (fp); @@ -350,7 +331,7 @@ libc_hidden_def (_IO_wfile_underflow) static wint_t -_IO_wfile_underflow_mmap (_IO_FILE *fp) +_IO_wfile_underflow_mmap (FILE *fp) { struct _IO_codecvt *cd; const char *read_stop; @@ -411,7 +392,7 @@ _IO_wfile_underflow_mmap (_IO_FILE *fp) } static wint_t -_IO_wfile_underflow_maybe_mmap (_IO_FILE *fp) +_IO_wfile_underflow_maybe_mmap (FILE *fp) { /* This is the first read attempt. Doing the underflow will choose mmap or vanilla operations and then punt to the chosen underflow routine. @@ -424,7 +405,7 @@ _IO_wfile_underflow_maybe_mmap (_IO_FILE *fp) wint_t -_IO_wfile_overflow (_IO_FILE *f, wint_t wch) +_IO_wfile_overflow (FILE *f, wint_t wch) { if (f->_flags & _IO_NO_WRITES) /* SET ERROR */ { @@ -439,6 +420,7 @@ _IO_wfile_overflow (_IO_FILE *f, wint_t wch) if (f->_wide_data->_IO_write_base == 0) { _IO_wdoallocbuf (f); + _IO_free_wbackup_area (f); _IO_wsetg (f, f->_wide_data->_IO_buf_base, f->_wide_data->_IO_buf_base, f->_wide_data->_IO_buf_base); @@ -496,9 +478,9 @@ _IO_wfile_overflow (_IO_FILE *f, wint_t wch) libc_hidden_def (_IO_wfile_overflow) wint_t -_IO_wfile_sync (_IO_FILE *fp) +_IO_wfile_sync (FILE *fp) { - _IO_ssize_t delta; + ssize_t delta; wint_t retval = 0; /* char* ptr = cur_ptr(); */ @@ -511,7 +493,7 @@ _IO_wfile_sync (_IO_FILE *fp) /* We have to find out how many bytes we have to go back in the external buffer. */ struct _IO_codecvt *cv = fp->_codecvt; - _IO_off64_t new_pos; + off64_t new_pos; int clen = (*cv->__codecvt_do_encoding) (cv); @@ -536,15 +518,13 @@ _IO_wfile_sync (_IO_FILE *fp) } new_pos = _IO_SYSSEEK (fp, delta, 1); - if (new_pos != (_IO_off64_t) EOF) + if (new_pos != (off64_t) EOF) { fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_read_ptr; fp->_IO_read_end = fp->_IO_read_ptr; } -#ifdef ESPIPE else if (errno == ESPIPE) ; /* Ignore error from unseekable devices. */ -#endif else retval = WEOF; } @@ -563,7 +543,7 @@ libc_hidden_def (_IO_wfile_sync) Returns 0 on success and -1 on error with the _IO_ERR_SEEN flag set. */ static int -adjust_wide_data (_IO_FILE *fp, bool do_convert) +adjust_wide_data (FILE *fp, bool do_convert) { struct _IO_codecvt *cv = fp->_codecvt; @@ -610,10 +590,10 @@ done: /* ftell{,o} implementation for wide mode. Don't modify any state of the file pointer while we try to get the current state of the stream except in one case, which is when we have unflushed writes in append mode. */ -static _IO_off64_t -do_ftell_wide (_IO_FILE *fp) +static off64_t +do_ftell_wide (FILE *fp) { - _IO_off64_t result, offset = 0; + off64_t result, offset = 0; /* No point looking for offsets in the buffer if it hasn't even been allocated. */ @@ -759,11 +739,11 @@ do_ftell_wide (_IO_FILE *fp) return result; } -_IO_off64_t -_IO_wfile_seekoff (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode) +off64_t +_IO_wfile_seekoff (FILE *fp, off64_t offset, int dir, int mode) { - _IO_off64_t result; - _IO_off64_t delta, new_offset; + off64_t result; + off64_t delta, new_offset; long int count; /* Short-circuit into a separate function. We don't want to mix any @@ -870,14 +850,17 @@ _IO_wfile_seekoff (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode) goto dumb; } } + + _IO_free_wbackup_area (fp); + /* At this point, dir==_IO_seek_set. */ /* If destination is within current buffer, optimize: */ if (fp->_offset != _IO_pos_BAD && fp->_IO_read_base != NULL && !_IO_in_backup (fp)) { - _IO_off64_t start_offset = (fp->_offset - - (fp->_IO_read_end - fp->_IO_buf_base)); + off64_t start_offset = (fp->_offset + - (fp->_IO_read_end - fp->_IO_buf_base)); if (offset >= start_offset && offset < fp->_offset) { _IO_setg (fp, fp->_IO_buf_base, @@ -970,13 +953,13 @@ resync: libc_hidden_def (_IO_wfile_seekoff) -_IO_size_t -_IO_wfile_xsputn (_IO_FILE *f, const void *data, _IO_size_t n) +size_t +_IO_wfile_xsputn (FILE *f, const void *data, size_t n) { const wchar_t *s = (const wchar_t *) data; - _IO_size_t to_do = n; + size_t to_do = n; int must_flush = 0; - _IO_size_t count; + size_t count; if (n <= 0) return 0; @@ -1010,13 +993,8 @@ _IO_wfile_xsputn (_IO_FILE *f, const void *data, _IO_size_t n) count = to_do; if (count > 20) { -#ifdef _LIBC f->_wide_data->_IO_write_ptr = __wmempcpy (f->_wide_data->_IO_write_ptr, s, count); -#else - wmemcpy (f->_wide_data->_IO_write_ptr, s, count); - f->_wide_data->_IO_write_ptr += count; -#endif s += count; } else @@ -1042,7 +1020,7 @@ _IO_wfile_xsputn (_IO_FILE *f, const void *data, _IO_size_t n) libc_hidden_def (_IO_wfile_xsputn) -const struct _IO_jump_t _IO_wfile_jumps = +const struct _IO_jump_t _IO_wfile_jumps libio_vtable = { JUMP_INIT_DUMMY, JUMP_INIT(finish, _IO_new_file_finish), @@ -1068,7 +1046,7 @@ const struct _IO_jump_t _IO_wfile_jumps = libc_hidden_data_def (_IO_wfile_jumps) -const struct _IO_jump_t _IO_wfile_jumps_mmap = +const struct _IO_jump_t _IO_wfile_jumps_mmap libio_vtable = { JUMP_INIT_DUMMY, JUMP_INIT(finish, _IO_new_file_finish), @@ -1092,7 +1070,7 @@ const struct _IO_jump_t _IO_wfile_jumps_mmap = JUMP_INIT(imbue, _IO_default_imbue) }; -const struct _IO_jump_t _IO_wfile_jumps_maybe_mmap = +const struct _IO_jump_t _IO_wfile_jumps_maybe_mmap libio_vtable = { JUMP_INIT_DUMMY, JUMP_INIT(finish, _IO_new_file_finish), diff --git a/libio/wgenops.c b/libio/wgenops.c index 9f524aaf2d..884d72deba 100644 --- a/libio/wgenops.c +++ b/libio/wgenops.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Written by Ulrich Drepper <drepper@cygnus.com>. Based on the single byte version by Per Bothner <bothner@cygnus.com>. @@ -34,23 +34,14 @@ #include <wchar.h> -#ifndef _LIBC -# define __wmemcpy(dst, src, n) wmemcpy (dst, src, n) -#endif - - -static int save_for_wbackup (_IO_FILE *fp, wchar_t *end_p) __THROW -#ifdef _LIBC - internal_function -#endif - ; +static int save_for_wbackup (FILE *fp, wchar_t *end_p) __THROW; /* Return minimum _pos markers Assumes the current get area is the main get area. */ -_IO_ssize_t -_IO_least_wmarker (_IO_FILE *fp, wchar_t *end_p) +ssize_t +_IO_least_wmarker (FILE *fp, wchar_t *end_p) { - _IO_ssize_t least_so_far = end_p - fp->_wide_data->_IO_read_base; + ssize_t least_so_far = end_p - fp->_wide_data->_IO_read_base; struct _IO_marker *mark; for (mark = fp->_markers; mark != NULL; mark = mark->_next) if (mark->_pos < least_so_far) @@ -61,7 +52,7 @@ libc_hidden_def (_IO_least_wmarker) /* Switch current get area from backup buffer to (start of) main get area. */ void -_IO_switch_to_main_wget_area (_IO_FILE *fp) +_IO_switch_to_main_wget_area (FILE *fp) { wchar_t *tmp; fp->_flags &= ~_IO_IN_BACKUP; @@ -81,7 +72,7 @@ libc_hidden_def (_IO_switch_to_main_wget_area) /* Switch current get area from main get area to (end of) backup area. */ void -_IO_switch_to_wbackup_area (_IO_FILE *fp) +_IO_switch_to_wbackup_area (FILE *fp) { wchar_t *tmp; fp->_flags |= _IO_IN_BACKUP; @@ -100,7 +91,7 @@ libc_hidden_def (_IO_switch_to_wbackup_area) void -_IO_wsetb (_IO_FILE *f, wchar_t *b, wchar_t *eb, int a) +_IO_wsetb (FILE *f, wchar_t *b, wchar_t *eb, int a) { if (f->_wide_data->_IO_buf_base && !(f->_flags2 & _IO_FLAGS2_USER_WBUF)) free (f->_wide_data->_IO_buf_base); @@ -115,7 +106,7 @@ libc_hidden_def (_IO_wsetb) wint_t -_IO_wdefault_pbackfail (_IO_FILE *fp, wint_t c) +_IO_wdefault_pbackfail (FILE *fp, wint_t c) { if (fp->_wide_data->_IO_read_ptr > fp->_wide_data->_IO_read_base && !_IO_in_backup (fp) @@ -154,9 +145,9 @@ _IO_wdefault_pbackfail (_IO_FILE *fp, wint_t c) else if (fp->_wide_data->_IO_read_ptr <= fp->_wide_data->_IO_read_base) { /* Increase size of existing backup buffer. */ - _IO_size_t new_size; - _IO_size_t old_size = (fp->_wide_data->_IO_read_end - - fp->_wide_data->_IO_read_base); + size_t new_size; + size_t old_size = (fp->_wide_data->_IO_read_end + - fp->_wide_data->_IO_read_base); wchar_t *new_buf; new_size = 2 * old_size; new_buf = (wchar_t *) malloc (new_size * sizeof (wchar_t)); @@ -178,7 +169,7 @@ libc_hidden_def (_IO_wdefault_pbackfail) void -_IO_wdefault_finish (_IO_FILE *fp, int dummy) +_IO_wdefault_finish (FILE *fp, int dummy) { struct _IO_marker *mark; if (fp->_wide_data->_IO_buf_base && !(fp->_flags2 & _IO_FLAGS2_USER_WBUF)) @@ -207,7 +198,7 @@ libc_hidden_def (_IO_wdefault_finish) wint_t -_IO_wdefault_uflow (_IO_FILE *fp) +_IO_wdefault_uflow (FILE *fp) { wint_t wch; wch = _IO_UNDERFLOW (fp); @@ -219,7 +210,7 @@ libc_hidden_def (_IO_wdefault_uflow) wint_t -__woverflow (_IO_FILE *f, wint_t wch) +__woverflow (FILE *f, wint_t wch) { if (f->_mode == 0) _IO_fwide (f, 1); @@ -229,7 +220,7 @@ libc_hidden_def (__woverflow) wint_t -__wuflow (_IO_FILE *fp) +__wuflow (FILE *fp) { if (fp->_mode < 0 || (fp->_mode == 0 && _IO_fwide (fp, 1) != 1)) return WEOF; @@ -259,7 +250,7 @@ __wuflow (_IO_FILE *fp) libc_hidden_def (__wuflow) wint_t -__wunderflow (_IO_FILE *fp) +__wunderflow (FILE *fp) { if (fp->_mode < 0 || (fp->_mode == 0 && _IO_fwide (fp, 1) != 1)) return WEOF; @@ -289,31 +280,26 @@ __wunderflow (_IO_FILE *fp) libc_hidden_def (__wunderflow) -_IO_size_t -_IO_wdefault_xsputn (_IO_FILE *f, const void *data, _IO_size_t n) +size_t +_IO_wdefault_xsputn (FILE *f, const void *data, size_t n) { const wchar_t *s = (const wchar_t *) data; - _IO_size_t more = n; + size_t more = n; if (more <= 0) return 0; for (;;) { /* Space available. */ - _IO_ssize_t count = (f->_wide_data->_IO_write_end - - f->_wide_data->_IO_write_ptr); + ssize_t count = (f->_wide_data->_IO_write_end + - f->_wide_data->_IO_write_ptr); if (count > 0) { - if ((_IO_size_t) count > more) + if ((size_t) count > more) count = more; if (count > 20) { -#ifdef _LIBC f->_wide_data->_IO_write_ptr = __wmempcpy (f->_wide_data->_IO_write_ptr, s, count); -#else - memcpy (f->_wide_data->_IO_write_ptr, s, count); - f->_wide_data->_IO_write_ptr += count; -#endif s += count; } else if (count <= 0) @@ -321,7 +307,7 @@ _IO_wdefault_xsputn (_IO_FILE *f, const void *data, _IO_size_t n) else { wchar_t *p = f->_wide_data->_IO_write_ptr; - _IO_ssize_t i; + ssize_t i; for (i = count; --i >= 0; ) *p++ = *s++; f->_wide_data->_IO_write_ptr = p; @@ -337,28 +323,23 @@ _IO_wdefault_xsputn (_IO_FILE *f, const void *data, _IO_size_t n) libc_hidden_def (_IO_wdefault_xsputn) -_IO_size_t -_IO_wdefault_xsgetn (_IO_FILE *fp, void *data, _IO_size_t n) +size_t +_IO_wdefault_xsgetn (FILE *fp, void *data, size_t n) { - _IO_size_t more = n; + size_t more = n; wchar_t *s = (wchar_t*) data; for (;;) { /* Data available. */ - _IO_ssize_t count = (fp->_wide_data->_IO_read_end - - fp->_wide_data->_IO_read_ptr); + ssize_t count = (fp->_wide_data->_IO_read_end + - fp->_wide_data->_IO_read_ptr); if (count > 0) { - if ((_IO_size_t) count > more) + if ((size_t) count > more) count = more; if (count > 20) { -#ifdef _LIBC s = __wmempcpy (s, fp->_wide_data->_IO_read_ptr, count); -#else - memcpy (s, fp->_wide_data->_IO_read_ptr, count); - s += count; -#endif fp->_wide_data->_IO_read_ptr += count; } else if (count <= 0) @@ -382,7 +363,7 @@ libc_hidden_def (_IO_wdefault_xsgetn) void -_IO_wdoallocbuf (_IO_FILE *fp) +_IO_wdoallocbuf (FILE *fp) { if (fp->_wide_data->_IO_buf_base) return; @@ -396,21 +377,21 @@ libc_hidden_def (_IO_wdoallocbuf) int -_IO_wdefault_doallocate (_IO_FILE *fp) +_IO_wdefault_doallocate (FILE *fp) { wchar_t *buf; - buf = malloc (_IO_BUFSIZ); + buf = malloc (BUFSIZ); if (__glibc_unlikely (buf == NULL)) return EOF; - _IO_wsetb (fp, buf, buf + _IO_BUFSIZ, 1); + _IO_wsetb (fp, buf, buf + BUFSIZ, 1); return 1; } libc_hidden_def (_IO_wdefault_doallocate) int -_IO_switch_to_wget_mode (_IO_FILE *fp) +_IO_switch_to_wget_mode (FILE *fp) { if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_write_base) if ((wint_t)_IO_WOVERFLOW (fp, WEOF) == WEOF) @@ -434,7 +415,7 @@ _IO_switch_to_wget_mode (_IO_FILE *fp) libc_hidden_def (_IO_switch_to_wget_mode) void -_IO_free_wbackup_area (_IO_FILE *fp) +_IO_free_wbackup_area (FILE *fp) { if (_IO_in_backup (fp)) _IO_switch_to_main_wget_area (fp); /* Just in case. */ @@ -445,42 +426,19 @@ _IO_free_wbackup_area (_IO_FILE *fp) } libc_hidden_def (_IO_free_wbackup_area) -#if 0 -int -_IO_switch_to_wput_mode (_IO_FILE *fp) -{ - fp->_wide_data->_IO_write_base = fp->_wide_data->_IO_read_ptr; - fp->_wide_data->_IO_write_ptr = fp->_wide_data->_IO_read_ptr; - /* Following is wrong if line- or un-buffered? */ - fp->_wide_data->_IO_write_end = (fp->_flags & _IO_IN_BACKUP - ? fp->_wide_data->_IO_read_end - : fp->_wide_data->_IO_buf_end); - - fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end; - fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_end; - - fp->_flags |= _IO_CURRENTLY_PUTTING; - return 0; -} -#endif - - static int -#ifdef _LIBC -internal_function -#endif -save_for_wbackup (_IO_FILE *fp, wchar_t *end_p) +save_for_wbackup (FILE *fp, wchar_t *end_p) { /* Append [_IO_read_base..end_p] to backup area. */ - _IO_ssize_t least_mark = _IO_least_wmarker (fp, end_p); + ssize_t least_mark = _IO_least_wmarker (fp, end_p); /* needed_size is how much space we need in the backup area. */ - _IO_size_t needed_size = ((end_p - fp->_wide_data->_IO_read_base) - - least_mark); + size_t needed_size = ((end_p - fp->_wide_data->_IO_read_base) + - least_mark); /* FIXME: Dubious arithmetic if pointers are NULL */ - _IO_size_t current_Bsize = (fp->_wide_data->_IO_save_end - - fp->_wide_data->_IO_save_base); - _IO_size_t avail; /* Extra space available for future expansion. */ - _IO_ssize_t delta; + size_t current_Bsize = (fp->_wide_data->_IO_save_end + - fp->_wide_data->_IO_save_base); + size_t avail; /* Extra space available for future expansion. */ + ssize_t delta; struct _IO_marker *mark; if (needed_size > current_Bsize) { @@ -492,32 +450,17 @@ save_for_wbackup (_IO_FILE *fp, wchar_t *end_p) return EOF; /* FIXME */ if (least_mark < 0) { -#ifdef _LIBC __wmempcpy (__wmempcpy (new_buffer + avail, fp->_wide_data->_IO_save_end + least_mark, -least_mark), fp->_wide_data->_IO_read_base, end_p - fp->_wide_data->_IO_read_base); -#else - memcpy (new_buffer + avail, - fp->_wide_data->_IO_save_end + least_mark, - -least_mark * sizeof (wchar_t)); - memcpy (new_buffer + avail - least_mark, - fp->_wide_data->_IO_read_base, - (end_p - fp->_wide_data->_IO_read_base) * sizeof (wchar_t)); -#endif } else { -#ifdef _LIBC __wmemcpy (new_buffer + avail, fp->_wide_data->_IO_read_base + least_mark, needed_size); -#else - memcpy (new_buffer + avail, - fp->_wide_data->_IO_read_base + least_mark, - needed_size * sizeof (wchar_t)); -#endif } free (fp->_wide_data->_IO_save_base); fp->_wide_data->_IO_save_base = new_buffer; @@ -528,32 +471,17 @@ save_for_wbackup (_IO_FILE *fp, wchar_t *end_p) avail = current_Bsize - needed_size; if (least_mark < 0) { -#ifdef _LIBC __wmemmove (fp->_wide_data->_IO_save_base + avail, fp->_wide_data->_IO_save_end + least_mark, -least_mark); __wmemcpy (fp->_wide_data->_IO_save_base + avail - least_mark, fp->_wide_data->_IO_read_base, end_p - fp->_wide_data->_IO_read_base); -#else - memmove (fp->_wide_data->_IO_save_base + avail, - fp->_wide_data->_IO_save_end + least_mark, - -least_mark * sizeof (wchar_t)); - memcpy (fp->_wide_data->_IO_save_base + avail - least_mark, - fp->_wide_data->_IO_read_base, - (end_p - fp->_wide_data->_IO_read_base) * sizeof (wchar_t)); -#endif } else if (needed_size > 0) -#ifdef _LIBC __wmemcpy (fp->_wide_data->_IO_save_base + avail, fp->_wide_data->_IO_read_base + least_mark, needed_size); -#else - memcpy (fp->_wide_data->_IO_save_base + avail, - fp->_wide_data->_IO_read_base + least_mark, - needed_size * sizeof (wchar_t)); -#endif } fp->_wide_data->_IO_backup_base = fp->_wide_data->_IO_save_base + avail; /* Adjust all the streammarkers. */ @@ -564,7 +492,7 @@ save_for_wbackup (_IO_FILE *fp, wchar_t *end_p) } wint_t -_IO_sputbackwc (_IO_FILE *fp, wint_t c) +_IO_sputbackwc (FILE *fp, wint_t c) { wint_t result; @@ -585,7 +513,7 @@ _IO_sputbackwc (_IO_FILE *fp, wint_t c) libc_hidden_def (_IO_sputbackwc) wint_t -_IO_sungetwc (_IO_FILE *fp) +_IO_sungetwc (FILE *fp) { wint_t result; @@ -615,7 +543,7 @@ _IO_adjust_wcolumn (unsigned start, const wchar_t *line, int count) } void -_IO_init_wmarker (struct _IO_marker *marker, _IO_FILE *fp) +_IO_init_wmarker (struct _IO_marker *marker, FILE *fp) { marker->_sbuf = fp; if (_IO_in_put_mode (fp)) @@ -650,7 +578,7 @@ _IO_wmarker_delta (struct _IO_marker *mark) } int -_IO_seekwmark (_IO_FILE *fp, struct _IO_marker *mark, int delta) +_IO_seekwmark (FILE *fp, struct _IO_marker *mark, int delta) { if (mark->_sbuf != fp) return EOF; @@ -671,25 +599,11 @@ _IO_seekwmark (_IO_FILE *fp, struct _IO_marker *mark, int delta) } void -_IO_unsave_wmarkers (_IO_FILE *fp) +_IO_unsave_wmarkers (FILE *fp) { struct _IO_marker *mark = fp->_markers; if (mark) { -#ifdef TODO - streampos offset = seekoff (0, ios::cur, ios::in); - if (offset != EOF) - { - offset += eGptr () - Gbase (); - for ( ; mark != NULL; mark = mark->_next) - mark->set_streampos (mark->_pos + offset); - } - else - { - for ( ; mark != NULL; mark = mark->_next) - mark->set_streampos (EOF); - } -#endif fp->_markers = 0; } diff --git a/libio/wmemstream.c b/libio/wmemstream.c index 1bdbae9fe8..c92d2da4b2 100644 --- a/libio/wmemstream.c +++ b/libio/wmemstream.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1995-2016 Free Software Foundation, Inc. +/* Copyright (C) 1995-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -26,15 +26,15 @@ struct _IO_FILE_wmemstream { _IO_strfile _sf; wchar_t **bufloc; - _IO_size_t *sizeloc; + size_t *sizeloc; }; -static int _IO_wmem_sync (_IO_FILE* fp) __THROW; -static void _IO_wmem_finish (_IO_FILE* fp, int) __THROW; +static int _IO_wmem_sync (FILE* fp) __THROW; +static void _IO_wmem_finish (FILE* fp, int) __THROW; -static const struct _IO_jump_t _IO_wmem_jumps = +static const struct _IO_jump_t _IO_wmem_jumps libio_vtable = { JUMP_INIT_DUMMY, JUMP_INIT (finish, _IO_wmem_finish), @@ -61,8 +61,8 @@ static const struct _IO_jump_t _IO_wmem_jumps = /* Open a stream that writes into a malloc'd buffer that is expanded as necessary. *BUFLOC and *SIZELOC are updated with the buffer's location and the number of characters written on fflush or fclose. */ -_IO_FILE * -open_wmemstream (wchar_t **bufloc, _IO_size_t *sizeloc) +FILE * +open_wmemstream (wchar_t **bufloc, size_t *sizeloc) { struct locked_FILE { @@ -81,7 +81,7 @@ open_wmemstream (wchar_t **bufloc, _IO_size_t *sizeloc) new_f->fp._sf._sbf._f._lock = &new_f->lock; #endif - buf = calloc (1, _IO_BUFSIZ); + buf = calloc (1, BUFSIZ); if (buf == NULL) { free (new_f); @@ -90,20 +90,23 @@ open_wmemstream (wchar_t **bufloc, _IO_size_t *sizeloc) _IO_no_init (&new_f->fp._sf._sbf._f, 0, 0, &new_f->wd, &_IO_wmem_jumps); _IO_fwide (&new_f->fp._sf._sbf._f, 1); _IO_wstr_init_static (&new_f->fp._sf._sbf._f, buf, - _IO_BUFSIZ / sizeof (wchar_t), buf); + BUFSIZ / sizeof (wchar_t), buf); new_f->fp._sf._sbf._f._flags2 &= ~_IO_FLAGS2_USER_WBUF; - new_f->fp._sf._s._allocate_buffer = (_IO_alloc_type) malloc; - new_f->fp._sf._s._free_buffer = (_IO_free_type) free; + new_f->fp._sf._s._allocate_buffer_unused = (_IO_alloc_type) malloc; + new_f->fp._sf._s._free_buffer_unused = (_IO_free_type) free; new_f->fp.bufloc = bufloc; new_f->fp.sizeloc = sizeloc; - return (_IO_FILE *) &new_f->fp._sf._sbf; + /* Disable single thread optimization. BZ 21735. */ + new_f->fp._sf._sbf._f._flags2 |= _IO_FLAGS2_NEED_LOCK; + + return (FILE *) &new_f->fp._sf._sbf; } static int -_IO_wmem_sync (_IO_FILE *fp) +_IO_wmem_sync (FILE *fp) { struct _IO_FILE_wmemstream *mp = (struct _IO_FILE_wmemstream *) fp; @@ -112,8 +115,6 @@ _IO_wmem_sync (_IO_FILE *fp) _IO_wstr_overflow (fp, '\0'); --fp->_wide_data->_IO_write_ptr; } - else - *fp->_wide_data->_IO_write_ptr = '\0'; *mp->bufloc = fp->_wide_data->_IO_write_base; *mp->sizeloc = (fp->_wide_data->_IO_write_ptr @@ -124,7 +125,7 @@ _IO_wmem_sync (_IO_FILE *fp) static void -_IO_wmem_finish (_IO_FILE *fp, int dummy) +_IO_wmem_finish (FILE *fp, int dummy) { struct _IO_FILE_wmemstream *mp = (struct _IO_FILE_wmemstream *) fp; diff --git a/libio/wprintf.c b/libio/wprintf.c index 8b0e843a1a..5945f651fc 100644 --- a/libio/wprintf.c +++ b/libio/wprintf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-2016 Free Software Foundation, Inc. +/* Copyright (C) 1991-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/libio/wscanf.c b/libio/wscanf.c index 739399bf8a..c8cdad0acd 100644 --- a/libio/wscanf.c +++ b/libio/wscanf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-2016 Free Software Foundation, Inc. +/* Copyright (C) 1991-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or diff --git a/libio/wstrops.c b/libio/wstrops.c index 2b9d0368f3..6626f2f711 100644 --- a/libio/wstrops.c +++ b/libio/wstrops.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -32,19 +32,19 @@ #include <stdio_ext.h> void -_IO_wstr_init_static (_IO_FILE *fp, wchar_t *ptr, _IO_size_t size, +_IO_wstr_init_static (FILE *fp, wchar_t *ptr, size_t size, wchar_t *pstart) { wchar_t *end; if (size == 0) end = ptr + __wcslen (ptr); - else if ((_IO_size_t) ptr + size * sizeof (wchar_t) > (_IO_size_t) ptr) + else if ((size_t) ptr + size * sizeof (wchar_t) > (size_t) ptr) end = ptr + size; else /* Even for misaligned ptr make sure there is integral number of wide characters. */ - end = ptr + (-1 - (_IO_size_t) ptr) / sizeof (wchar_t); + end = ptr + (-1 - (size_t) ptr) / sizeof (wchar_t); _IO_wsetb (fp, ptr, end, 0); fp->_wide_data->_IO_write_base = ptr; @@ -63,14 +63,14 @@ _IO_wstr_init_static (_IO_FILE *fp, wchar_t *ptr, _IO_size_t size, fp->_wide_data->_IO_read_end = end; } /* A null _allocate_buffer function flags the strfile as being static. */ - (((_IO_strfile *) fp)->_s._allocate_buffer) = (_IO_alloc_type)0; + (((_IO_strfile *) fp)->_s._allocate_buffer_unused) = (_IO_alloc_type)0; } -_IO_wint_t -_IO_wstr_overflow (_IO_FILE *fp, _IO_wint_t c) +wint_t +_IO_wstr_overflow (FILE *fp, wint_t c) { int flush_only = c == WEOF; - _IO_size_t pos; + size_t pos; if (fp->_flags & _IO_NO_WRITES) return flush_only ? 0 : WEOF; if ((fp->_flags & _IO_TIED_PUT_GET) && !(fp->_flags & _IO_CURRENTLY_PUTTING)) @@ -80,7 +80,7 @@ _IO_wstr_overflow (_IO_FILE *fp, _IO_wint_t c) fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end; } pos = fp->_wide_data->_IO_write_ptr - fp->_wide_data->_IO_write_base; - if (pos >= (_IO_size_t) (_IO_wblen (fp) + flush_only)) + if (pos >= (size_t) (_IO_wblen (fp) + flush_only)) { if (fp->_flags2 & _IO_FLAGS2_USER_WBUF) /* not allowed to enlarge */ return WEOF; @@ -89,15 +89,13 @@ _IO_wstr_overflow (_IO_FILE *fp, _IO_wint_t c) wchar_t *new_buf; wchar_t *old_buf = fp->_wide_data->_IO_buf_base; size_t old_wblen = _IO_wblen (fp); - _IO_size_t new_size = 2 * old_wblen + 100; + size_t new_size = 2 * old_wblen + 100; if (__glibc_unlikely (new_size < old_wblen) || __glibc_unlikely (new_size > SIZE_MAX / sizeof (wchar_t))) return EOF; - new_buf - = (wchar_t *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (new_size - * sizeof (wchar_t)); + new_buf = malloc (new_size * sizeof (wchar_t)); if (new_buf == NULL) { /* __ferror(fp) = 1; */ @@ -106,12 +104,12 @@ _IO_wstr_overflow (_IO_FILE *fp, _IO_wint_t c) if (old_buf) { __wmemcpy (new_buf, old_buf, old_wblen); - (*((_IO_strfile *) fp)->_s._free_buffer) (old_buf); + free (old_buf); /* Make sure _IO_setb won't try to delete _IO_buf_base. */ fp->_wide_data->_IO_buf_base = NULL; } - wmemset (new_buf + old_wblen, L'\0', new_size - old_wblen); + __wmemset (new_buf + old_wblen, L'\0', new_size - old_wblen); _IO_wsetb (fp, new_buf, new_buf + new_size, 1); fp->_wide_data->_IO_read_base = @@ -136,8 +134,8 @@ _IO_wstr_overflow (_IO_FILE *fp, _IO_wint_t c) } -_IO_wint_t -_IO_wstr_underflow (_IO_FILE *fp) +wint_t +_IO_wstr_underflow (FILE *fp) { if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_read_end) fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_write_ptr; @@ -155,8 +153,8 @@ _IO_wstr_underflow (_IO_FILE *fp) /* The size of the valid part of the buffer. */ -_IO_ssize_t -_IO_wstr_count (_IO_FILE *fp) +ssize_t +_IO_wstr_count (FILE *fp) { struct _IO_wide_data *wd = fp->_wide_data; @@ -167,35 +165,33 @@ _IO_wstr_count (_IO_FILE *fp) static int -enlarge_userbuf (_IO_FILE *fp, _IO_off64_t offset, int reading) +enlarge_userbuf (FILE *fp, off64_t offset, int reading) { - if ((_IO_ssize_t) offset <= _IO_blen (fp)) + if ((ssize_t) offset <= _IO_wblen (fp)) return 0; struct _IO_wide_data *wd = fp->_wide_data; - _IO_ssize_t oldend = wd->_IO_write_end - wd->_IO_write_base; + ssize_t oldend = wd->_IO_write_end - wd->_IO_write_base; /* Try to enlarge the buffer. */ if (fp->_flags2 & _IO_FLAGS2_USER_WBUF) /* User-provided buffer. */ return 1; - _IO_size_t newsize = offset + 100; + size_t newsize = offset + 100; if (__glibc_unlikely (newsize > SIZE_MAX / sizeof (wchar_t))) return 1; wchar_t *oldbuf = wd->_IO_buf_base; - wchar_t *newbuf - = (wchar_t *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (newsize - * sizeof (wchar_t)); + wchar_t *newbuf = malloc (newsize * sizeof (wchar_t)); if (newbuf == NULL) return 1; if (oldbuf != NULL) { __wmemcpy (newbuf, oldbuf, _IO_wblen (fp)); - (*((_IO_strfile *) fp)->_s._free_buffer) (oldbuf); + free (oldbuf); /* Make sure _IO_setb won't try to delete _IO_buf_base. */ wd->_IO_buf_base = NULL; @@ -228,59 +224,83 @@ enlarge_userbuf (_IO_FILE *fp, _IO_off64_t offset, int reading) new position. */ assert (offset >= oldend); if (reading) - wmemset (wd->_IO_read_base + oldend, L'\0', offset - oldend); + __wmemset (wd->_IO_read_base + oldend, L'\0', offset - oldend); else - wmemset (wd->_IO_write_base + oldend, L'\0', offset - oldend); + __wmemset (wd->_IO_write_base + oldend, L'\0', offset - oldend); return 0; } +static void +_IO_wstr_switch_to_get_mode (FILE *fp) +{ + if (_IO_in_backup (fp)) + fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_backup_base; + else + { + fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_buf_base; + if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_read_end) + fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_write_ptr; + } + fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_write_ptr; + fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_write_ptr; -_IO_off64_t -_IO_wstr_seekoff (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode) + fp->_flags &= ~_IO_CURRENTLY_PUTTING; +} + +off64_t +_IO_wstr_seekoff (FILE *fp, off64_t offset, int dir, int mode) { - _IO_off64_t new_pos; + off64_t new_pos; if (mode == 0 && (fp->_flags & _IO_TIED_PUT_GET)) mode = (fp->_flags & _IO_CURRENTLY_PUTTING ? _IOS_OUTPUT : _IOS_INPUT); + bool was_writing = (fp->_wide_data->_IO_write_ptr > + fp->_wide_data->_IO_write_base + || _IO_in_put_mode (fp)); + if (was_writing) + _IO_wstr_switch_to_get_mode (fp); + if (mode == 0) { - /* Don't move any pointers. But there is no clear indication what - mode FP is in. Let's guess. */ - if (fp->_IO_file_flags & _IO_NO_WRITES) - new_pos = fp->_wide_data->_IO_read_ptr - fp->_wide_data->_IO_read_base; - else - new_pos = (fp->_wide_data->_IO_write_ptr - - fp->_wide_data->_IO_write_base); + new_pos = (fp->_wide_data->_IO_write_ptr + - fp->_wide_data->_IO_write_base); } else { - _IO_ssize_t cur_size = _IO_wstr_count (fp); + ssize_t cur_size = _IO_wstr_count (fp); new_pos = EOF; /* Move the get pointer, if requested. */ if (mode & _IOS_INPUT) { + ssize_t base; switch (dir) { - case _IO_seek_end: - offset += cur_size; + case _IO_seek_set: + base = 0; break; case _IO_seek_cur: - offset += (fp->_wide_data->_IO_read_ptr - - fp->_wide_data->_IO_read_base); + base = (fp->_wide_data->_IO_read_ptr + - fp->_wide_data->_IO_read_base); break; - default: /* case _IO_seek_set: */ + default: /* case _IO_seek_end: */ + base = cur_size; break; } - if (offset < 0) - return EOF; - if ((_IO_ssize_t) offset > cur_size - && enlarge_userbuf (fp, offset, 1) != 0) + ssize_t maxval = SSIZE_MAX/sizeof (wchar_t) - base; + if (offset < -base || offset > maxval) + { + __set_errno (EINVAL); + return EOF; + } + base += offset; + if (base > cur_size + && enlarge_userbuf (fp, base, 1) != 0) return EOF; fp->_wide_data->_IO_read_ptr = (fp->_wide_data->_IO_read_base - + offset); + + base); fp->_wide_data->_IO_read_end = (fp->_wide_data->_IO_read_base + cur_size); new_pos = offset; @@ -289,33 +309,40 @@ _IO_wstr_seekoff (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode) /* Move the put pointer, if requested. */ if (mode & _IOS_OUTPUT) { + ssize_t base; switch (dir) { - case _IO_seek_end: - offset += cur_size; + case _IO_seek_set: + base = 0; break; case _IO_seek_cur: - offset += (fp->_wide_data->_IO_write_ptr - - fp->_wide_data->_IO_write_base); + base = (fp->_wide_data->_IO_write_ptr + - fp->_wide_data->_IO_write_base); break; - default: /* case _IO_seek_set: */ + default: /* case _IO_seek_end: */ + base = cur_size; break; } - if (offset < 0) - return EOF; - if ((_IO_ssize_t) offset > cur_size - && enlarge_userbuf (fp, offset, 0) != 0) + ssize_t maxval = SSIZE_MAX/sizeof (wchar_t) - base; + if (offset < -base || offset > maxval) + { + __set_errno (EINVAL); + return EOF; + } + base += offset; + if (base > cur_size + && enlarge_userbuf (fp, base, 0) != 0) return EOF; fp->_wide_data->_IO_write_ptr = (fp->_wide_data->_IO_write_base - + offset); - new_pos = offset; + + base); + new_pos = base; } } return new_pos; } -_IO_wint_t -_IO_wstr_pbackfail (_IO_FILE *fp, _IO_wint_t c) +wint_t +_IO_wstr_pbackfail (FILE *fp, wint_t c) { if ((fp->_flags & _IO_NO_WRITES) && c != WEOF) return WEOF; @@ -323,16 +350,16 @@ _IO_wstr_pbackfail (_IO_FILE *fp, _IO_wint_t c) } void -_IO_wstr_finish (_IO_FILE *fp, int dummy) +_IO_wstr_finish (FILE *fp, int dummy) { if (fp->_wide_data->_IO_buf_base && !(fp->_flags2 & _IO_FLAGS2_USER_WBUF)) - (((_IO_strfile *) fp)->_s._free_buffer) (fp->_wide_data->_IO_buf_base); + free (fp->_wide_data->_IO_buf_base); fp->_wide_data->_IO_buf_base = NULL; _IO_wdefault_finish (fp, 0); } -const struct _IO_jump_t _IO_wstr_jumps = +const struct _IO_jump_t _IO_wstr_jumps libio_vtable = { JUMP_INIT_DUMMY, JUMP_INIT(finish, _IO_wstr_finish), |