Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can dup2 really return EINTR?

In the spec and two implementations:

  • According to POSIX, dup2() may return EINTR.
  • The linux man pages list it as permitted.
  • The FreeBSD man pages indicate it's not ever returned. Is this a bug - since its close implementation can EINTR (at least for TCP linger if nothing else).

In reality, can Linux return EINTR for dup2()? Presumably if so, it would be because close() decided to wait and a signal arrived (TCP linger or dodgy file system drivers that try to sync when closing).

In reality, does FreeBSD guarantee not to return EINTR for dup2()? In that case, it must be that it doesn't bother waiting for any outstanding operations on the old fd and simply unlinks the fd.

What does POSIX dup2() mean when it refers to "closing" (not in italics), rather than referencing the actual close() function - are we to understand it's just talking about "closing" it in an informal way (unlinking the file descriptor), or is it attempting to say that the effect should be as if the close() function were first called and then dup2() were called atomically.

If fildes2 is already a valid open file descriptor, it shall be closed first, unless fildes is equal to fildes2 in which case dup2() shall return fildes2 without closing it.

If dup2() does have to close, wait, then atomically dup, it's going to be a nightmare for implementors! It's much worse than the EINTR with close() fiasco. Cowardly POSIX doesn't even say if the dup took place in the case of EINTR...

like image 658
Nicholas Wilson Avatar asked Nov 12 '22 07:11

Nicholas Wilson


1 Answers

Here's the relevant information from the C/POSIX library documentation with respect to the standard Linux implementation:

 If OLD and NEW are different numbers, and OLD is a valid
 descriptor number, then `dup2' is equivalent to:

      close (NEW);
      fcntl (OLD, F_DUPFD, NEW)

 However, `dup2' does this atomically; there is no instant in the
 middle of calling `dup2' at which NEW is closed and not yet a
 duplicate of OLD.

It lists the possible error values returned by dup and dup2 as EBADF, EINVAL, and EMFILE, and no others. The documentation states that all functions that can return EINTR are listed as such, which indicates that these don't. Note that these are implemented via fcntl, not a call to close.

like image 106
teppic Avatar answered Nov 25 '22 16:11

teppic