summaryrefslogtreecommitdiffstats
path: root/lib/libc/stdio/freopen.c
diff options
context:
space:
mode:
authorache <ache@FreeBSD.org>2006-10-16 14:31:56 +0000
committerache <ache@FreeBSD.org>2006-10-16 14:31:56 +0000
commit9a7ddac59ad48ee1b12b63eba29c6904028d622e (patch)
treef5a89eeb33f1fd9a61ff920ed5b4c15cd519d3c2 /lib/libc/stdio/freopen.c
parent26039aabd1c4ce251355792287ab53f304632aae (diff)
downloadFreeBSD-src-9a7ddac59ad48ee1b12b63eba29c6904028d622e.zip
FreeBSD-src-9a7ddac59ad48ee1b12b63eba29c6904028d622e.tar.gz
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.
Diffstat (limited to 'lib/libc/stdio/freopen.c')
-rw-r--r--lib/libc/stdio/freopen.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/lib/libc/stdio/freopen.c b/lib/libc/stdio/freopen.c
index 70cfd60..7142eee 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 @@ finish:
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);
}
OpenPOWER on IntegriCloud