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; |