Chromium Code Reviews| Index: base/posix/unix_domain_socket_linux.cc |
| diff --git a/base/posix/unix_domain_socket_linux.cc b/base/posix/unix_domain_socket_linux.cc |
| index 436c337adb4f4e151666be2ac7d86d03458ae97a..8bfc8cea7fcf32e5910225e04a62350ccfeb4b82 100644 |
| --- a/base/posix/unix_domain_socket_linux.cc |
| +++ b/base/posix/unix_domain_socket_linux.cc |
| @@ -17,6 +17,12 @@ |
| const size_t UnixDomainSocket::kMaxFileDescriptors = 16; |
| // static |
| +bool UnixDomainSocket::EnableReceiveProcessId(int fd) { |
| + const int enable = 1; |
| + return setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &enable, sizeof(enable)) == 0; |
| +} |
| + |
| +// static |
| bool UnixDomainSocket::SendMsg(int fd, |
| const void* buf, |
| size_t length, |
| @@ -58,7 +64,16 @@ ssize_t UnixDomainSocket::RecvMsg(int fd, |
| void* buf, |
| size_t length, |
| std::vector<int>* fds) { |
| - return UnixDomainSocket::RecvMsgWithFlags(fd, buf, length, 0, fds); |
| + return UnixDomainSocket::RecvMsgWithPid(fd, buf, length, fds, NULL); |
| +} |
| + |
| +// static |
| +ssize_t UnixDomainSocket::RecvMsgWithPid(int fd, |
| + void* buf, |
| + size_t length, |
| + std::vector<int>* fds, |
| + base::ProcessId* pid) { |
| + return UnixDomainSocket::RecvMsgWithFlags(fd, buf, length, 0, fds, pid); |
| } |
| // static |
| @@ -66,7 +81,8 @@ ssize_t UnixDomainSocket::RecvMsgWithFlags(int fd, |
| void* buf, |
| size_t length, |
| int flags, |
| - std::vector<int>* fds) { |
| + std::vector<int>* fds, |
| + base::ProcessId* out_pid) { |
| fds->clear(); |
| struct msghdr msg = {}; |
| @@ -74,7 +90,8 @@ ssize_t UnixDomainSocket::RecvMsgWithFlags(int fd, |
| msg.msg_iov = &iov; |
| msg.msg_iovlen = 1; |
| - char control_buffer[CMSG_SPACE(sizeof(int) * kMaxFileDescriptors)]; |
| + char control_buffer[CMSG_SPACE(sizeof(int) * kMaxFileDescriptors) + |
| + CMSG_SPACE(sizeof(struct ucred))]; |
| msg.msg_control = control_buffer; |
| msg.msg_controllen = sizeof(control_buffer); |
| @@ -84,17 +101,24 @@ ssize_t UnixDomainSocket::RecvMsgWithFlags(int fd, |
| int* wire_fds = NULL; |
| unsigned wire_fds_len = 0; |
| + base::ProcessId pid = -1; |
| if (msg.msg_controllen > 0) { |
| struct cmsghdr* cmsg; |
| for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) { |
| + const unsigned payload_len = cmsg->cmsg_len - CMSG_LEN(0); |
|
jln (very slow on Chromium)
2014/04/24 18:32:58
Ohh my, this looks like it's ripe for rewrite (in
mdempsky
2014/04/24 19:00:34
ACK
|
| if (cmsg->cmsg_level == SOL_SOCKET && |
| cmsg->cmsg_type == SCM_RIGHTS) { |
| - const unsigned payload_len = cmsg->cmsg_len - CMSG_LEN(0); |
| DCHECK(payload_len % sizeof(int) == 0); |
| + DCHECK(wire_fds == NULL); |
| wire_fds = reinterpret_cast<int*>(CMSG_DATA(cmsg)); |
| wire_fds_len = payload_len / sizeof(int); |
| - break; |
| + } |
| + if (cmsg->cmsg_level == SOL_SOCKET && |
| + cmsg->cmsg_type == SCM_CREDENTIALS) { |
| + DCHECK(payload_len == sizeof(struct ucred)); |
| + DCHECK(pid == -1); |
| + pid = reinterpret_cast<struct ucred*>(CMSG_DATA(cmsg))->pid; |
| } |
| } |
| } |
| @@ -111,6 +135,11 @@ ssize_t UnixDomainSocket::RecvMsgWithFlags(int fd, |
| memcpy(vector_as_array(fds), wire_fds, sizeof(int) * wire_fds_len); |
| } |
| + if (out_pid) { |
| + DCHECK(pid != -1); |
| + *out_pid = pid; |
| + } |
| + |
| return r; |
| } |
| @@ -151,8 +180,8 @@ ssize_t UnixDomainSocket::SendRecvMsgWithFlags(int fd, |
| fd_vector.clear(); |
| // When porting to OSX keep in mind it doesn't support MSG_NOSIGNAL, so the |
| // sender might get a SIGPIPE. |
| - const ssize_t reply_len = RecvMsgWithFlags(fds[0], reply, max_reply_len, |
| - recvmsg_flags, &fd_vector); |
| + const ssize_t reply_len = RecvMsgWithFlags( |
| + fds[0], reply, max_reply_len, recvmsg_flags, &fd_vector, NULL); |
| close(fds[0]); |
| if (reply_len == -1) |
| return -1; |