diff --git a/include/stdio.h b/include/stdio.h index ee3ab3bfb98..3dedb8fd5a5 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 71671f69f24..b921c428060 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 66502430dc3..0ba242c1aed 100644 --- a/lib/libc/stdio/fileno.c +++ b/lib/libc/stdio/fileno.c @@ -33,6 +33,7 @@ */ #include "namespace.h" +#include #include #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)); }