git: 7cd756ff4fe7 - main - fileno(3): set errno when returning -1

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Fri, 29 Nov 2024 15:26:13 UTC
The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=7cd756ff4fe7e65a9a3f588904998bf6f4b37623

commit 7cd756ff4fe7e65a9a3f588904998bf6f4b37623
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2024-11-28 22:12:29 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2024-11-29 15:25:32 +0000

    fileno(3): set errno when returning -1
    
    as required by IEEE Std 1003.1™-2024.
    
    PR:     283014
    Reported by:    Graham Percival <gperciva@tarsnap.com>
    Reviewed by:    emaste, imp
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D47834
---
 include/stdio.h         |  4 ----
 lib/libc/stdio/ferror.3 | 20 ++++++++++++++++++--
 lib/libc/stdio/fileno.c | 25 ++++++++++++++++++++-----
 3 files changed, 38 insertions(+), 11 deletions(-)

diff --git a/include/stdio.h b/include/stdio.h
index ee3ab3bfb986..3dedb8fd5a54 100644
--- a/include/stdio.h
+++ b/include/stdio.h
@@ -506,10 +506,6 @@ extern int __isthreaded;
 #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))
 #define	putc(x, fp)	(!__isthreaded ? __sputc(x, fp) : (putc)(x, fp))
 
diff --git a/lib/libc/stdio/ferror.3 b/lib/libc/stdio/ferror.3
index 71671f69f247..b921c4280607 100644
--- a/lib/libc/stdio/ferror.3
+++ b/lib/libc/stdio/ferror.3
@@ -110,9 +110,25 @@ before calling them.
 These functions may be used to avoid the overhead of locking the stream
 and to prevent races when multiple threads are operating on the same stream.
 .Sh ERRORS
-These functions should not fail and do not set the external
-variable
+These functions, except
+.Fn fileno ,
+should not fail and do not set the external variable
 .Va errno .
+.Pp
+On error,
+.Fn fileno
+returns \-1 and sets
+.Va errno
+to one of the following values:
+.Bl -tag -width Er
+.It Bq Er EBADF
+The stream is not associated with a file.
+.It Bq Er EBADF
+The file descriptor underlying stream is not a valid file descriptor.
+.Pp
+Note that detection of this condition is not reliable, the error might
+be not reported.
+.El
 .Sh SEE ALSO
 .Xr open 2 ,
 .Xr fdopen 3 ,
diff --git a/lib/libc/stdio/fileno.c b/lib/libc/stdio/fileno.c
index 66502430dc3d..0ba242c1aed3 100644
--- a/lib/libc/stdio/fileno.c
+++ b/lib/libc/stdio/fileno.c
@@ -33,6 +33,7 @@
  */
 
 #include "namespace.h"
+#include <errno.h>
 #include <stdio.h>
 #include "un-namespace.h"
 #include "libc_private.h"
@@ -40,14 +41,29 @@
 #undef fileno
 #undef fileno_unlocked
 
+static int
+__fileno_impl(FILE *fp)
+{
+	int fd;
+
+	fd = fp->_file;
+	if (fd == -1)
+		errno = EBADF;
+	return (fd);
+}
+
 int
 fileno(FILE *fp)
 {
 	int fd;
 
-	FLOCKFILE(fp);
-	fd = __sfileno(fp);
-	FUNLOCKFILE(fp);
+	if (__isthreaded) {
+		FLOCKFILE(fp);
+		fd = __fileno_impl(fp);
+		FUNLOCKFILE(fp);
+	} else {
+		fd = __fileno_impl(fp);
+	}
 
 	return (fd);
 }
@@ -55,6 +71,5 @@ fileno(FILE *fp)
 int
 fileno_unlocked(FILE *fp)
 {
-
-	return (__sfileno(fp));
+	return (__fileno_impl(fp));
 }