diff --git a/gnu/lib/libcxx/shlib_version b/gnu/lib/libcxx/shlib_version index c10074d52ae..f461c533903 100644 --- a/gnu/lib/libcxx/shlib_version +++ b/gnu/lib/libcxx/shlib_version @@ -1,2 +1,2 @@ -major=10 +major=11 minor=0 diff --git a/gnu/lib/libcxxabi/shlib_version b/gnu/lib/libcxxabi/shlib_version index 89ac6ba9412..b0bd05a74e2 100644 --- a/gnu/lib/libcxxabi/shlib_version +++ b/gnu/lib/libcxxabi/shlib_version @@ -1,3 +1,3 @@ # Don't forget to give libc++ the same type of bump! -major=7 +major=8 minor=0 diff --git a/gnu/lib/libexecinfo/shlib_version b/gnu/lib/libexecinfo/shlib_version index 012c14171d3..d9961ea9fef 100644 --- a/gnu/lib/libexecinfo/shlib_version +++ b/gnu/lib/libexecinfo/shlib_version @@ -1,2 +1,2 @@ -major=3 +major=4 minor=0 diff --git a/gnu/lib/libiberty/shlib_version b/gnu/lib/libiberty/shlib_version index 56246d02b24..262f3bc13b6 100644 --- a/gnu/lib/libiberty/shlib_version +++ b/gnu/lib/libiberty/shlib_version @@ -1,2 +1,2 @@ -major=12 +major=13 minor=0 diff --git a/gnu/lib/libreadline/shlib_version b/gnu/lib/libreadline/shlib_version index 3066b9771e7..9c1551636c5 100644 --- a/gnu/lib/libreadline/shlib_version +++ b/gnu/lib/libreadline/shlib_version @@ -1,2 +1,2 @@ -major=5 +major=6 minor=0 diff --git a/gnu/lib/libstdc++-v3/shlib_version b/gnu/lib/libstdc++-v3/shlib_version index 95478c54e77..35fa45f7ed2 100644 --- a/gnu/lib/libstdc++-v3/shlib_version +++ b/gnu/lib/libstdc++-v3/shlib_version @@ -1,2 +1,2 @@ -major=57 +major=58 minor=0 diff --git a/gnu/lib/libstdc++/shlib_version b/gnu/lib/libstdc++/shlib_version index 95478c54e77..35fa45f7ed2 100644 --- a/gnu/lib/libstdc++/shlib_version +++ b/gnu/lib/libstdc++/shlib_version @@ -1,2 +1,2 @@ -major=57 +major=58 minor=0 diff --git a/gnu/usr.bin/perl/shlib_version b/gnu/usr.bin/perl/shlib_version index 361604a5eb3..c622cb8cdf3 100644 --- a/gnu/usr.bin/perl/shlib_version +++ b/gnu/usr.bin/perl/shlib_version @@ -1,2 +1,2 @@ -major=25 +major=26 minor=0 diff --git a/include/stdio.h b/include/stdio.h index 74bcd6ff3e3..1ef395b0610 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -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) diff --git a/include/wchar.h b/include/wchar.h index 96e86a15515..efaf8dbcfc4 100644 --- a/include/wchar.h +++ b/include/wchar.h @@ -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 #include -#include /* 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_ */ diff --git a/lib/libc/Symbols.list b/lib/libc/Symbols.list index 6eb2cca93e5..85517b2efbf 100644 --- a/lib/libc/Symbols.list +++ b/lib/libc/Symbols.list @@ -1371,10 +1371,14 @@ __fwriting __sF __srget __swbuf +__stderr +__stdin +__stdout asprintf clearerr dprintf fclose +fdclose fdopen feof ferror diff --git a/lib/libc/hidden/_stdio.h b/lib/libc/hidden/_stdio.h new file mode 100644 index 00000000000..db1c331afe5 --- /dev/null +++ b/lib/libc/hidden/_stdio.h @@ -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_ */ diff --git a/lib/libc/hidden/stdio.h b/lib/libc/hidden/stdio.h index a40a4b45c1d..a25abb5b9e9 100644 --- a/lib/libc/hidden/stdio.h +++ b/lib/libc/hidden/stdio.h @@ -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 * @@ -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 +#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_ */ diff --git a/lib/libc/hidden/wchar.h b/lib/libc/hidden/wchar.h index c77dbd695b4..9804da6a469 100644 --- a/lib/libc/hidden/wchar.h +++ b/lib/libc/hidden/wchar.h @@ -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 * @@ -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 +#include <_stdio.h> /* struct __sFILE, std{in,out,err} */ PROTO_NORMAL(btowc); PROTO_NORMAL(fgetwc); diff --git a/lib/libc/shlib_version b/lib/libc/shlib_version index 7a749b0c915..98af1dc86b6 100644 --- a/lib/libc/shlib_version +++ b/lib/libc/shlib_version @@ -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. diff --git a/lib/libc/stdio/Makefile.inc b/lib/libc/stdio/Makefile.inc index 4da652e324d..844f55134af 100644 --- a/lib/libc/stdio/Makefile.inc +++ b/lib/libc/stdio/Makefile.inc @@ -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 \ diff --git a/lib/libc/stdio/fclose.3 b/lib/libc/stdio/fclose.3 index 57622322421..df308480326 100644 --- a/lib/libc/stdio/fclose.3 +++ b/lib/libc/stdio/fclose.3 @@ -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 . diff --git a/lib/libc/stdio/fclose.c b/lib/libc/stdio/fclose.c index 10266bd0a62..28c62d206a9 100644 --- a/lib/libc/stdio/fclose.c +++ b/lib/libc/stdio/fclose.c @@ -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 + * All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. @@ -36,6 +37,25 @@ #include #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); } diff --git a/lib/libc/stdio/fdclose.c b/lib/libc/stdio/fdclose.c new file mode 100644 index 00000000000..2a0855e10f5 --- /dev/null +++ b/lib/libc/stdio/fdclose.c @@ -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 + * 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 +#include +#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; +} diff --git a/lib/libc/stdio/findfp.c b/lib/libc/stdio/findfp.c index 6fd80d0c415..4a94b3df818 100644 --- a/lib/libc/stdio/findfp.c +++ b/lib/libc/stdio/findfp.c @@ -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 /* ALIGN ALIGNBYTES */ -#include -#include #include +#include +#include #include #include +#include + #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) diff --git a/lib/libcrypto/shlib_version b/lib/libcrypto/shlib_version index a5cb76dd4fe..79adf54372d 100644 --- a/lib/libcrypto/shlib_version +++ b/lib/libcrypto/shlib_version @@ -1,3 +1,3 @@ # Don't forget to give libssl and libtls the same type of bump! -major=56 +major=57 minor=0 diff --git a/lib/libcurses/shlib_version b/lib/libcurses/shlib_version index 9c0249765d4..50dca71750e 100644 --- a/lib/libcurses/shlib_version +++ b/lib/libcurses/shlib_version @@ -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 diff --git a/lib/libedit/shlib_version b/lib/libedit/shlib_version index 9c1551636c5..5b844bbf422 100644 --- a/lib/libedit/shlib_version +++ b/lib/libedit/shlib_version @@ -1,2 +1,2 @@ -major=6 +major=7 minor=0 diff --git a/lib/libexpat/shlib_version b/lib/libexpat/shlib_version index 77913220429..84e2c2920d7 100644 --- a/lib/libexpat/shlib_version +++ b/lib/libexpat/shlib_version @@ -1,2 +1,2 @@ -major=15 +major=16 minor=0 diff --git a/lib/libfido2/shlib_version b/lib/libfido2/shlib_version index 5b844bbf422..d0f0988b418 100644 --- a/lib/libfido2/shlib_version +++ b/lib/libfido2/shlib_version @@ -1,2 +1,2 @@ -major=7 +major=8 minor=0 diff --git a/lib/libfuse/shlib_version b/lib/libfuse/shlib_version index b52599a164f..012c14171d3 100644 --- a/lib/libfuse/shlib_version +++ b/lib/libfuse/shlib_version @@ -1,2 +1,2 @@ -major=2 +major=3 minor=0 diff --git a/lib/libkvm/shlib_version b/lib/libkvm/shlib_version index ffdd3d2d569..94727e17b3a 100644 --- a/lib/libkvm/shlib_version +++ b/lib/libkvm/shlib_version @@ -1,2 +1,2 @@ -major=17 +major=18 minor=0 diff --git a/lib/libpcap/shlib_version b/lib/libpcap/shlib_version index 1c5d96eb2aa..c10074d52ae 100644 --- a/lib/libpcap/shlib_version +++ b/lib/libpcap/shlib_version @@ -1,2 +1,2 @@ -major=9 +major=10 minor=0 diff --git a/lib/librthread/shlib_version b/lib/librthread/shlib_version index 72e5894f74e..295c96b24e9 100644 --- a/lib/librthread/shlib_version +++ b/lib/librthread/shlib_version @@ -1,2 +1,2 @@ -major=27 -minor=1 +major=28 +minor=0 diff --git a/lib/libskey/shlib_version b/lib/libskey/shlib_version index 9c1551636c5..5b844bbf422 100644 --- a/lib/libskey/shlib_version +++ b/lib/libskey/shlib_version @@ -1,2 +1,2 @@ -major=6 +major=7 minor=0 diff --git a/lib/libsndio/shlib_version b/lib/libsndio/shlib_version index 9521c10dfe1..d0f0988b418 100644 --- a/lib/libsndio/shlib_version +++ b/lib/libsndio/shlib_version @@ -1,2 +1,2 @@ -major=7 -minor=3 +major=8 +minor=0 diff --git a/lib/libutil/shlib_version b/lib/libutil/shlib_version index dc34974a494..83b24802061 100644 --- a/lib/libutil/shlib_version +++ b/lib/libutil/shlib_version @@ -1,2 +1,2 @@ -major=20 -minor=1 +major=21 +minor=0