Skip to content
This repository was archived by the owner on Jun 9, 2020. It is now read-only.

Commit aa68538

Browse files
committed
Fix socketpair() to work correctly
socketpair() did not register the returned file descripters internally, causing the subsequent read() to fail.
1 parent 506d5bd commit aa68538

1 file changed

Lines changed: 28 additions & 6 deletions

File tree

src/net/net.c

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -620,10 +620,32 @@ DEFINE_SYSCALL(getpeername, int, sockfd, gaddr_t, addr_ptr, gaddr_t, addrlen_ptr
620620
DEFINE_SYSCALL(socketpair, int, family, int, type, int, protocol, gaddr_t, usockvec_ptr)
621621
{
622622
int fds[2];
623-
int r = syswrap(socketpair(linux_to_darwin_sa_family(family), type, protocol, fds));
624-
if (r < 0)
625-
return r;
626-
if (copy_to_user(usockvec_ptr, fds, sizeof fds))
627-
return -LINUX_EFAULT;
628-
return r;
623+
pthread_rwlock_wrlock(&proc.fileinfo.fdtable_lock);
624+
int ret = syswrap(socketpair(linux_to_darwin_sa_family(family), type, protocol, fds));
625+
if (ret < 0)
626+
goto err;
627+
int e = register_fd(fds[0], type & LINUX_SOCK_CLOEXEC);
628+
if (e < 0) {
629+
close(fds[0]);
630+
close(fds[1]);
631+
ret = e;
632+
goto err;
633+
}
634+
e = register_fd(fds[1], type & LINUX_SOCK_CLOEXEC);
635+
if (e < 0) {
636+
user_close(fds[0]);
637+
close(fds[1]);
638+
ret = e;
639+
goto err;
640+
}
641+
if (copy_to_user(usockvec_ptr, fds, sizeof fds)) {
642+
user_close(fds[0]);
643+
user_close(fds[1]);
644+
ret = -LINUX_EFAULT;
645+
goto err;
646+
}
647+
648+
err:
649+
pthread_rwlock_unlock(&proc.fileinfo.fdtable_lock);
650+
return ret;
629651
}

0 commit comments

Comments
 (0)