From b0bf75c83c24db04cd99f83728e00bfa29d2df5e Mon Sep 17 00:00:00 2001 From: "Andrey A. Chernov" Date: Mon, 16 Oct 2006 14:31:56 +0000 Subject: [PATCH] file == NULL: Issue __sflush() before possible setting O_APPEND mode or ftruncate(), write to wrong place may occurse oserwise. Use simplified _sseek() to the start, if no O_APPEND is set, instead of _fseeko() (_sseek() to the end, if O_APPEND, occurse later, as for file != NULL). Don't check seek error return, as original fopen() and freopen() never does. file != NULL: Add missing _sseek() to the end. --- lib/libc/stdio/freopen.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/lib/libc/stdio/freopen.c b/lib/libc/stdio/freopen.c index 70cfd601aa3a..7142eee26e84 100644 --- a/lib/libc/stdio/freopen.c +++ b/lib/libc/stdio/freopen.c @@ -104,6 +104,8 @@ freopen(file, mode, fp) errno = EINVAL; return (NULL); } + if (fp->_flags & __SWR) + (void) __sflush(fp); if ((oflags ^ dflags) & O_APPEND) { dflags &= ~O_APPEND; dflags |= oflags & O_APPEND; @@ -117,15 +119,8 @@ freopen(file, mode, fp) } if (oflags & O_TRUNC) (void) ftruncate(fp->_file, (off_t)0); - fp->_flags |= __SNPT; /* real seek */ - if (_fseeko(fp, (off_t)0, oflags & O_APPEND ? SEEK_END : SEEK_SET, - 0) < 0 && errno != ESPIPE) { - sverrno = errno; - fclose(fp); - FUNLOCKFILE(fp); - errno = sverrno; - return (NULL); - } + if (!(oflags & O_APPEND)) + (void) _sseek(fp, (fpos_t)0, SEEK_SET); f = fp->_file; isopen = 0; wantfd = -1; @@ -219,6 +214,16 @@ freopen(file, mode, fp) fp->_write = __swrite; fp->_seek = __sseek; fp->_close = __sclose; + /* + * When opening in append mode, even though we use O_APPEND, + * we need to seek to the end so that ftell() gets the right + * answer. If the user then alters the seek pointer, or + * the file extends, this will fail, but there is not much + * we can do about this. (We could set __SAPP and check in + * fseek and ftell.) + */ + if (oflags & O_APPEND) + (void) _sseek(fp, (fpos_t)0, SEEK_END); FUNLOCKFILE(fp); return (fp); }