Commit Graph

88 Commits

Author SHA1 Message Date
Florian Weimer
ecc7c3deb9 libio: Check remaining buffer size in _IO_wdo_write (bug 31183)
The multibyte character needs to fit into the remaining buffer space,
not the already-written buffer space.  Without the fix, we were never
moving the write pointer from the start of the buffer, always using
the single-character fallback buffer.

Fixes commit 04b76b5aa8 ("Don't error out writing
a multibyte character to an unbuffered stream (bug 17522)").
2024-01-02 14:36:17 +01:00
Paul Eggert
dff8da6b3e Update copyright dates with scripts/update-copyrights 2024-01-01 10:53:40 -08:00
Adhemerval Zanella Netto
3020f72618 libio: Remove the usage of __libc_IO_vtables
Instead of using a special ELF section along with a linker script
directive to put the IO vtables within the RELRO section, the libio
vtables are all moved to an array marked as data.relro (so linker
will place in the RELRO segment without the need of extra directives).

To avoid static linking namespace issues and including all vtable
referenced objects, all required function pointers are set to weak alias.

Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
2023-03-27 13:57:55 -03:00
Joseph Myers
6d7e8eda9b Update copyright dates with scripts/update-copyrights 2023-01-06 21:14:39 +00:00
José Bollo
edc696a73a libio: Ensure output buffer for wchars (bug #28828)
The _IO_wfile_overflow does not check if the write pointer for wide
data is valid before access, different than _IO_file_overflow.  This
leads to crash on some cases, as described by bug 28828.

The minimal sequence to produce the crash was:

  #include <stdio.h>
  #include <wchar.h>
  int main (int ac, char **av)
  {
    setvbuf (stdout, NULL, _IOLBF, 0);
    fgetwc (stdin);
    fputwc (10, stdout); /*CRASH HERE!*/
    return 0;
  }

The "fgetwc(stdin);" is necessary since it triggers the bug by setting
the flag _IO_CURRENTLY_PUTTING on stdout indirectly (file wfileops.c,
function _IO_wfile_underflow, line 213).

Signed-off-by: Jose Bollo <jobol@nonadev.net>
2022-03-08 14:25:32 -03:00
Paul Eggert
581c785bf3 Update copyright dates with scripts/update-copyrights
I used these shell commands:

../glibc/scripts/update-copyrights $PWD/../gnulib/build-aux/update-copyright
(cd ../glibc && git commit -am"[this commit message]")

and then ignored the output, which consisted lines saying "FOO: warning:
copyright statement not found" for each of 7061 files FOO.

I then removed trailing white space from math/tgmath.h,
support/tst-support-open-dev-null-range.c, and
sysdeps/x86_64/multiarch/strlen-vec.S, to work around the following
obscure pre-commit check failure diagnostics from Savannah.  I don't
know why I run into these diagnostics whereas others evidently do not.

remote: *** 912-#endif
remote: *** 913:
remote: *** 914-
remote: *** error: lines with trailing whitespace found
...
remote: *** error: sysdeps/unix/sysv/linux/statx_cp.c: trailing lines
2022-01-01 11:40:24 -08:00
Siddhesh Poyarekar
30891f35fa Remove "Contributed by" lines
We stopped adding "Contributed by" or similar lines in sources in 2012
in favour of git logs and keeping the Contributors section of the
glibc manual up to date.  Removing these lines makes the license
header a bit more consistent across files and also removes the
possibility of error in attribution when license blocks or files are
copied across since the contributed-by lines don't actually reflect
reality in those cases.

Move all "Contributed by" and similar lines (Written by, Test by,
etc.) into a new file CONTRIBUTED-BY to retain record of these
contributions.  These contributors are also mentioned in
manual/contrib.texi, so we just maintain this additional record as a
courtesy to the earlier developers.

The following scripts were used to filter a list of files to edit in
place and to clean up the CONTRIBUTED-BY file respectively.  These
were not added to the glibc sources because they're not expected to be
of any use in future given that this is a one time task:

https://gist.github.com/siddhesh/b5ecac94eabfd72ed2916d6d8157e7dc
https://gist.github.com/siddhesh/15ea1f5e435ace9774f485030695ee02

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
2021-09-03 22:06:44 +05:30
Adhemerval Zanella
52a5fe70a2 Use 64 bit time_t stat internally
For the legacy ABI with supports 32-bit time_t it calls the 64-bit
time directly, since the LFS symbols calls the 64-bit time_t ones
internally.

Checked on i686-linux-gnu and x86_64-linux-gnu.

Reviewed-by: Lukasz Majewski <lukma@denx.de>
2021-06-22 12:09:52 -03:00
Paul Eggert
2b778ceb40 Update copyright dates with scripts/update-copyrights
I used these shell commands:

../glibc/scripts/update-copyrights $PWD/../gnulib/build-aux/update-copyright
(cd ../glibc && git commit -am"[this commit message]")

and then ignored the output, which consisted lines saying "FOO: warning:
copyright statement not found" for each of 6694 files FOO.
I then removed trailing white space from benchtests/bench-pthread-locks.c
and iconvdata/tst-iconv-big5-hkscs-to-2ucs4.c, to work around this
diagnostic from Savannah:
remote: *** pre-commit check failed ...
remote: *** error: lines with trailing whitespace found
remote: error: hook declined to update refs/heads/master
2021-01-02 12:17:34 -08:00
Joseph Myers
d614a75396 Update copyright dates with scripts/update-copyrights. 2020-01-01 00:14:33 +00:00
Paul Eggert
5a82c74822 Prefer https to http for gnu.org and fsf.org URLs
Also, change sources.redhat.com to sourceware.org.
This patch was automatically generated by running the following shell
script, which uses GNU sed, and which avoids modifying files imported
from upstream:

sed -ri '
  s,(http|ftp)(://(.*\.)?(gnu|fsf|sourceware)\.org($|[^.]|\.[^a-z])),https\2,g
  s,(http|ftp)(://(.*\.)?)sources\.redhat\.com($|[^.]|\.[^a-z]),https\2sourceware.org\4,g
' \
  $(find $(git ls-files) -prune -type f \
      ! -name '*.po' \
      ! -name 'ChangeLog*' \
      ! -path COPYING ! -path COPYING.LIB \
      ! -path manual/fdl-1.3.texi ! -path manual/lgpl-2.1.texi \
      ! -path manual/texinfo.tex ! -path scripts/config.guess \
      ! -path scripts/config.sub ! -path scripts/install-sh \
      ! -path scripts/mkinstalldirs ! -path scripts/move-if-change \
      ! -path INSTALL ! -path  locale/programs/charmap-kw.h \
      ! -path po/libc.pot ! -path sysdeps/gnu/errlist.c \
      ! '(' -name configure \
            -execdir test -f configure.ac -o -f configure.in ';' ')' \
      ! '(' -name preconfigure \
            -execdir test -f preconfigure.ac ';' ')' \
      -print)

and then by running 'make dist-prepare' to regenerate files built
from the altered files, and then executing the following to cleanup:

  chmod a+x sysdeps/unix/sysv/linux/riscv/configure
  # Omit irrelevant whitespace and comment-only changes,
  # perhaps from a slightly-different Autoconf version.
  git checkout -f \
    sysdeps/csky/configure \
    sysdeps/hppa/configure \
    sysdeps/riscv/configure \
    sysdeps/unix/sysv/linux/csky/configure
  # Omit changes that caused a pre-commit check to fail like this:
  # remote: *** error: sysdeps/powerpc/powerpc64/ppc-mcount.S: trailing lines
  git checkout -f \
    sysdeps/powerpc/powerpc64/ppc-mcount.S \
    sysdeps/unix/sysv/linux/s390/s390-64/syscall.S
  # Omit change that caused a pre-commit check to fail like this:
  # remote: *** error: sysdeps/sparc/sparc64/multiarch/memcpy-ultra3.S: last line does not end in newline
  git checkout -f sysdeps/sparc/sparc64/multiarch/memcpy-ultra3.S
2019-09-07 02:43:31 -07:00
Florian Weimer
09e1b0e3f6 libio: Remove codecvt vtable [BZ #24588]
The codecvt vtable is not a real vtable because it also contains the
conversion state data.  Furthermore, wide stream support was added to
GCC 3.0, after a C++ ABI bump, so there is no compatibility
requirement with libstdc++.

This change removes several unmangled function pointers which could
be used with a corrupted FILE object to redirect execution.  (libio
vtable verification did not cover the codecvt vtable.)

Reviewed-by: Yann Droneaud <ydroneaud@opteya.com>
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
2019-05-20 21:54:57 +02:00
Andreas Schwab
32ff397533 Fix crash in _IO_wfile_sync (bug 20568)
When computing the length of the converted part of the stdio buffer, use
the number of consumed wide characters, not the (negative) distance to the
end of the wide buffer.
2019-05-15 16:47:09 +02:00
Paul Pluzhnikov
5f10701fdc libio: use stdout in puts and putchar, etc [BZ #24051].
GLIBC explicitly allows one to assign a new FILE pointer to stdout and
other standard streams.  printf and wprintf were honouring assignment to
stdout and using the new value, but puts, putchar, and wide char variants
did not.

The stdout part is fixed here.  The stdin part will be fixed in a followup.
2019-01-31 14:07:45 -08:00
Joseph Myers
04277e02d7 Update copyright dates with scripts/update-copyrights.
* All files with FSF copyright notices: Update copyright dates
	using scripts/update-copyrights.
	* locale/programs/charmap-kw.h: Regenerated.
	* locale/programs/locfile-kw.h: Likewise.
2019-01-01 00:11:28 +00:00
Zack Weinberg
2cc7bad0ae [BZ 1190] Make EOF sticky in stdio.
C99 specifies that the EOF condition on a file is "sticky": once EOF
has been encountered, all subsequent reads should continue to return
EOF until the file is closed or something clears the "end-of-file
indicator" (e.g. fseek, clearerr).  This is arguably a change from
C89, where the wording was ambiguous; the BSDs always had sticky EOF,
but the System V lineage would attempt to read from the underlying fd
again.  GNU libc has followed System V for as long as we've been
using libio, but nowadays C99 conformance and BSD compatibility are
more important than System V compatibility.

You might wonder if changing the _underflow impls is sufficient to
apply the C99 semantics to all of the many stdio functions that
perform input.  It should be enough to cover all paths to _IO_SYSREAD,
and the only other functions that call _IO_SYSREAD are the _seekoff
impls, which is OK because seeking clears EOF, and the _xsgetn impls,
which, as far as I can tell, are unused within glibc.

The test programs in this patch use a pseudoterminal to set up the
necessary conditions.  To facilitate this I added a new test-support
function that sets up a pair of pty file descriptors for you; it's
almost the same as BSD openpty, the only differences are that it
allocates the optionally-returned tty pathname with malloc, and that
it crashes if anything goes wrong.

	[BZ #1190]
        [BZ #19476]
	* libio/fileops.c (_IO_new_file_underflow): Return EOF immediately
	if the _IO_EOF_SEEN bit is already set; update commentary.
	* libio/oldfileops.c (_IO_old_file_underflow): Likewise.
	* libio/wfileops.c (_IO_wfile_underflow): Likewise.

	* support/support_openpty.c, support/tty.h: New files.
	* support/Makefile (libsupport-routines): Add support_openpty.

	* libio/tst-fgetc-after-eof.c, wcsmbs/test-fgetwc-after-eof.c:
	New test cases.
	* libio/Makefile (tests): Add tst-fgetc-after-eof.
	* wcsmbs/Makefile (tests): Add tst-fgetwc-after-eof.
2018-03-13 08:31:56 -04:00
Zack Weinberg
30bfee2630 Remove miscellaneous debris from libio.
This patch eliminates a number of #if 0 and #ifdef TODO blocks, macros
that are never used, macros that provide portability to substrates that
lack basic things like EINVAL and off_t, and other such debris.

I preserved IO_DEBUG and CHECK_FILE, even though as far as I can tell
IO_DEBUG is never defined and therefore CHECK_FILE never does
anything, because it seems like we might actually want to turn it _on_.

Installed stripped libraries and executables are unchanged, except,
again, that the line number of an assertion changes (this time it's
somewhere in fileops.c).

	* libio/libio.h (_IO_pos_BAD, _IO_pos_0, _IO_pos_adjust):
	Define here, unconditionally.
	* libio/iolibio.h (_IO_pos_BAD): Don't define here.
	* libio/libioP.h: Remove #if 0 blocks.
	(_IO_pos_BAD, _IO_pos_0, _IO_pos_adjust): Don't define here.
	(_IO_va_start, COERCE_FILE, MAYBE_SET_EINVAL): Don't define.
	(CHECK_FILE): Don't use MAYBE_SET_EINVAL or COERCE_FILE.  Fix style.

	* libio/clearerr.c, libio/fputc.c, libio/getchar.c:
	Assume weak_alias is always defined.

	* libio/fileops.c, libio/genops.c, libio/oldfileops.c
	* libio/oldpclose.c, libio/pclose.c, libio/wfileops.c:
	Remove #if 0 and #ifdef TODO blocks.
	Assume text_set_element is always defined.

	* libio/iofdopen.c, libio/iogetdelim.c, libio/oldiofdopen.c
	Use __set_errno (EINVAL) instead of MAYBE_SET_EINVAL.
	* libio/tst-mmap-eofsync.c: Make #if 1 block unconditional.
2018-02-21 14:39:54 -05:00
Zack Weinberg
9964a14579 Mechanically remove _IO_ name aliases for types and constants.
This patch mechanically removes all remaining uses, and the
definitions, of the following libio name aliases:

 name                         replaced with
 ----                         -------------
 _IO_FILE                     FILE
 _IO_fpos_t                   __fpos_t
 _IO_fpos64_t                 __fpos64_t
 _IO_size_t                   size_t
 _IO_ssize_t                  ssize_t or __ssize_t
 _IO_off_t                    off_t
 _IO_off64_t                  off64_t
 _IO_pid_t                    pid_t
 _IO_uid_t                    uid_t
 _IO_wint_t                   wint_t
 _IO_va_list                  va_list or __gnuc_va_list
 _IO_BUFSIZ                   BUFSIZ
 _IO_cookie_io_functions_t    cookie_io_functions_t
 __io_read_fn                 cookie_read_function_t
 __io_write_fn                cookie_write_function_t
 __io_seek_fn                 cookie_seek_function_t
 __io_close_fn                cookie_close_function_t

I used __fpos_t and __fpos64_t instead of fpos_t and fpos64_t because
the definitions of fpos_t and fpos64_t depend on the largefile mode.
I used __ssize_t and __gnuc_va_list in a handful of headers where
namespace cleanliness might be relevant even though they're
internal-use-only.  In all other cases, I used the public-namespace
name.

There are a tiny handful of places where I left a use of 'struct _IO_FILE'
alone, because it was being used together with 'struct _IO_FILE_plus'
or 'struct _IO_FILE_complete' in the same arithmetic expression.

Because this patch was almost entirely done with search and replace, I
may have introduced indentation botches.  I did proofread the diff,
but I may have missed something.

The ChangeLog below calls out all of the places where this was not a
pure search-and-replace change.

Installed stripped libraries and executables are unchanged by this patch,
except that some assertions in vfscanf.c change line numbers.

	* libio/libio.h (_IO_FILE): Delete; all uses changed to FILE.
	(_IO_fpos_t): Delete; all uses changed to __fpos_t.
	(_IO_fpos64_t): Delete; all uses changed to __fpos64_t.
	(_IO_size_t): Delete; all uses changed to size_t.
	(_IO_ssize_t): Delete; all uses changed to ssize_t or __ssize_t.
	(_IO_off_t): Delete; all uses changed to off_t.
	(_IO_off64_t): Delete; all uses changed to off64_t.
	(_IO_pid_t): Delete; all uses changed to pid_t.
	(_IO_uid_t): Delete; all uses changed to uid_t.
	(_IO_wint_t): Delete; all uses changed to wint_t.
	(_IO_va_list): Delete; all uses changed to va_list or __gnuc_va_list.
	(_IO_BUFSIZ): Delete; all uses changed to BUFSIZ.
	(_IO_cookie_io_functions_t): Delete; all uses changed to
	cookie_io_functions_t.
	(__io_read_fn): Delete; all uses changed to cookie_read_function_t.
	(__io_write_fn): Delete; all uses changed to cookie_write_function_t.
	(__io_seek_fn): Delete; all uses changed to cookie_seek_function_t.
	(__io_close_fn): Delete: all uses changed to cookie_close_function_t.

	* libio/iofopncook.c: Remove unnecessary forward declarations.
	* libio/iolibio.h: Correct outdated commentary.
	* malloc/malloc.c (__malloc_stats): Remove unnecessary casts.
	* stdio-common/fxprintf.c (__fxprintf_nocancel):
	Remove unnecessary casts.
	* stdio-common/getline.c: Use _IO_getdelim directly.
	Don't redefine ssize_t.
	* stdio-common/printf_fp.c, stdio_common/printf_fphex.c
	* stdio-common/printf_size.c: Don't redefine size_t or FILE.
	Remove outdated comments.
	* stdio-common/vfscanf.c: Don't redefine va_list.
2018-02-21 14:11:05 -05:00
Joseph Myers
688903eb3e Update copyright dates with scripts/update-copyrights.
* All files with FSF copyright notices: Update copyright dates
	using scripts/update-copyrights.
	* locale/programs/charmap-kw.h: Regenerated.
	* locale/programs/locfile-kw.h: Likewise.
2018-01-01 00:32:25 +00:00
Adhemerval Zanella
cc683f7ed4 libio: Free backup area when it not required (BZ#22415)
Some libio operations fail to correctly free the backup area (created
by _IO_{w}default_pbackfail on unget{w}c) resulting in either invalid
buffer free operations or memory leaks.

For instance, on the example provided by BZ#22415 a following
fputc after a fseek to rewind the stream issues an invalid free on
the buffer.  It is because although _IO_file_overflow correctly
(from fputc) correctly calls _IO_free_backup_area, the
_IO_new_file_seekoff (called by fseek) updates the FILE internal
pointers without first free the backup area (resulting in invalid
values in the internal pointers).

The wide version also shows an issue, but instead of accessing invalid
pointers it leaks the backup memory on fseek/fputwc operation.

Checked on x86_64-linux-gnu and i686-linux-gnu.

	* libio/Makefile (tests): Add tst-bz22415.
	(tst-bz22415-ENV): New rule.
	(generated): Add tst-bz22415.mtrace and tst-bz22415.check.
	(tests-special): Add tst-bz22415-mem.out.
	($(objpfx)tst-bz22415-mem.out): New rule.
	* libio/fileops.c (_IO_new_file_seekoff): Call _IO_free_backup_area
	in case of a successful seek operation.
	* libio/wfileops.c (_IO_wfile_seekoff): Likewise.
	(_IO_wfile_overflow): Call _IO_free_wbackup_area in case a write
	buffer is required.
	* libio/tst-bz22415.c: New test.
2017-12-12 17:29:54 -02:00
Florian Weimer
5f0704b66c libio: Assume _LIBC, weak_alias, errno, (__set_)errno &c are defined
Do not define _POSIX_SOURCE.
2017-08-31 14:48:25 +02:00
Joseph Myers
bfff8b1bec Update copyright dates with scripts/update-copyrights. 2017-01-01 00:14:16 +00:00
Florian Weimer
db3476aff1 libio: Implement vtable verification [BZ #20191]
This commit puts all libio vtables in a dedicated, read-only ELF
section, so that they are consecutive in memory.  Before any indirect
jump, the vtable pointer is checked against the section boundaries,
and the process is terminated if the vtable pointer does not fall into
the special ELF section.

To enable backwards compatibility, a special flag variable
(_IO_accept_foreign_vtables), protected by the pointer guard, avoids
process termination if libio stream object constructor functions have
been called earlier.  Such constructor functions are called by the GCC
2.95 libstdc++ library, and this mechanism ensures compatibility with
old binaries.  Existing callers inside glibc of these functions are
adjusted to call the original functions, not the wrappers which enable
vtable compatiblity.

The compatibility mechanism is used to enable passing FILE * objects
across a static dlopen boundary, too.
2016-06-23 20:01:52 +02:00
Joseph Myers
f7a9f785e5 Update copyright dates with scripts/update-copyrights. 2016-01-04 16:05:18 +00:00
Feng Gao
2e4250225c Use "|" instead of "+" when combine the _IO_LINE_BUF and _IO_UNBUFFERED flags
Both of "_IO_UNBUFFERED" and "_IO_LINE_BUF"  are the bit flags, but I
find there are some codes looks like "_IO_LINE_BUF+_IO_UNBUFFERED",
while some codes are "_IO_LINE_BUF|_IO_UNBUFFERED".

I think the former is not good, even though the final result is same.
2015-07-08 13:53:11 +05:30
Joseph Myers
b168057aaa Update copyright dates with scripts/update-copyrights. 2015-01-02 16:29:47 +00:00
Siddhesh Poyarekar
24b9788285 Fix up function definition style
Don't use K&R style for function definitions.
2014-12-04 08:45:55 +05:30
Siddhesh Poyarekar
fe8b4d98e9 Reset cached offset when reading to end of stream (BZ #17653)
POSIX allows applications to switch file handles when a read results
in an end of file.  Unset the cached offset at this point so that it
is queried again.
2014-12-04 08:13:28 +05:30
Siddhesh Poyarekar
be349d7042 ftell: seek to end only when there are unflushed bytes (BZ #17647)
Currently we seek to end of file if there are unflushed writes or the
stream is in write mode, to get the current offset for writing in
append mode, which is the end of file.  The latter case (i.e. stream
is in write mode, but no unflushed writes) is unnecessary since it
will only happen when the stream has just been flushed, in which case
the recorded offset ought to be reliable.

Removing that case lets ftell give the correct offset when it follows
an ftruncate.  The latter truncates the file, but does not change the
file position, due to which it is permissible to call ftell without an
intervening fseek call.

Tested on x86_64 to verify that the added test case fails without the
patch and succeeds with it, and that there are no additional
regressions due to it.

	[BZ #17647]
	* libio/fileops.c (do_ftell): Seek only when there are
	unflushed writes.
	* libio/wfileops.c (do_ftell_wide): Likewise.
	* libio/tst-ftell-active-handler.c (do_ftruncate_test): New
	test case.
	(do_one_test): Call it.
2014-12-04 08:08:37 +05:30
Andreas Schwab
04b76b5aa8 Don't error out writing a multibyte character to an unbuffered stream (bug 17522) 2014-11-03 09:58:24 +01:00
Siddhesh Poyarekar
545583d664 Fix memory leak in error path of do_ftell_wide (BZ #17370) 2014-09-16 14:20:45 +05:30
Tim Lammens
984c0ea97f Fix memory leak in libio/wfileops.c do_ftell_wide [BZ #17370] 2014-09-11 10:44:02 +05:30
Siddhesh Poyarekar
2482ae433a Fix offset computation for append+ mode on switching from read (BZ #16724)
The offset computation in write mode uses the fact that _IO_read_end
is kept in sync with the external file offset.  This however is not
true when O_APPEND is in effect since switching to write mode ought to
send the external file offset to the end of file without making the
necessary adjustment to _IO_read_end.

Hence in append mode, offset computation when writing should only
consider the effect of unflushed writes, i.e. from _IO_write_base to
_IO_write_ptr.

The wiki has a detailed document that describes the rationale for
offsets returned by ftell in various conditions:

https://sourceware.org/glibc/wiki/File%20offsets%20in%20a%20stdio%20stream%20and%20ftell
2014-05-27 13:54:19 +05:30
Siddhesh Poyarekar
ea33158c96 Fix offset caching for streams and use it for ftell (BZ #16680)
The ftell implementation was made conservative to ensure that
incorrectly cached offsets never affect it.  However, this causes
problems for append mode when a file stream is rewound.  Additionally,
the 'clever' trick of using stat to get position for append mode files
caused more problems than it solved and broke old behavior.  I have
described the various problems that it caused and then finally the
solution.

For a and a+ mode files, rewinding the stream should result in ftell
returning 0 as the offset, but the stat() trick caused it to
(incorrectly) always return the end of file.  Now I couldn't find
anything in POSIX that specifies the stream position after rewind()
for a file opened in 'a' mode, but for 'a+' mode it should be set to
0.  For 'a' mode too, it probably makes sense to keep it set to 0 in
the interest of retaining old behavior.

The initial file position for append mode files is implementation
defined, so the implementation could either retain the current file
position or move the position to the end of file.  The earlier ftell
implementation would move the offset to end of file for append-only
mode, but retain the old offset for a+ mode.  It would also cache the
offset (this detail is important).  My patch broke this and would set
the initial position to end of file for both append modes, thus
breaking old behavior.  I was ignorant enough to write an incorrect
test case for it too.

The Change:

I have now brought back the behavior of seeking to end of file for
append-only streams, but with a slight difference.  I don't cache the
offset though, since we would want ftell to query the current file
position through lseek while the stream is not active.  Since the
offset is moved to the end of file, we can rely on the file position
reported by lseek and we don't need to resort to the stat() nonsense.

Finally, the cache is always reliable, except when there are unflished
writes in an append mode stream (i.e. both a and a+).  In the latter
case, it is safe to just do an lseek to SEEK_END.  The value can be
safely cached too, since the file handle is already active at this
point.  Incidentally, this is the only state change we affect in the
file handle (apart from taking locks of course).

I have also updated the test case to correct my impression of the
initial file position for a+ streams to the initial behavior.  I have
verified that this does not break any existing tests in the testsuite
and also passes with the new tests.
2014-03-17 21:23:56 +05:30
Siddhesh Poyarekar
091eff71a5 Fix up formatting 2014-03-04 12:27:34 +05:30
Siddhesh Poyarekar
fa3cd24827 Use cached offset in ftell when reliable
The cached offset is reliable to use in ftell when the stream handle
is active.  We can consider a stream as being active when there is
unflushed data.  However, even in this case, we can use the cached
offset only when the stream is not being written to in a+ mode,
because this case may have unflushed data and a stale offset; the
previous read could have sent it off somewhere other than the end of
the file.

There were a couple of adjustments necessary to get this to work.
Firstly, fdopen now ceases to use _IO_attach_fd because it sets the
offset cache to the current file position.  This is not correct
because there could be changes to the file descriptor before the
stream handle is activated, which would not get reflected.

A similar offset caching action is done in _IO_fwide, claiming that
wide streams have 'problems' with the file offsets.  There don't seem
to be any obvious problems with not having the offset cache available,
other than that it will have to be queried in a subsequent
read/write/seek.  I have removed this as well.

The testsuite passes successfully with these changes on x86_64.
2014-03-04 12:23:28 +05:30
Siddhesh Poyarekar
000232b9bc Separate ftell from fseek logic and avoid modifying FILE data (#16532)
ftell semantics are distinct from fseek(SEEK_CUR) especially when it
is called on a file handler that is not yet active.  Due to this
caveat, much care needs to be taken while modifying the handler data
and hence, this first iteration on separating out ftell focusses on
maintaining handler data integrity at all times while it figures out
the current stream offset.  The result is that it makes a syscall for
every offset request.

There is scope for optimizing this by caching offsets when we know
that the handler is active.  A simple way to find out is when the
buffers have data.  It is not so simple to find this out when the
buffer is empty without adding some kind of flag.
2014-03-04 07:45:58 +05:30
Ondřej Bílka
a1ffb40e32 Use glibc_likely instead __builtin_expect. 2014-02-10 15:07:12 +01:00
Siddhesh Poyarekar
df675f9933 Fix infinite loop in ftell when writing wide char data (BZ #16398)
ftell tries to avoid flushing the buffer when it is in write mode by
converting the wide char data and placing it into the binary buffer.
If the output buffer space is full and there is data to write, the
code reverts to flushing the buffer.  This breaks when there is space
in the buffer but it is not enough to convert the next character in
the wide data buffer, due to which __codecvt_do_out returns a
__codecvt_partial status.  In this case, ftell keeps running in an
infinite loop.

The fix here is to detect the __codecvt_partial status in addition to
checking if the buffer is full.  I have also added a test case that
demonstrates the infinite loop.
2014-02-05 12:49:00 +05:30
Allan McRae
d4697bc93d Update copyright notices with scripts/update-copyrights 2014-01-01 22:00:23 +10:00
Joseph Myers
2e09a79ada Avoid use of "register" as optimization hint. 2013-06-07 22:24:35 +00:00
Roland McGrath
f1d70dad53 Remove lots of inline keywords. 2013-02-07 14:44:18 -08:00
Joseph Myers
568035b787 Update copyright notices with scripts/update-copyrights. 2013-01-02 19:05:09 +00:00
Joseph Myers
c8450f70fa Remove _G_off64_t and _G_stat64 from _G_config.h. 2012-10-09 15:09:32 +00:00
Siddhesh Poyarekar
adb26faefe Don't flush write buffer for ftell
[BZ #5298]
Use write pointer state along with the file offset and/or the read
pointers to get the current file position.
2012-09-28 18:38:14 +05:30
Siddhesh Poyarekar
4573c6b098 Adjust wide data buffer pointers during fseek and ftell
[BZ #14543]
Set the internal buffer state correctly whenever the external buffer
state is modified by fseek by either computing the current
_IO_read_ptr/end for the internal buffer based on the new _IO_read_ptr
in the external buffer or converting the content read into the
external buffer, up to the extent of the requested fseek offset.
2012-09-28 18:21:39 +05:30
Siddhesh Poyarekar
1ffb8c9001 Fix typos in comments
* libio/fileops.c: Fix typos in comments.
        * libio/oldfileops.c: Likewise.
        * libio/wfileops.c: Likewise.
2012-09-05 22:04:57 +05:30
Andreas Schwab
d18ea0c5e6 Remove use of INTDEF/INTUSE in libio 2012-05-24 23:06:20 +02:00
Paul Eggert
59ba27a63a Replace FSF snail mail address with URLs. 2012-02-09 23:18:22 +00:00
Marek Polacek
aaddc98c25 Remove unused variables 2011-11-11 13:27:59 -05:00