1
0
mirror of https://github.com/openbsd/src.git synced 2026-06-17 23:03:29 +02:00

Make the FILE object opaque. Move the __sFILE definition into

libc/hidden/_stdio.h.  All programs that refer to the internal
structure of the FILE object can't be compiled from now on.
std{in,out,err} doesn't refer __sF[] now, but the hidden __sF along
with __srget and __swbuf symbols are kept temporarily to make our
transition easier.  But those symbols will be deleted soon.  The shared
library versions are bumped for libc and all the other libraries that
refer to std{in,out,err}.

diff from guenther, tweak by me, tested by many
ok sthen tb
This commit is contained in:
yasuoka
2025-07-16 15:33:05 +00:00
parent 59ba13b996
commit b7f6c2eb76
32 changed files with 429 additions and 219 deletions
+1 -1
View File
@@ -1,2 +1,2 @@
major=10
major=11
minor=0
+1 -1
View File
@@ -1,3 +1,3 @@
# Don't forget to give libc++ the same type of bump!
major=7
major=8
minor=0
+1 -1
View File
@@ -1,2 +1,2 @@
major=3
major=4
minor=0
+1 -1
View File
@@ -1,2 +1,2 @@
major=12
major=13
minor=0
+1 -1
View File
@@ -1,2 +1,2 @@
major=5
major=6
minor=0
+1 -1
View File
@@ -1,2 +1,2 @@
major=57
major=58
minor=0
+1 -1
View File
@@ -1,2 +1,2 @@
major=57
major=58
minor=0
+1 -1
View File
@@ -1,2 +1,2 @@
major=25
major=26
minor=0
+13 -148
View File
@@ -1,4 +1,4 @@
/* $OpenBSD: stdio.h,v 1.56 2024/08/07 05:15:28 guenther Exp $ */
/* $OpenBSD: stdio.h,v 1.57 2025/07/16 15:33:05 yasuoka Exp $ */
/* $NetBSD: stdio.h,v 1.18 1996/04/25 18:29:21 jtc Exp $ */
/*-
@@ -60,97 +60,21 @@ typedef __off_t off_t;
typedef off_t fpos_t; /* stdio file position type */
/*
* NB: to fit things in six character monocase externals, the stdio
* code uses the prefix `__s' for stdio objects, typically followed
* by a three-character attempt at a mnemonic.
*/
/* stdio buffers */
struct __sbuf {
unsigned char *_base;
int _size;
};
/*
* stdio state variables.
*
* The following always hold:
*
* if (_flags&(__SLBF|__SWR)) == (__SLBF|__SWR),
* _lbfsize is -_bf._size, else _lbfsize is 0
* if _flags&__SRD, _w is 0
* if _flags&__SWR, _r is 0
*
* This ensures that the getc and putc macros (or inline functions) never
* try to write or read from a file that is in `read' or `write' mode.
* (Moreover, they can, and do, automatically switch from read mode to
* write mode, and back, on "r+" and "w+" files.)
*
* _lbfsize is used only to make the inline line-buffered output stream
* code as compact as possible.
*
* _ub, _up, and _ur are used when ungetc() pushes back more characters
* than fit in the current _bf, or when ungetc() pushes back a character
* that does not match the previous one in _bf. When this happens,
* _ub._base becomes non-nil (i.e., a stream has ungetc() data iff
* _ub._base!=NULL) and _up and _ur save the current values of _p and _r.
*/
typedef struct __sFILE {
unsigned char *_p; /* current position in (some) buffer */
int _r; /* read space left for getc() */
int _w; /* write space left for putc() */
short _flags; /* flags, below; this FILE is free if 0 */
short _file; /* fileno, if Unix descriptor, else -1 */
struct __sbuf _bf; /* the buffer (at least 1 byte, if !NULL) */
int _lbfsize; /* 0 or -_bf._size, for inline putc */
/* operations */
void *_cookie; /* cookie passed to io functions */
int (*_close)(void *);
int (*_read)(void *, char *, int);
fpos_t (*_seek)(void *, fpos_t, int);
int (*_write)(void *, const char *, int);
/* extension data, to avoid further ABI breakage */
struct __sbuf _ext;
/* data for long sequences of ungetc() */
unsigned char *_up; /* saved _p when _p is doing ungetc data */
int _ur; /* saved _r when _r is counting ungetc data */
/* tricks to meet minimum requirements even when malloc() fails */
unsigned char _ubuf[3]; /* guarantee an ungetc() buffer */
unsigned char _nbuf[1]; /* guarantee a getc() buffer */
/* separate buffer for fgetln() when line crosses buffer boundary */
struct __sbuf _lb; /* buffer for fgetln() */
/* Unix stdio files get aligned to block boundaries on fseek() */
int _blksize; /* stat.st_blksize (may be != _bf._size) */
fpos_t _offset; /* current lseek offset */
} FILE;
#ifndef _STDFILES_DECLARED
#define _STDFILES_DECLARED
typedef struct __sFILE FILE;
struct __sFstub { long _stub; };
__BEGIN_DECLS
extern FILE __sF[];
extern struct __sFstub __stdin[];
extern struct __sFstub __stdout[];
extern struct __sFstub __stderr[];
__END_DECLS
#endif
#define __SLBF 0x0001 /* line buffered */
#define __SNBF 0x0002 /* unbuffered */
#define __SRD 0x0004 /* OK to read */
#define __SWR 0x0008 /* OK to write */
/* RD and WR are never simultaneously asserted */
#define __SRW 0x0010 /* open for reading & writing */
#define __SEOF 0x0020 /* found EOF */
#define __SERR 0x0040 /* found error */
#define __SMBF 0x0080 /* _buf is from malloc */
#define __SAPP 0x0100 /* fdopen()ed in append mode */
#define __SSTR 0x0200 /* this is an sprintf/snprintf string */
#define __SOPT 0x0400 /* do fseek() optimisation */
#define __SNPT 0x0800 /* do not do fseek() optimisation */
#define __SOFF 0x1000 /* set iff _offset is in fact correct */
#define __SMOD 0x2000 /* true => fgetln modified _p text */
#define __SALC 0x4000 /* allocate string space dynamically */
#define __SIGN 0x8000 /* ignore this file in _fwalk */
#define stdin ((struct __sFILE *)__stdin)
#define stdout ((struct __sFILE *)__stdout)
#define stderr ((struct __sFILE *)__stderr)
/*
* The following three definitions are for ANSI C, which took them
@@ -194,10 +118,6 @@ __END_DECLS
#define SEEK_END 2 /* set file offset to EOF plus offset */
#endif
#define stdin (&__sF[0])
#define stdout (&__sF[1])
#define stderr (&__sF[2])
/*
* Functions defined in ANSI C standard.
*/
@@ -357,6 +277,7 @@ __END_DECLS
*/
#if __BSD_VISIBLE
__BEGIN_DECLS
int fdclose(FILE *, int *_fdp);
char *fgetln(FILE *, size_t *);
int fpurge(FILE *);
int getw(FILE *);
@@ -379,62 +300,6 @@ __END_DECLS
#define fwopen(cookie, fn) funopen(cookie, 0, fn, 0, 0)
#endif /* __BSD_VISIBLE */
/*
* Functions internal to the implementation.
*/
__BEGIN_DECLS
int __srget(FILE *);
int __swbuf(int, FILE *);
__END_DECLS
/*
* The __sfoo macros are here so that we can
* define function versions in the C library.
*/
#define __sgetc(p) (--(p)->_r < 0 ? __srget(p) : (int)(*(p)->_p++))
static __inline int __sputc(int _c, FILE *_p) {
if (--_p->_w >= 0 || (_p->_w >= _p->_lbfsize && (char)_c != '\n'))
return (*_p->_p++ = _c);
else
return (__swbuf(_c, _p));
}
#define __sfeof(p) (((p)->_flags & __SEOF) != 0)
#define __sferror(p) (((p)->_flags & __SERR) != 0)
#define __sclearerr(p) ((void)((p)->_flags &= ~(__SERR|__SEOF)))
#define __sfileno(p) ((p)->_file)
extern int __isthreaded;
#define feof(p) (!__isthreaded ? __sfeof(p) : (feof)(p))
#define ferror(p) (!__isthreaded ? __sferror(p) : (ferror)(p))
#define clearerr(p) (!__isthreaded ? __sclearerr(p) : (clearerr)(p))
#if __POSIX_VISIBLE
#define fileno(p) (!__isthreaded ? __sfileno(p) : (fileno)(p))
#endif
#define getc(fp) (!__isthreaded ? __sgetc(fp) : (getc)(fp))
#if __BSD_VISIBLE
/*
* The macro implementations of putc and putc_unlocked are not
* fully POSIX compliant; they do not set errno on failure
*/
#define putc(x, fp) (!__isthreaded ? __sputc(x, fp) : (putc)(x, fp))
#endif /* __BSD_VISIBLE */
#if __POSIX_VISIBLE >= 199506
#define getc_unlocked(fp) __sgetc(fp)
/*
* The macro implementations of putc and putc_unlocked are not
* fully POSIX compliant; they do not set errno on failure
*/
#if __BSD_VISIBLE
#define putc_unlocked(x, fp) __sputc(x, fp)
#endif /* __BSD_VISIBLE */
#endif /* __POSIX_VISIBLE >= 199506 */
#define getchar() getc(stdin)
#define putchar(x) putc(x, stdout)
#define getchar_unlocked() getc_unlocked(stdin)
+14 -4
View File
@@ -1,4 +1,4 @@
/* $OpenBSD: wchar.h,v 1.33 2024/08/07 04:59:45 guenther Exp $ */
/* $OpenBSD: wchar.h,v 1.34 2025/07/16 15:33:05 yasuoka Exp $ */
/* $NetBSD: wchar.h,v 1.16 2003/03/07 07:11:35 tshiozak Exp $ */
/*-
@@ -63,7 +63,17 @@
#include <sys/_null.h>
#include <sys/_types.h>
#include <stdio.h> /* for FILE* */
#ifndef _STDFILES_DECLARED
#define _STDFILES_DECLARED
typedef struct __sFILE FILE;
struct __sFstub { long _stub; };
__BEGIN_DECLS
extern struct __sFstub __stdin[];
extern struct __sFstub __stdout[];
extern struct __sFstub __stderr[];
__END_DECLS
#endif
#if !defined(_WCHAR_T_DEFINED_) && !defined(__cplusplus)
#define _WCHAR_T_DEFINED_
@@ -235,9 +245,9 @@ wchar_t *fgetwln(FILE * __restrict, size_t * __restrict);
#endif
#define getwc(f) fgetwc(f)
#define getwchar() getwc(stdin)
#define getwchar() getwc((FILE *)__stdin)
#define putwc(wc, f) fputwc((wc), (f))
#define putwchar(wc) putwc((wc), stdout)
#define putwchar(wc) putwc((wc), (FILE *)__stdout)
__END_DECLS
#endif /* !_WCHAR_H_ */
+4
View File
@@ -1371,10 +1371,14 @@ __fwriting
__sF
__srget
__swbuf
__stderr
__stdin
__stdout
asprintf
clearerr
dprintf
fclose
fdclose
fdopen
feof
ferror
+142
View File
@@ -0,0 +1,142 @@
/* $OpenBSD: _stdio.h,v 1.1 2025/07/16 15:33:05 yasuoka Exp $ */
/* $NetBSD: stdio.h,v 1.18 1996/04/25 18:29:21 jtc Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Chris Torek.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)stdio.h 5.17 (Berkeley) 6/3/91
*/
#ifndef _LIBC__STDIO_H_
#define _LIBC__STDIO_H_
/*
* NB: to fit things in six character monocase externals, the stdio
* code uses the prefix `__s' for stdio objects, typically followed
* by a three-character attempt at a mnemonic.
* XXX With this all strictly inside libc, the naming rules are no
* XXX longer necessary.
*/
/* stdio buffers */
struct __sbuf {
unsigned char *_base;
int _size;
};
typedef __off_t fpos_t;
/*
* stdio state variables.
*
* The following always hold:
*
* if (_flags&(__SLBF|__SWR)) == (__SLBF|__SWR),
* _lbfsize is -_bf._size, else _lbfsize is 0
* if _flags&__SRD, _w is 0
* if _flags&__SWR, _r is 0
*
* This ensures that the getc and putc macros (or inline functions) never
* try to write or read from a file that is in `read' or `write' mode.
* (Moreover, they can, and do, automatically switch from read mode to
* write mode, and back, on "r+" and "w+" files.)
*
* _lbfsize is used only to make the inline line-buffered output stream
* code as compact as possible.
*
* _ub, _up, and _ur are used when ungetc() or ungetwc() push back more
* characters than fit in the current _bf, or when ungetc() or ungetwc() push
* back a character that does not match the previous one in _bf. When this
* happens, _ub._base becomes non-nil (i.e., a stream has ungetc() data iff
* _ub._base!=NULL) and _up and _ur save the current values of _p and _r.
*/
struct __sFILE {
unsigned char *_p; /* current position in (some) buffer */
int _r; /* read space left for getc() */
int _w; /* write space left for putc() */
short _flags; /* flags, below; this FILE is free if 0 */
short _file; /* fileno, if Unix descriptor, else -1 */
struct __sbuf _bf; /* the buffer (at least 1 byte, if !NULL) */
int _lbfsize; /* 0 or -_bf._size, for inline putc */
/* operations */
void *_cookie; /* cookie passed to io functions */
int (*_close)(void *);
int (*_read)(void *, char *, int);
fpos_t (*_seek)(void *, fpos_t, int);
int (*_write)(void *, const char *, int);
/* extension data, to avoid further ABI breakage */
struct __sbuf _ext;
/* data for long sequences of ungetc() */
unsigned char *_up; /* saved _p when _p is doing ungetc data */
int _ur; /* saved _r when _r is counting ungetc data */
/* tricks to meet minimum requirements even when malloc() fails */
unsigned char _ubuf[3]; /* guarantee an ungetc() buffer */
unsigned char _nbuf[1]; /* guarantee a getc() buffer */
/* separate buffer for fgetln() when line crosses buffer boundary */
struct __sbuf _lb; /* buffer for fgetln() */
/* Unix stdio files get aligned to block boundaries on fseek() */
int _blksize; /* stat.st_blksize (may be != _bf._size) */
fpos_t _offset; /* current lseek offset */
};
#define __SLBF 0x0001 /* line buffered */
#define __SNBF 0x0002 /* unbuffered */
#define __SRD 0x0004 /* OK to read */
#define __SWR 0x0008 /* OK to write */
/* RD and WR are never simultaneously asserted */
#define __SRW 0x0010 /* open for reading & writing */
#define __SEOF 0x0020 /* found EOF */
#define __SERR 0x0040 /* found error */
#define __SMBF 0x0080 /* _buf is from malloc */
#define __SAPP 0x0100 /* fdopen()ed in append mode */
#define __SSTR 0x0200 /* this is an sprintf/snprintf string */
#define __SOPT 0x0400 /* do fseek() optimisation */
#define __SNPT 0x0800 /* do not do fseek() optimisation */
#define __SOFF 0x1000 /* set iff _offset is in fact correct */
#define __SMOD 0x2000 /* true => fgetln modified _p text */
#define __SALC 0x4000 /* allocate string space dynamically */
#define __SIGN 0x8000 /* ignore this file in _fwalk */
#define __SONW 0x10000 /* orientation set to narrow */
#define __SOWD 0x20000 /* orientation set to wide */
/* ONW and OWD are never simultaneously asserted */
__BEGIN_DECLS
extern FILE __stdin[];
extern FILE __stdout[];
extern FILE __stderr[];
__END_DECLS
#endif /* _LIBC__STDIO_H_ */
+46 -6
View File
@@ -1,4 +1,4 @@
/* $OpenBSD: stdio.h,v 1.8 2022/05/14 05:06:32 guenther Exp $ */
/* $OpenBSD: stdio.h,v 1.9 2025/07/16 15:33:05 yasuoka Exp $ */
/*
* Copyright (c) 2015 Philip Guenther <guenther@openbsd.org>
*
@@ -18,17 +18,23 @@
#ifndef _LIBC_STDIO_H_
#define _LIBC_STDIO_H_
/* Rename __swbuf() before it's used in the inline __sputc() */
struct __sFILE;
int __swbuf(int, struct __sFILE *);
PROTO_NORMAL(__swbuf);
/* we want the const-correct declarations inside libc */
#define __SYS_ERRLIST
#ifndef _STDFILES_DECLARED
#define _STDFILES_DECLARED
typedef struct __sFILE FILE;
#endif
int __swbuf(int, struct __sFILE *);
int __srget(struct __sFILE *);
PROTO_NORMAL(__swbuf);
#include_next <stdio.h>
#include <_stdio.h> /* struct __sFILE, std{in,out,err} */
__BEGIN_HIDDEN_DECLS
int __cleanfile(FILE *, int _doclose);
char *_mktemp(char *);
__END_HIDDEN_DECLS
@@ -46,6 +52,7 @@ PROTO_NORMAL(clearerr);
PROTO_NORMAL(ctermid);
PROTO_NORMAL(dprintf);
PROTO_NORMAL(fclose);
PROTO_DEPRECATED(fdclose);
PROTO_NORMAL(fdopen);
PROTO_NORMAL(feof);
PROTO_NORMAL(ferror);
@@ -118,4 +125,37 @@ PROTO_NORMAL(vsnprintf);
PROTO_STD_DEPRECATED(vsprintf);
PROTO_NORMAL(vsscanf);
/*
* The __sfoo macros are here so that we can
* define function versions in the C library.
*/
#define __sgetc(p) (--(p)->_r < 0 ? __srget(p) : (int)(*(p)->_p++))
static __inline int __sputc(int _c, FILE *_p) {
if (--_p->_w >= 0 || (_p->_w >= _p->_lbfsize && (char)_c != '\n'))
return (*_p->_p++ = _c);
else
return (__swbuf(_c, _p));
}
#define __sfeof(p) (((p)->_flags & __SEOF) != 0)
#define __sferror(p) (((p)->_flags & __SERR) != 0)
#define __sclearerr(p) ((void)((p)->_flags &= ~(__SERR|__SEOF)))
#define __sfileno(p) ((p)->_file)
extern int __isthreaded;
#define feof(p) (!__isthreaded ? __sfeof(p) : (feof)(p))
#define ferror(p) (!__isthreaded ? __sferror(p) : (ferror)(p))
#define clearerr(p) (!__isthreaded ? __sclearerr(p) : (clearerr)(p))
#define fileno(p) (!__isthreaded ? __sfileno(p) : (fileno)(p))
#define getc(fp) (!__isthreaded ? __sgetc(fp) : (getc)(fp))
/*
* The macro implementations of putc and putc_unlocked are not
* fully POSIX compliant; they do not set errno on failure
*/
#define putc(x, fp) (!__isthreaded ? __sputc(x, fp) : (putc)(x, fp))
#define getc_unlocked(fp) __sgetc(fp)
#define putc_unlocked(x, fp) __sputc(x, fp)
#endif /* _LIBC_STDIO_H_ */
+7 -1
View File
@@ -1,4 +1,4 @@
/* $OpenBSD: wchar.h,v 1.5 2024/07/14 09:51:18 jca Exp $ */
/* $OpenBSD: wchar.h,v 1.6 2025/07/16 15:33:05 yasuoka Exp $ */
/*
* Copyright (c) 2015 Philip Guenther <guenther@openbsd.org>
*
@@ -18,7 +18,13 @@
#ifndef _LIBC_WCHAR_H_
#define _LIBC_WCHAR_H_
#ifndef _STDFILES_DECLARED
#define _STDFILES_DECLARED
typedef struct __sFILE FILE;
#endif
#include_next <wchar.h>
#include <_stdio.h> /* struct __sFILE, std{in,out,err} */
PROTO_NORMAL(btowc);
PROTO_NORMAL(fgetwc);
+2 -2
View File
@@ -1,4 +1,4 @@
major=100
minor=3
major=101
minor=0
# note: If changes were made to include/thread_private.h or if system calls
# were added/changed then librthread/shlib_version must also be updated.
+2 -2
View File
@@ -1,11 +1,11 @@
# $OpenBSD: Makefile.inc,v 1.31 2024/08/12 20:56:55 guenther Exp $
# $OpenBSD: Makefile.inc,v 1.32 2025/07/16 15:33:05 yasuoka Exp $
# stdio sources
.PATH: ${LIBCSRCDIR}/stdio
CFLAGS+=-DFLOATING_POINT -DPRINTF_WIDE_CHAR -DSCANF_WIDE_CHAR
SRCS+= asprintf.c clrerr.c fclose.c fdopen.c feof.c ferror.c fflush.c fgetc.c \
SRCS+= asprintf.c clrerr.c fclose.c fdclose.c fdopen.c feof.c ferror.c fflush.c fgetc.c \
fgetln.c fgetpos.c fgets.c fileno.c findfp.c flags.c fmemopen.c \
fopen.c fprintf.c fpurge.c fputc.c fputs.c fread.c freopen.c fscanf.c \
fseek.c fsetpos.c ftell.c funopen.c fvwrite.c fwalk.c fwrite.c \
+53 -6
View File
@@ -1,4 +1,4 @@
.\" $OpenBSD: fclose.3,v 1.12 2025/06/03 14:15:53 yasuoka Exp $
.\" $OpenBSD: fclose.3,v 1.13 2025/07/16 15:33:05 yasuoka Exp $
.\"
.\" Copyright (c) 1990, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -31,16 +31,19 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd $Mdocdate: June 3 2025 $
.Dd $Mdocdate: July 16 2025 $
.Dt FCLOSE 3
.Os
.Sh NAME
.Nm fclose
.Nm fclose ,
.Nm fdclose
.Nd close a stream
.Sh SYNOPSIS
.In stdio.h
.Ft int
.Fn fclose "FILE *stream"
.Ft int
.Fn fdclose "FILE *stream" "int *fdp"
.Sh DESCRIPTION
The
.Fn fclose
@@ -53,6 +56,25 @@ while if the stream was being used for input then the underlying
file position may be updated,
as if via
.Xr fflush 3 .
.Pp
The
.Fn fdclose
function is equivalent to
.Fn fclose
except that it does not close the associated file descriptor.
If
.Fa fdp
is not
.Dv NULL ,
the file descriptor will be stored through it.
If the stream was created with a function other than
.Xr fopen 3 ,
.Xr fdopen 3 ,
or
.Xr freopen 3
and as a result does not have an associated file descriptor then
-1 will stored through
.Fa fdp .
.Sh RETURN VALUES
Upon successful completion 0 is returned.
Otherwise,
@@ -62,6 +84,11 @@ is returned and the global variable
is set to indicate the error.
In either case no further access to the stream is possible.
.Sh ERRORS
The
.Fn fclose
and
.Fn fdclose
functions will fail if
.Bl -tag -width Er
.It Bq Er EBADF
The argument
@@ -70,13 +97,28 @@ is not an open stream.
.El
.Pp
The
.Fn fdclose
function will fail if
.Bl -tag -width Er
.It Bq Er EOPNOTSUPP
The argument
.Fa stream
does not have an associated file descriptor.
.El
.Pp
They may also fail and set
.Va errno
for any of the errors specified for the
.Xr fflush 3
routine.
.Pp
The
.Fn fclose
function may also fail and set
.Va errno
for any of the errors specified for the routines
for any of the errors specified for the
.Xr close 2
or
.Xr fflush 3 .
routine.
.Sh SEE ALSO
.Xr close 2 ,
.Xr fflush 3 ,
@@ -92,3 +134,8 @@ The
.Fn fclose
function first appeared in
.At v7 .
.Pp
The
.Fn fdclose
function first appeared in
.Fx 11.0 .
+24 -15
View File
@@ -1,7 +1,8 @@
/* $OpenBSD: fclose.c,v 1.13 2025/06/03 14:15:53 yasuoka Exp $ */
/* $OpenBSD: fclose.c,v 1.14 2025/07/16 15:33:05 yasuoka Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
* Copyright (c) 1990, 1993 The Regents of the University of California.
* Copyright (c) 2013 Mariusz Zaborski <oshogbo@FreeBSD.org>
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Chris Torek.
@@ -36,6 +37,25 @@
#include <stdlib.h>
#include "local.h"
int
__cleanfile(FILE *fp, int doclose)
{
int r;
r = __sflush(fp);
if (doclose && fp->_close != NULL && (*fp->_close)(fp->_cookie) < 0)
r = EOF;
if (fp->_flags & __SMBF)
free(fp->_bf._base);
if (HASUB(fp))
FREEUB(fp);
if (HASLB(fp))
FREELB(fp);
fp->_r = fp->_w = 0; /* Mess up if reaccessed. */
fp->_flags = 0; /* Release this FILE for reuse. */
return r;
}
int
fclose(FILE *fp)
{
@@ -46,18 +66,7 @@ fclose(FILE *fp)
return (EOF);
}
FLOCKFILE(fp);
WCIO_FREE(fp);
r = __sflush(fp);
if (fp->_close != NULL && (*fp->_close)(fp->_cookie) < 0)
r = EOF;
if (fp->_flags & __SMBF)
free((char *)fp->_bf._base);
if (HASUB(fp))
FREEUB(fp);
if (HASLB(fp))
FREELB(fp);
fp->_r = fp->_w = 0; /* Mess up if reaccessed. */
fp->_flags = 0; /* Release this FILE for reuse. */
r = __cleanfile(fp, 1);
FUNLOCKFILE(fp);
return (r);
}
+72
View File
@@ -0,0 +1,72 @@
/* $OpenBSD: fdclose.c,v 1.1 2025/07/16 15:33:05 yasuoka Exp $ */
/*-
* Copyright (c) 1990, 1993 The Regents of the University of California.
* Copyright (c) 2013 Mariusz Zaborski <oshogbo@FreeBSD.org>
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Chris Torek.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <errno.h>
#include <stdio.h>
#include "local.h"
int
fdclose(FILE *fp, int *fdp)
{
int r, err;
if (fdp != NULL)
*fdp = -1;
if (fp->_flags == 0) { /* not open! */
errno = EBADF;
return EOF;
}
FLOCKFILE(fp);
r = 0;
if (fp->_close != __sclose) {
r = EOF;
err = EOPNOTSUPP;
} else if (fp->_file < 0) {
r = EOF;
err = EBADF;
}
if (r == EOF) {
(void)__cleanfile(fp, 1);
errno = err;
} else {
if (fdp != NULL)
*fdp = fp->_file;
r = __cleanfile(fp, 0);
}
FUNLOCKFILE(fp);
return r;
}
+27 -12
View File
@@ -1,4 +1,4 @@
/* $OpenBSD: findfp.c,v 1.20 2021/11/29 03:20:37 deraadt Exp $ */
/* $OpenBSD: findfp.c,v 1.21 2025/07/16 15:33:05 yasuoka Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -32,11 +32,13 @@
*/
#include <sys/param.h> /* ALIGN ALIGNBYTES */
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "local.h"
#include "glue.h"
#include "thread_private.h"
@@ -45,11 +47,11 @@ int __sdidinit;
#define NDYNAMIC 10 /* add ten more whenever necessary */
#define std(flags, file) \
{0,0,0,flags,file,{0},0,__sF+file,__sclose,__sread,__sseek,__swrite, \
{(unsigned char *)(__sFext+file), 0}}
/* p r w flags file _bf z cookie close read seek write
ext */
#define std(flags, file, cookie) \
{ ._flags = (flags), ._file = (file), ._cookie = (cookie), \
._close = __sclose, ._read = __sread, ._seek = __sseek, \
._write = __swrite, ._ext = { (unsigned char *)(__sFext + file), 0} }
/* the usual - (stdin + stdout + stderr) */
static FILE usual[FOPEN_MAX - 3];
@@ -59,12 +61,25 @@ static struct glue *lastglue = &uglue;
static void *sfp_mutex;
static struct __sfileext __sFext[3];
/*
* These are separate variables because they may end up copied
* into program images via COPY relocations, so their addresses
* won't be related. That also means they need separate glue :(
*/
FILE __stdin[1] = { std(__SRD, STDIN_FILENO, __stdin) };
FILE __stdout[1] = { std(__SWR, STDOUT_FILENO, __stdout) };
FILE __stderr[1] = { std(__SWR|__SNBF, STDERR_FILENO, __stderr) };
static struct glue sglue2 = { &uglue, 1, __stderr };
static struct glue sglue1 = { &sglue2, 1, __stdout };
struct glue __sglue = { &sglue1, 1, __stdin };
/* __sF[] for old version */
FILE __sF[3] = {
std(__SRD, STDIN_FILENO), /* stdin */
std(__SWR, STDOUT_FILENO), /* stdout */
std(__SWR|__SNBF, STDERR_FILENO) /* stderr */
std(__SRD, STDIN_FILENO, __stdin),
std(__SWR, STDOUT_FILENO, __stdout),
std(__SWR|__SNBF, STDERR_FILENO, __stderr)
};
struct glue __sglue = { &uglue, 3, __sF };
static struct glue *
moreglue(int n)
+1 -1
View File
@@ -1,3 +1,3 @@
# Don't forget to give libssl and libtls the same type of bump!
major=56
major=57
minor=0
+1 -1
View File
@@ -1,3 +1,3 @@
# Don't forget to give libedit and gnu/lib/libreadline the same type of bump!
major=15
major=16
minor=0
+1 -1
View File
@@ -1,2 +1,2 @@
major=6
major=7
minor=0
+1 -1
View File
@@ -1,2 +1,2 @@
major=15
major=16
minor=0
+1 -1
View File
@@ -1,2 +1,2 @@
major=7
major=8
minor=0
+1 -1
View File
@@ -1,2 +1,2 @@
major=2
major=3
minor=0
+1 -1
View File
@@ -1,2 +1,2 @@
major=17
major=18
minor=0
+1 -1
View File
@@ -1,2 +1,2 @@
major=9
major=10
minor=0
+2 -2
View File
@@ -1,2 +1,2 @@
major=27
minor=1
major=28
minor=0
+1 -1
View File
@@ -1,2 +1,2 @@
major=6
major=7
minor=0
+2 -2
View File
@@ -1,2 +1,2 @@
major=7
minor=3
major=8
minor=0
+2 -2
View File
@@ -1,2 +1,2 @@
major=20
minor=1
major=21
minor=0