Opened 6 hours ago

Closed 6 hours ago

Last modified 6 hours ago

#19476 closed bug (fixed)

dup3 mistakenly succeeds when given equal file descriptors.

Reported by: collinfunk Owned by: nobody
Priority: normal Milestone: R1/beta6
Component: System/POSIX Version: R1/beta5
Keywords: Cc:
Blocked By: Blocking:
Platform: All

Description

POSIX 2024 states the following [1]:

The dup3() function shall fail if:

[EINVAL]

The fildes and fildes2 arguments are equal.

On Haiku this is not the case and the function returns 0. This was caught by Gnulib's tests. I have written a small test program with only the relevant check:

#define _GNU_SOURCE 1
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>

int
main (void)
{
  const char *file = "test-dup3.tmp";
  int fd = open (file, O_CREAT | O_TRUNC | O_RDWR, 0600);
  int result = dup3 (fd, fd, 0);
  int saved_errno = errno;

  /* Check that the file could be created.  */
  if (fd == -1)
    abort ();
  /* Cleanup the file and restore errno.  */
  (void) unlink (file);
  errno = saved_errno;
  /* Expect dup3 to fail with errno == EINVAL.  */
  if (result != -1)
    {
      (void) close (result);
      fprintf (stderr, "dup3 (fd, fd, 0) should fail with EINVAL\n");
      abort ();
    }
  printf ("%s\n", strerror (errno));
  return 0;
}

Here is the result on GNU/Linux: $ gcc main.c $ ./a.out Invalid argument $ echo $? 0

On my Haiku VM: $ uname -a Haiku shredder 1 hrev58727 Mar 12 2025 06:02:13 x86_64 x86_64 Haiku $ gcc main.c $ ./a.out dup3 (fd, fd, 0) should fail with EINVAL Abort

[1] https://pubs.opengroup.org/onlinepubs/9799919799/functions/dup3.html

Change History (4)

comment:1 by waddlesplash, 6 hours ago

Milestone: UnscheduledR1/beta6
Resolution: fixed
Status: newclosed

Fixed in hrev58733. Thanks for reporting!

comment:2 by waddlesplash, 6 hours ago

(FWIW, dup3() only exists on the Haiku nightlies, i.e. the next in-development release; R1/beta5 did not support it at all. I don't know how much sense it makes to add a GNUlib workaround for this.)

comment:3 by collinfunk, 6 hours ago

Thanks for the quick fix.

Gnulib will implement dup3 on any reasonable platform.

In the case of systems without dup3, it will just use dup2 and fcntl. Not perfect since it is a race condition, but will allow programs to compile and (mostly) work.

comment:4 by waddlesplash, 6 hours ago

Sure, implementing dup3 as dup2+fcntl makes sense, I meant the workaround you've just committed to GNUlib to check for this case before calling the real dup3 on Haiku.

Note: See TracTickets for help on using tickets.