> and _stat32i64, when applied to the "NUL" device on mingw, reports > that "NUL" is a regular file.
It's worth mentioning this bug in the documentation. And adding a unit test. 2025-06-12 Bruno Haible <br...@clisp.org> stat, lstat, fstat tests: Enhance tests regarding /dev/null or NUL. * tests/test-fstat.c: Include <fcntl.h>. (main): Check that fstat reports /dev/null or NUL as a character device. * tests/test-stat.h (test_stat_func): Likewise for stat. * tests/test-lstat.h (test_lstat_func): Likewise for lstat. 2025-06-12 Bruno Haible <br...@clisp.org> stat: Document mingw bug. * doc/posix-functions/stat.texi: Mention the bug with NUL on mingw.
>From 2b918f2e68b801daf7a4268d611c1ed9cbee1574 Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Fri, 13 Jun 2025 00:02:57 +0200 Subject: [PATCH 1/2] stat: Document mingw bug. * doc/posix-functions/stat.texi: Mention the bug with NUL on mingw. --- ChangeLog | 5 +++++ doc/posix-functions/stat.texi | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/ChangeLog b/ChangeLog index a12a1707c9..cb4853e4b3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2025-06-12 Bruno Haible <br...@clisp.org> + + stat: Document mingw bug. + * doc/posix-functions/stat.texi: Mention the bug with NUL on mingw. + 2025-06-12 Bruno Haible <br...@clisp.org> stat: Add support for mingw 13 in 32-bit mode. diff --git a/doc/posix-functions/stat.texi b/doc/posix-functions/stat.texi index 160e86b978..6e0df396a5 100644 --- a/doc/posix-functions/stat.texi +++ b/doc/posix-functions/stat.texi @@ -36,6 +36,10 @@ different results: mingw, MSVC 14. @item +@c https://sourceforge.net/p/mingw-w64/bugs/1009/ +On mingw, the @code{st_mode} field of @code{stat("NUL",buf)} is bogus, +suggesting that @code{NUL} is a regular file. +@item On macOS 12.6, when this function yields a timestamp with a nonpositive @code{tv_sec} value, @code{tv_nsec} might be in the range @minus{}999999999..@minus{}1, representing a negative nanoseconds -- 2.43.0
>From fab078415a9789b8f74aae37d2cf94f103f7261d Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Thu, 12 Jun 2025 19:45:19 +0200 Subject: [PATCH 2/2] stat, lstat, fstat tests: Enhance tests regarding /dev/null or NUL. * tests/test-fstat.c: Include <fcntl.h>. (main): Check that fstat reports /dev/null or NUL as a character device. * tests/test-stat.h (test_stat_func): Likewise for stat. * tests/test-lstat.h (test_lstat_func): Likewise for lstat. --- ChangeLog | 8 ++++++++ tests/test-fstat.c | 17 +++++++++++++++++ tests/test-lstat.h | 9 +++++++++ tests/test-stat.h | 9 +++++++++ 4 files changed, 43 insertions(+) diff --git a/ChangeLog b/ChangeLog index cb4853e4b3..da241662d7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2025-06-12 Bruno Haible <br...@clisp.org> + + stat, lstat, fstat tests: Enhance tests regarding /dev/null or NUL. + * tests/test-fstat.c: Include <fcntl.h>. + (main): Check that fstat reports /dev/null or NUL as a character device. + * tests/test-stat.h (test_stat_func): Likewise for stat. + * tests/test-lstat.h (test_lstat_func): Likewise for lstat. + 2025-06-12 Bruno Haible <br...@clisp.org> stat: Document mingw bug. diff --git a/tests/test-fstat.c b/tests/test-fstat.c index 474e262077..7e65ee2f23 100644 --- a/tests/test-fstat.c +++ b/tests/test-fstat.c @@ -22,6 +22,7 @@ SIGNATURE_CHECK (fstat, int, (int, struct stat *)); #include <errno.h> +#include <fcntl.h> #include <unistd.h> #include "macros.h" @@ -46,5 +47,21 @@ main () ASSERT (errno == EBADF); } + /* /dev/null is a character device. */ + { + int fd; + struct stat statbuf; + +#if defined _WIN32 && !defined __CYGWIN__ + fd = open ("NUL", O_RDWR); +#else + fd = open ("/dev/null", O_RDWR); +#endif + ASSERT (fstat (fd, &statbuf) == 0); + close (fd); + ASSERT (!S_ISREG (statbuf.st_mode)); + ASSERT (S_ISCHR (statbuf.st_mode)); + } + return test_exit_status; } diff --git a/tests/test-lstat.h b/tests/test-lstat.h index b9846df710..fb9a808a76 100644 --- a/tests/test-lstat.h +++ b/tests/test-lstat.h @@ -64,6 +64,15 @@ test_lstat_func (int (*func) (char const *, struct stat *), bool print) ASSERT (func (BASE "file/", &st1) == -1); ASSERT (errno == ENOTDIR); + /* /dev/null is a character device. */ +#if defined _WIN32 && !defined __CYGWIN__ + ASSERT (func ("NUL", &st1) == 0); +#else + ASSERT (func ("/dev/null", &st1) == 0); +#endif + ASSERT (!S_ISREG (st1.st_mode)); + ASSERT (S_ISCHR (st1.st_mode)); + /* Now for some symlink tests, where supported. We set up: link1 -> directory link2 -> file diff --git a/tests/test-stat.h b/tests/test-stat.h index fc0a9d4dd5..3d2b912e8f 100644 --- a/tests/test-stat.h +++ b/tests/test-stat.h @@ -61,6 +61,15 @@ test_stat_func (int (*func) (char const *, struct stat *), bool print) ASSERT (func (BASE "file/", &st1) == -1); ASSERT (errno == ENOTDIR); + /* /dev/null is a character device. */ +#if defined _WIN32 && !defined __CYGWIN__ + ASSERT (func ("NUL", &st1) == 0); +#else + ASSERT (func ("/dev/null", &st1) == 0); +#endif + ASSERT (!S_ISREG (st1.st_mode)); + ASSERT (S_ISCHR (st1.st_mode)); + /* Now for some symlink tests, where supported. We set up: link1 -> directory link2 -> file -- 2.43.0