summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorPhilip Guenther <guenther@cvs.openbsd.org>2024-08-12 20:53:10 +0000
committerPhilip Guenther <guenther@cvs.openbsd.org>2024-08-12 20:53:10 +0000
commit5d4e5874ed04b1a4c1cf1b5c2b62f1400651c0d6 (patch)
tree81a29c90ed3adee86b543d78e65fda9b3a481829 /lib
parenta20e90e8c3317fd59cb16b445a5562e6f46bc005 (diff)
Make exit(), fclose(), fflush(), and freopen() comply with POSIX-2008
requirements for setting the underlying file position when flushing read-mode streams, and make an fseek()-after-fflush() not change the underlying file position. Much testing, review, and assistance from tb@ ok tb@ millert@
Diffstat (limited to 'lib')
-rw-r--r--lib/libc/stdio/fclose.313
-rw-r--r--lib/libc/stdio/fclose.c4
-rw-r--r--lib/libc/stdio/fflush.328
-rw-r--r--lib/libc/stdio/fflush.c62
-rw-r--r--lib/libc/stdio/freopen.c7
-rw-r--r--lib/libc/stdio/fseek.c9
-rw-r--r--lib/libc/stdio/ftell.c5
-rw-r--r--lib/libc/stdlib/exit.311
8 files changed, 88 insertions, 51 deletions
diff --git a/lib/libc/stdio/fclose.3 b/lib/libc/stdio/fclose.3
index b1f7c536b0a..cedcaed15ed 100644
--- a/lib/libc/stdio/fclose.3
+++ b/lib/libc/stdio/fclose.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: fclose.3,v 1.9 2015/11/04 21:30:13 tedu Exp $
+.\" $OpenBSD: fclose.3,v 1.10 2024/08/12 20:53:09 guenther Exp $
.\"
.\" Copyright (c) 1990, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -31,7 +31,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd $Mdocdate: November 4 2015 $
+.Dd $Mdocdate: August 12 2024 $
.Dt FCLOSE 3
.Os
.Sh NAME
@@ -47,8 +47,11 @@ The
function dissociates the named
.Fa stream
from its underlying file or set of functions.
-If the stream was being used for output, any buffered data is written
-first, using
+If the stream was being used for output then any buffered data is written
+first,
+while if the stream was being used for input then the underlying
+file position may be updated,
+as if via
.Xr fflush 3 .
.Sh RETURN VALUES
Upon successful completion 0 is returned.
@@ -83,7 +86,7 @@ or
The
.Fn fclose
function conforms to
-.St -ansiC .
+.St -p1003.1-2024 .
.Sh HISTORY
The
.Fn fclose
diff --git a/lib/libc/stdio/fclose.c b/lib/libc/stdio/fclose.c
index 4bd162abc84..07026faccd4 100644
--- a/lib/libc/stdio/fclose.c
+++ b/lib/libc/stdio/fclose.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fclose.c,v 1.10 2015/08/31 02:53:57 guenther Exp $ */
+/* $OpenBSD: fclose.c,v 1.11 2024/08/12 20:53:09 guenther Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -47,7 +47,7 @@ fclose(FILE *fp)
}
FLOCKFILE(fp);
WCIO_FREE(fp);
- r = fp->_flags & __SWR ? __sflush(fp) : 0;
+ r = __sflush(fp);
if (fp->_close != NULL && (*fp->_close)(fp->_cookie) < 0)
r = EOF;
if (fp->_flags & __SMBF)
diff --git a/lib/libc/stdio/fflush.3 b/lib/libc/stdio/fflush.3
index 677d087c817..1e1c7803942 100644
--- a/lib/libc/stdio/fflush.3
+++ b/lib/libc/stdio/fflush.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: fflush.3,v 1.13 2019/09/07 10:28:27 schwarze Exp $
+.\" $OpenBSD: fflush.3,v 1.14 2024/08/12 20:53:09 guenther Exp $
.\"
.\" Copyright (c) 1990, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -31,7 +31,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd $Mdocdate: September 7 2019 $
+.Dd $Mdocdate: August 12 2024 $
.Dt FFLUSH 3
.Os
.Sh NAME
@@ -50,6 +50,20 @@ The function
forces a write of all buffered data for the given output or update
.Fa stream
via the stream's underlying write function.
+If
+.Fa stream
+is a stream opened for reading with
+.Xr fdopen 3 ,
+.Xr fopen 3 ,
+or
+.Xr freopen 3
+of a seekable file and it is not already at EOF then
+.Fn fflush
+sets the seek position of the file to the file position of the
+stream and discards any text pushed back by via
+.Xr ungetc 3
+or
+.Xr ungetwc 3 .
The open status of the stream is unaffected.
.Pp
If the
@@ -70,7 +84,9 @@ For input streams this discards any input read from the underlying object
but not yet obtained via
.Xr getc 3 ;
this includes any text pushed back via
-.Xr ungetc 3 .
+.Xr ungetc 3
+or
+.Xr ungetwc 3 .
.Sh RETURN VALUES
Upon successful completion 0 is returned.
Otherwise,
@@ -82,9 +98,7 @@ is set to indicate the error.
.Bl -tag -width Er
.It Bq Er EBADF
.Fa stream
-is not an open stream or, in the case of
-.Fn fflush ,
-not a stream open for writing.
+is not an open stream.
.El
.Pp
The function
@@ -102,7 +116,7 @@ for any of the errors specified for the routine
The
.Fn fflush
function conforms to
-.St -ansiC .
+.St -p1003.1-2024 .
.Sh HISTORY
A predecessor
.Fn flush
diff --git a/lib/libc/stdio/fflush.c b/lib/libc/stdio/fflush.c
index fd1a4b3504b..5888e2364c8 100644
--- a/lib/libc/stdio/fflush.c
+++ b/lib/libc/stdio/fflush.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fflush.c,v 1.9 2015/08/31 02:53:57 guenther Exp $ */
+/* $OpenBSD: fflush.c,v 1.10 2024/08/12 20:53:09 guenther Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -33,6 +33,7 @@
#include <errno.h>
#include <stdio.h>
+#include <stdlib.h>
#include "local.h"
/* Flush a single file, or (if fp is NULL) all files. */
@@ -44,11 +45,7 @@ fflush(FILE *fp)
if (fp == NULL)
return (_fwalk(__sflush_locked));
FLOCKFILE(fp);
- if ((fp->_flags & (__SWR | __SRW)) == 0) {
- errno = EBADF;
- r = EOF;
- } else
- r = __sflush(fp);
+ r = __sflush(fp);
FUNLOCKFILE(fp);
return (r);
}
@@ -58,30 +55,51 @@ int
__sflush(FILE *fp)
{
unsigned char *p;
+ fpos_t off;
int n, t;
t = fp->_flags;
- if ((t & __SWR) == 0)
- return (0);
+ if (t & __SWR) {
+ if ((p = fp->_bf._base) == NULL)
+ return (0);
- if ((p = fp->_bf._base) == NULL)
- return (0);
+ n = fp->_p - p; /* write this much */
- n = fp->_p - p; /* write this much */
+ /*
+ * Set these immediately to avoid problems with longjmp and to
+ * allow exchange buffering (via setvbuf) in user write
+ * function.
+ */
+ fp->_p = p;
+ fp->_w = t & (__SLBF|__SNBF) ? 0 : fp->_bf._size;
- /*
- * Set these immediately to avoid problems with longjmp and to allow
- * exchange buffering (via setvbuf) in user write function.
- */
- fp->_p = p;
- fp->_w = t & (__SLBF|__SNBF) ? 0 : fp->_bf._size;
+ for (; n > 0; n -= t, p += t) {
+ t = (*fp->_write)(fp->_cookie, (char *)p, n);
+ if (t <= 0) {
+ fp->_flags |= __SERR;
+ return (EOF);
+ }
+ }
+ } else if ((t & __SRD) && !(t & __SEOF)) {
+ if (fp->_seek != __sseek || fp->_file < 0) {
+ errno = EBADF;
+ return EOF;
+ }
- for (; n > 0; n -= t, p += t) {
- t = (*fp->_write)(fp->_cookie, (char *)p, n);
- if (t <= 0) {
- fp->_flags |= __SERR;
- return (EOF);
+ off = fp->_r;
+ if (HASUB(fp)) {
+ off += fp->_ur;
+ FREEUB(fp);
}
+ if (t & __SOFF) {
+ off = fp->_offset - off;
+ __sseek(fp->_cookie, off, SEEK_SET);
+ } else if (off != 0)
+ __sseek(fp->_cookie, -off, SEEK_CUR);
+
+ WCIO_FREE(fp);
+ fp->_p = fp->_bf._base;
+ fp->_r = 0;
}
return (0);
}
diff --git a/lib/libc/stdio/freopen.c b/lib/libc/stdio/freopen.c
index 65065e54d7d..2b82300c0b2 100644
--- a/lib/libc/stdio/freopen.c
+++ b/lib/libc/stdio/freopen.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: freopen.c,v 1.17 2019/06/29 16:12:21 deraadt Exp $ */
+/* $OpenBSD: freopen.c,v 1.18 2024/08/12 20:53:09 guenther Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -75,9 +75,8 @@ freopen(const char *file, const char *mode, FILE *fp)
isopen = 0;
wantfd = -1;
} else {
- /* flush the stream; ANSI doesn't require this. */
- if (fp->_flags & __SWR)
- (void) __sflush(fp);
+ /* flush the stream; POSIX, not ANSI, requires this. */
+ (void) __sflush(fp);
/* if close is NULL, closing is a no-op, hence pointless */
isopen = fp->_close != NULL;
if ((wantfd = fp->_file) < 0 && isopen) {
diff --git a/lib/libc/stdio/fseek.c b/lib/libc/stdio/fseek.c
index 18c530138a6..a65867d3f46 100644
--- a/lib/libc/stdio/fseek.c
+++ b/lib/libc/stdio/fseek.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fseek.c,v 1.14 2022/05/14 05:06:32 guenther Exp $ */
+/* $OpenBSD: fseek.c,v 1.15 2024/08/12 20:53:09 guenther Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -116,7 +116,8 @@ fseeko(FILE *fp, off_t offset, int whence)
/*
* Can only optimise if:
* reading (and not reading-and-writing);
- * not unbuffered; and
+ * not unbuffered;
+ * not immediately after an fflush(); and
* this is a `regular' Unix file (and hence seekfn==__sseek).
* We must check __NBF first, because it is possible to have __NBF
* and __SOPT both set.
@@ -125,6 +126,8 @@ fseeko(FILE *fp, off_t offset, int whence)
__smakebuf(fp);
if (fp->_flags & (__SWR | __SRW | __SNBF | __SNPT))
goto dumb;
+ if (fp->_r == 0 && (fp->_p == NULL || fp->_p == fp->_bf._base))
+ goto dumb;
if ((fp->_flags & __SOPT) == 0) {
if (seekfn != __sseek ||
fp->_file < 0 || fstat(fp->_file, &st) == -1 ||
@@ -228,7 +231,7 @@ fseeko(FILE *fp, off_t offset, int whence)
* do it. Allow the seek function to change fp->_bf._base.
*/
dumb:
- if (__sflush(fp) ||
+ if (((fp->_flags & __SWR) && __sflush(fp)) ||
(*seekfn)(fp->_cookie, (fpos_t)offset, whence) == POS_ERR) {
FUNLOCKFILE(fp);
return (EOF);
diff --git a/lib/libc/stdio/ftell.c b/lib/libc/stdio/ftell.c
index a75ebbbaad7..69e1f0d6ef9 100644
--- a/lib/libc/stdio/ftell.c
+++ b/lib/libc/stdio/ftell.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ftell.c,v 1.11 2015/08/31 02:53:57 guenther Exp $ */
+/* $OpenBSD: ftell.c,v 1.12 2024/08/12 20:53:09 guenther Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -55,7 +55,8 @@ ftello(FILE *fp)
* adjust for buffered bytes.
*/
FLOCKFILE(fp);
- __sflush(fp); /* may adjust seek offset on append stream */
+ if (fp->_flags & __SWR)
+ __sflush(fp); /* may adjust seek offset on append stream */
if (fp->_flags & __SOFF)
pos = fp->_offset;
else {
diff --git a/lib/libc/stdlib/exit.3 b/lib/libc/stdlib/exit.3
index a1c43780d65..5e006e53f40 100644
--- a/lib/libc/stdlib/exit.3
+++ b/lib/libc/stdlib/exit.3
@@ -29,9 +29,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $OpenBSD: exit.3,v 1.16 2014/11/30 21:21:59 schwarze Exp $
+.\" $OpenBSD: exit.3,v 1.17 2024/08/12 20:53:09 guenther Exp $
.\"
-.Dd $Mdocdate: November 30 2014 $
+.Dd $Mdocdate: August 12 2024 $
.Dt EXIT 3
.Os
.Sh NAME
@@ -54,9 +54,7 @@ Call the functions registered with the
.Xr atexit 3
function, in the reverse order of their registration.
.It
-Flush all open output streams.
-.It
-Close all open streams.
+Flush and close all open streams.
.It
Unlink all files created with the
.Xr tmpfile 3
@@ -79,6 +77,7 @@ function never returns.
.Sh SEE ALSO
.Xr _exit 2 ,
.Xr atexit 3 ,
+.Xr fflush 3 ,
.Xr intro 3 ,
.Xr sysexits 3 ,
.Xr tmpfile 3
@@ -86,7 +85,7 @@ function never returns.
The
.Fn exit
function conforms to
-.St -isoC-99 .
+.St -p1003.1-2024 .
.Sh HISTORY
An
.Fn exit