On Thu, Apr 26, 2012 at 06:56:45PM +0200, Bernhard Reutner-Fischer wrote: > On 26 April 2012 18:47, Rich Felker <[email protected]> wrote: > > On Thu, Apr 26, 2012 at 11:00:39AM -0400, Rich Felker wrote: > >> On Thu, Apr 26, 2012 at 10:18:11AM -0400, Mark Salter wrote: > >> > +#ifdef __NR_dup2 > >> > _syscall2(int, dup2, int, oldfd, int, newfd) > >> > +#elif defined __NR_dup3 > >> > +#include <fcntl.h> > >> > + > >> > +int > >> > +dup2 (int fd, int fd2) > >> > +{ > >> > + /* For the degenerate case, check if the fd is valid (by trying to > >> > + get the file status flags) and return it, or else return EBADF. > >> > */ > >> > + if (fd == fd2) > >> > + return __libc_fcntl(fd, F_GETFL, 0) < 0 ? -1 : fd; > >> > >> Is there a reason this special case is necessary? Not questioning it, > >> I just want to know. > > > > OK, I'll answer my own question: it seems to be a workaround for a > > kernel bug on 64-bit Linux: > > > > http://old.nabble.com/-PATCH--dup2:-Fix-return-value-with-oldfd-%3D%3D-newfd-and-invalid-fd-td23488867.html > > Which, from the looks, was fixed in > 6c5d0512a091480c9f981162227fdb1c9d70e555 so 2.6.27 and later do not > need this in libc.
Personally, if I were to put this workaround in musl (my libc), I would not add the extra code to call fcntl but instead do: return __syscall_ret((int)__syscall(SYS_dup2, fd1, fd2)); i.e. simply cast to (int) to sign-extend after the raw syscall return value, but before passing it to my wrapper function that checks if it's an errno value and sets errno. I don't know what the equivalent code would be in uClibc, but it's probably a lot smaller and simpler than adding the extra case to call fcntl. Only problem is it might be too messy to bypass and re-call the errno-setting code; my syscall architecture makes it easy but uClibc's might not. Rich _______________________________________________ uClibc mailing list [email protected] http://lists.busybox.net/mailman/listinfo/uclibc
