Hi Bruno,

On 5/17/24 2:10 PM, Bruno Haible wrote:
> On NetBSD 9.0 and 10.0, I always see the same tests fail:
> 
> FAIL: test-dup3
> ===============
> 
> ../../gltests/test-dup3.c:113: assertion 'dup3 (fd, fd, o_flags) == -1' failed
> FAIL test-dup3 (exit status: 134)

It looks like dup3 behaves differently on NetBSD. It is documented
correctly, but I am not sure the reasoning behind the change.

For NetBSD the return value [1]:

     These calls return the new file descriptor value.  In the case of dup2()
     and dup3() this is always the same as newfd.  If an error occurs, the
     value -1 is returned and errno is set to indicate what happened.

For GNU/Linux [2]:

    If oldfd equals newfd, then dup3() fails with the error
    EINVAL.

Currently dup3 is replaced unconditionally. I made this change in a
NetBSD virtual machine and the test program passes:

$ git diff .
diff --git a/lib/dup3.c b/lib/dup3.c
index a810d3be19..7674f042a4 100644
--- a/lib/dup3.c
+++ b/lib/dup3.c
@@ -34,6 +34,15 @@ dup3 (int oldfd, int newfd, int flags)
   /* Avoid a cygwin crasher. */
   setdtablesize (newfd + 1);
 # endif
+
+#ifdef __NetBSD__
+  if (newfd == oldfd)
+    {
+      errno = EINVAL;
+      return -1;
+    }
+#endif
+
   /* Try the system call first, if it exists.  (We may be running with a glibc
      that has the function but with an older kernel that lacks it.)  */
   {

Sort of messy but does the trick. I haven't applied it in case you
have any better ideas.

Collin

[1] https://man.netbsd.org/dup3.2
[2] https://man7.org/linux/man-pages/man2/dup3.2.html

Reply via email to