Hi Collin,

> The bug report got addressed today.

Nice! That was quick (probably because it was a kernel issue — on libc issues
they are much slower).

> I think we may have the ordering wrong
> in lib/dup3.c:
> 
>   if (newfd < 0 || newfd >= getdtablesize () || fcntl (oldfd, F_GETFD) == -1)
>     {
>       errno = EBADF;
>       return -1;
>     }
> 
>   if (newfd == oldfd)
>     {
>       errno = EINVAL;
>       return -1;
>     }
> 
> In the Linux kernel sources they are done in this order [5]:
> 
>     if ((flags & ~O_CLOEXEC) != 0)
>       return -EINVAL;
> 
>     if (unlikely(oldfd == newfd))
>       return -EINVAL;
> 
>     if (newfd >= rlimit(RLIMIT_NOFILE))
>        return -EBADF;
> 
> Unless glibc wraps the syscall in it's own functions where the order
> is changed. I'm not too sure how that stuff works but I couldn't seem
> to find it.

When several possible error conditions apply at the same time, the
implementations can pick the one they like, and the caller has no
guarantee regarding the errno value. So, in this case, Linux is right
but Gnulib is right as well.

Bruno




Reply via email to