-.\" $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.
.\" 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
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.
The
.Fn fclose
function conforms to
-.St -ansiC .
+.St -p1003.1-2024 .
.Sh HISTORY
The
.Fn fclose
-/* $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.
}
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)
-.\" $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.
.\" 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
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
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,
.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
The
.Fn fflush
function conforms to
-.St -ansiC .
+.St -p1003.1-2024 .
.Sh HISTORY
A predecessor
.Fn flush
-/* $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.
#include <errno.h>
#include <stdio.h>
+#include <stdlib.h>
#include "local.h"
/* Flush a single file, or (if fp is NULL) all files. */
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);
}
__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);
}
-/* $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.
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) {
-/* $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.
/*
* 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.
__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 ||
* 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);
-/* $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.
* 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 {
.\" 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
.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
.Sh SEE ALSO
.Xr _exit 2 ,
.Xr atexit 3 ,
+.Xr fflush 3 ,
.Xr intro 3 ,
.Xr sysexits 3 ,
.Xr tmpfile 3
The
.Fn exit
function conforms to
-.St -isoC-99 .
+.St -p1003.1-2024 .
.Sh HISTORY
An
.Fn exit