On 2025-11-16 22:57, Bruno Haible wrote:
These two new tests fail on NetBSD 10.0:
Thanks, I installed the attached which fixed things for me on NetBSD 10.0.
From 20074698382b7e4f049f52bbdeaf6a39508a8601 Mon Sep 17 00:00:00 2001 From: Paul Eggert <[email protected]> Date: Mon, 17 Nov 2025 16:28:24 -0800 Subject: [PATCH] openat2: follow OS re EFTYPE/EMLINK/ELOOP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On FreeBSD and NetBSD, have openat2 behave like openat with respect to whether O_NOFOLLOW fails with EMLINK and EFTYPE when opening a symlink. Although these openat implementations do not conform to POSIX, their behavior is arguably more useful than the POSIX behavior so let’s have openat2 be consistent with openat rather than matching the GNU/Linux behavior. This should fix a test failure reported by Bruno Haible in: https://lists.gnu.org/r/bug-gnulib/2025-11/msg00183.html * lib/fcntl.in.h (_GL_OPENAT_ESYMLINK): New macro. * lib/openat2.c (do_openat2): Use it instead of ELOOP. * tests/test-openat2.c (is_nofollow_error): Use it; this makes the tests pickier on FreeBSD and NetBSD, as they now require local behavior. --- ChangeLog | 17 +++++++++++++++++ lib/fcntl.in.h | 9 +++++++++ lib/openat2.c | 6 +++--- tests/test-openat2.c | 10 +--------- 4 files changed, 30 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index d6350250e8..823398850d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2025-11-17 Paul Eggert <[email protected]> + + openat2: follow OS re EFTYPE/EMLINK/ELOOP + On FreeBSD and NetBSD, have openat2 behave like openat + with respect to whether O_NOFOLLOW fails with EMLINK and EFTYPE + when opening a symlink. Although these openat implementations + do not conform to POSIX, their behavior is arguably more useful + than the POSIX behavior so let’s have openat2 be consistent with + openat rather than matching the GNU/Linux behavior. + This should fix a test failure reported by Bruno Haible in: + https://lists.gnu.org/r/bug-gnulib/2025-11/msg00183.html + * lib/fcntl.in.h (_GL_OPENAT_ESYMLINK): New macro. + * lib/openat2.c (do_openat2): Use it instead of ELOOP. + * tests/test-openat2.c (is_nofollow_error): + Use it; this makes the tests pickier on FreeBSD and NetBSD, + as they now require local behavior. + 2025-11-17 Bruno Haible <[email protected]> readutmp, boot-time tests: Fix test failure in CentOS 7 CI environments. diff --git a/lib/fcntl.in.h b/lib/fcntl.in.h index 3fbbf4b0e4..bcb5606b13 100644 --- a/lib/fcntl.in.h +++ b/lib/fcntl.in.h @@ -495,6 +495,15 @@ _GL_WARN_ON_USE (openat2, "openat2 is not portable - " # define AT_NO_AUTOMOUNT 0 #endif +/* errno when openat+O_NOFOLLOW fails because the file is a symlink. */ +#if defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __DragonFly__ +# define _GL_OPENAT_ESYMLINK EMLINK +#elif defined __NetBSD__ +# define _GL_OPENAT_ESYMLINK EFTYPE +#else +# define _GL_OPENAT_ESYMLINK ELOOP +#endif + #endif /* _@GUARD_PREFIX@_FCNTL_H */ #endif /* _@GUARD_PREFIX@_FCNTL_H */ #endif diff --git a/lib/openat2.c b/lib/openat2.c index 9281e7a1a2..d616b80a55 100644 --- a/lib/openat2.c +++ b/lib/openat2.c @@ -333,7 +333,7 @@ do_openat2 (int *fd, char const *filename, if (subfd < 0) { int openerr = negative_errno (); - if (! ((openerr == -ELOOP) + if (! ((openerr == -_GL_OPENAT_ESYMLINK) | (!!(subflags & O_DIRECTORY) & (openerr == -ENOTDIR)))) return openerr; @@ -363,7 +363,7 @@ do_openat2 (int *fd, char const *filename, } if (maxlinks <= 0) - return -ELOOP; + return -_GL_OPENAT_ESYMLINK; maxlinks--; /* A symlink and the symlink loop count is not exhausted. @@ -386,7 +386,7 @@ do_openat2 (int *fd, char const *filename, if (r < 0) return negative_errno (); if (st.f_type == S_MAGIC_PROC) - return -ELOOP; + return -_GL_OPENAT_ESYMLINK; } #endif diff --git a/tests/test-openat2.c b/tests/test-openat2.c index 3f9dc70039..12830a0bc9 100644 --- a/tests/test-openat2.c +++ b/tests/test-openat2.c @@ -333,15 +333,7 @@ do_test_flags (void) static bool is_nofollow_error (int err) { -#ifdef EFTYPE /* NetBSD openat+O_NOFOLLOW on symlink */ - if (err == EFTYPE) - return true; -#endif -#ifdef EMLINK /* FreeBSD openat+O_NOFOLLOW on symlink */ - if (err == EMLINK) - return true; -#endif - return err == ELOOP; + return err == _GL_OPENAT_ESYMLINK; } static void -- 2.51.0
