Merge "Fix dup2 in the case where the two fds are equal."

This commit is contained in:
Elliott Hughes 2015-02-24 05:55:37 +00:00 committed by Gerrit Code Review
commit 2aef607b25
2 changed files with 30 additions and 0 deletions

View file

@ -26,8 +26,19 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include <fcntl.h>
#include <unistd.h> #include <unistd.h>
int dup2(int old_fd, int new_fd) { int dup2(int old_fd, int new_fd) {
// If old_fd is equal to new_fd and a valid file descriptor, dup2 returns
// old_fd without closing it. This is not true of dup3, so we have to
// handle this case ourselves.
if (old_fd == new_fd) {
if (fcntl(old_fd, F_GETFD) == -1) {
return -1;
}
return old_fd;
}
return dup3(old_fd, new_fd, 0); return dup3(old_fd, new_fd, 0);
} }

View file

@ -801,3 +801,22 @@ TEST(unistd, sysconf) {
VERIFY_SYSCONF_NOT_SUPPORT(_SC_XOPEN_UUCP); VERIFY_SYSCONF_NOT_SUPPORT(_SC_XOPEN_UUCP);
#endif // defined(__BIONIC__) #endif // defined(__BIONIC__)
} }
TEST(unistd, dup2_same) {
// POSIX says of dup2:
// If fildes2 is already a valid open file descriptor ...
// [and] fildes is equal to fildes2 ... dup2() shall return
// fildes2 without closing it.
// This isn't true of dup3(2), so we need to manually implement that.
// Equal and valid.
int fd = open("/proc/version", O_RDONLY);
ASSERT_TRUE(fd != -1);
ASSERT_EQ(fd, dup2(fd, fd));
ASSERT_EQ(0, close(fd)); // Check that dup2 didn't close fd.
// Equal, but invalid.
errno = 0;
ASSERT_EQ(-1, dup2(fd, fd));
ASSERT_EQ(EBADF, errno);
}