diff options
| author | Dag-Erling Smørgrav <des@FreeBSD.org> | 2026-02-02 15:46:57 +0000 |
|---|---|---|
| committer | Dag-Erling Smørgrav <des@FreeBSD.org> | 2026-02-02 15:46:57 +0000 |
| commit | 5074d5c9845e142883cdbb9ad212be66e57615d0 (patch) | |
| tree | 07a0cb69533619ce94736f9426027fe9bcf3fe53 | |
| parent | 387ae6390534b6e9b48931840e7bc76eeb0b258d (diff) | |
libc: Improve POSIX conformance of dirfd()
POSIX states that dirfd() should set errno to EINVAL and return -1 if
dirp does not refer to a valid directory stream. Our interpretation is
that this applies if dirp is null or the file descriptor associated
with it is negative.
MFC after: 1 week
Sponsored by: Klara, Inc.
Reviewed by: markj
Differential Revision: https://reviews.freebsd.org/D55025
| -rw-r--r-- | lib/libc/gen/directory.3 | 14 | ||||
| -rw-r--r-- | lib/libc/gen/dirfd.c | 5 |
2 files changed, 18 insertions, 1 deletions
diff --git a/lib/libc/gen/directory.3 b/lib/libc/gen/directory.3 index ccbc60b03776..270abb2d2371 100644 --- a/lib/libc/gen/directory.3 +++ b/lib/libc/gen/directory.3 @@ -256,7 +256,9 @@ The function returns 0 on success and -1 on failure. The .Fn fdclosedir -function returns an open file descriptor on success and -1 on failure. +and +.Fn dirfd +functions return an open file descriptor on success and -1 on failure. .Sh ERRORS The .Fn opendir @@ -327,6 +329,16 @@ function may also fail and set .Va errno for any of the errors specified for the routine .Xr close 2 . +.Pp +The +.Fn dirfd +function will fail if: +.Bl -tag -width Er +.It Bq Er EINVAL +The +.Fa dirp +argument does not refer to a valid directory stream. +.El .Sh SEE ALSO .Xr close 2 , .Xr lseek 2 , diff --git a/lib/libc/gen/dirfd.c b/lib/libc/gen/dirfd.c index ba8f52845b4e..fbbf703b5a2e 100644 --- a/lib/libc/gen/dirfd.c +++ b/lib/libc/gen/dirfd.c @@ -28,6 +28,7 @@ #include "namespace.h" #include <dirent.h> +#include <errno.h> #include "un-namespace.h" #include "gen-private.h" @@ -35,5 +36,9 @@ int dirfd(DIR *dirp) { + if (dirp == NULL || _dirfd(dirp) < 0) { + errno = EINVAL; + return (-1); + } return (_dirfd(dirp)); } |
