git: 9fb5c02356b0 - stable/14 - fileno(3): set errno when returning -1

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Tue, 03 Dec 2024 00:51:23 UTC
The branch stable/14 has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=9fb5c02356b0717aa3cdde3c19adc6d3f0521225

commit 9fb5c02356b0717aa3cdde3c19adc6d3f0521225
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2024-11-28 22:12:29 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2024-12-03 00:39:22 +0000

    fileno(3): set errno when returning -1
    
    PR:     283014
    
    (cherry picked from commit 7cd756ff4fe7e65a9a3f588904998bf6f4b37623)
---
 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 b7c412c81da7..0b6d9f22709d 100644
--- a/include/stdio.h
+++ b/include/stdio.h
@@ -497,10 +497,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 1529c002fb7f..7c4a3ee58b23 100644
--- a/lib/libc/stdio/ferror.3
+++ b/lib/libc/stdio/ferror.3
@@ -112,9 +112,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 3adf8dcb959e..cb5bfef8409b 100644
--- a/lib/libc/stdio/fileno.c
+++ b/lib/libc/stdio/fileno.c
@@ -36,6 +36,7 @@
 static char sccsid[] = "@(#)fileno.c	8.1 (Berkeley) 6/4/93";
 #endif /* LIBC_SCCS and not lint */
 #include "namespace.h"
+#include <errno.h>
 #include <stdio.h>
 #include "un-namespace.h"
 #include "libc_private.h"
@@ -43,14 +44,29 @@ static char sccsid[] = "@(#)fileno.c	8.1 (Berkeley) 6/4/93";
 #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);
 }
@@ -58,6 +74,5 @@ fileno(FILE *fp)
 int
 fileno_unlocked(FILE *fp)
 {
-
-	return (__sfileno(fp));
+	return (__fileno_impl(fp));
 }