| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ipc/ipc_channel_posix.h" | 5 #include "ipc/ipc_channel_posix.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <fcntl.h> | 8 #include <fcntl.h> |
| 9 #include <stddef.h> | 9 #include <stddef.h> |
| 10 #include <sys/types.h> | 10 #include <sys/types.h> |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 109 if (HANDLE_EINTR(close(i->second)) < 0) | 109 if (HANDLE_EINTR(close(i->second)) < 0) |
| 110 PLOG(ERROR) << "close " << channel_id; | 110 PLOG(ERROR) << "close " << channel_id; |
| 111 map_.erase(i); | 111 map_.erase(i); |
| 112 } | 112 } |
| 113 } | 113 } |
| 114 | 114 |
| 115 // Insert a mapping from @channel_id to @fd. It's a fatal error to insert a | 115 // Insert a mapping from @channel_id to @fd. It's a fatal error to insert a |
| 116 // mapping if one already exists for the given channel_id | 116 // mapping if one already exists for the given channel_id |
| 117 void Insert(const std::string& channel_id, int fd) { | 117 void Insert(const std::string& channel_id, int fd) { |
| 118 base::AutoLock locked(lock_); | 118 base::AutoLock locked(lock_); |
| 119 DCHECK(fd != -1); | 119 DCHECK_NE(-1, fd); |
| 120 | 120 |
| 121 ChannelToFDMap::const_iterator i = map_.find(channel_id); | 121 ChannelToFDMap::const_iterator i = map_.find(channel_id); |
| 122 CHECK(i == map_.end()) << "Creating second IPC server (fd " << fd << ") " | 122 CHECK(i == map_.end()) << "Creating second IPC server (fd " << fd << ") " |
| 123 << "for '" << channel_id << "' while first " | 123 << "for '" << channel_id << "' while first " |
| 124 << "(fd " << i->second << ") still exists"; | 124 << "(fd " << i->second << ") still exists"; |
| 125 map_[channel_id] = fd; | 125 map_[channel_id] = fd; |
| 126 } | 126 } |
| 127 | 127 |
| 128 private: | 128 private: |
| 129 base::Lock lock_; | 129 base::Lock lock_; |
| (...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 549 // printf("Bug found!\n"); | 549 // printf("Bug found!\n"); |
| 550 // } | 550 // } |
| 551 if (msg.msg_controllen > 0) { | 551 if (msg.msg_controllen > 0) { |
| 552 // On OSX, CMSG_FIRSTHDR doesn't handle the case where controllen is 0 | 552 // On OSX, CMSG_FIRSTHDR doesn't handle the case where controllen is 0 |
| 553 // and will return a pointer into nowhere. | 553 // and will return a pointer into nowhere. |
| 554 for (struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg); cmsg; | 554 for (struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg); cmsg; |
| 555 cmsg = CMSG_NXTHDR(&msg, cmsg)) { | 555 cmsg = CMSG_NXTHDR(&msg, cmsg)) { |
| 556 if (cmsg->cmsg_level == SOL_SOCKET && | 556 if (cmsg->cmsg_level == SOL_SOCKET && |
| 557 cmsg->cmsg_type == SCM_RIGHTS) { | 557 cmsg->cmsg_type == SCM_RIGHTS) { |
| 558 const unsigned payload_len = cmsg->cmsg_len - CMSG_LEN(0); | 558 const unsigned payload_len = cmsg->cmsg_len - CMSG_LEN(0); |
| 559 DCHECK(payload_len % sizeof(int) == 0); | 559 DCHECK_EQ(0U, payload_len % sizeof(int)); |
| 560 wire_fds = reinterpret_cast<int*>(CMSG_DATA(cmsg)); | 560 wire_fds = reinterpret_cast<int*>(CMSG_DATA(cmsg)); |
| 561 num_wire_fds = payload_len / 4; | 561 num_wire_fds = payload_len / 4; |
| 562 | 562 |
| 563 if (msg.msg_flags & MSG_CTRUNC) { | 563 if (msg.msg_flags & MSG_CTRUNC) { |
| 564 LOG(ERROR) << "SCM_RIGHTS message was truncated" | 564 LOG(ERROR) << "SCM_RIGHTS message was truncated" |
| 565 << " cmsg_len:" << cmsg->cmsg_len | 565 << " cmsg_len:" << cmsg->cmsg_len |
| 566 << " fd:" << pipe_; | 566 << " fd:" << pipe_; |
| 567 for (unsigned i = 0; i < num_wire_fds; ++i) | 567 for (unsigned i = 0; i < num_wire_fds; ++i) |
| 568 if (HANDLE_EINTR(close(wire_fds[i])) < 0) | 568 if (HANDLE_EINTR(close(wire_fds[i])) < 0) |
| 569 PLOG(ERROR) << "close " << i; | 569 PLOG(ERROR) << "close " << i; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 629 struct iovec fd_pipe_iov = { &dummy, 1 }; | 629 struct iovec fd_pipe_iov = { &dummy, 1 }; |
| 630 msg.msg_iov = &fd_pipe_iov; | 630 msg.msg_iov = &fd_pipe_iov; |
| 631 msg.msg_controllen = sizeof(input_cmsg_buf_); | 631 msg.msg_controllen = sizeof(input_cmsg_buf_); |
| 632 ssize_t n = HANDLE_EINTR(recvmsg(fd_pipe_, &msg, MSG_DONTWAIT)); | 632 ssize_t n = HANDLE_EINTR(recvmsg(fd_pipe_, &msg, MSG_DONTWAIT)); |
| 633 if (n == 1 && msg.msg_controllen > 0) { | 633 if (n == 1 && msg.msg_controllen > 0) { |
| 634 for (struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg); cmsg; | 634 for (struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg); cmsg; |
| 635 cmsg = CMSG_NXTHDR(&msg, cmsg)) { | 635 cmsg = CMSG_NXTHDR(&msg, cmsg)) { |
| 636 if (cmsg->cmsg_level == SOL_SOCKET && | 636 if (cmsg->cmsg_level == SOL_SOCKET && |
| 637 cmsg->cmsg_type == SCM_RIGHTS) { | 637 cmsg->cmsg_type == SCM_RIGHTS) { |
| 638 const unsigned payload_len = cmsg->cmsg_len - CMSG_LEN(0); | 638 const unsigned payload_len = cmsg->cmsg_len - CMSG_LEN(0); |
| 639 DCHECK(payload_len % sizeof(int) == 0); | 639 DCHECK_EQ(0U, payload_len % sizeof(int)); |
| 640 wire_fds = reinterpret_cast<int*>(CMSG_DATA(cmsg)); | 640 wire_fds = reinterpret_cast<int*>(CMSG_DATA(cmsg)); |
| 641 num_wire_fds = payload_len / 4; | 641 num_wire_fds = payload_len / 4; |
| 642 | 642 |
| 643 if (msg.msg_flags & MSG_CTRUNC) { | 643 if (msg.msg_flags & MSG_CTRUNC) { |
| 644 LOG(ERROR) << "SCM_RIGHTS message was truncated" | 644 LOG(ERROR) << "SCM_RIGHTS message was truncated" |
| 645 << " cmsg_len:" << cmsg->cmsg_len | 645 << " cmsg_len:" << cmsg->cmsg_len |
| 646 << " fd:" << pipe_; | 646 << " fd:" << pipe_; |
| 647 for (unsigned i = 0; i < num_wire_fds; ++i) | 647 for (unsigned i = 0; i < num_wire_fds; ++i) |
| 648 if (HANDLE_EINTR(close(wire_fds[i])) < 0) | 648 if (HANDLE_EINTR(close(wire_fds[i])) < 0) |
| 649 PLOG(ERROR) << "close " << i; | 649 PLOG(ERROR) << "close " << i; |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 762 | 762 |
| 763 if (pipe_ == -1) | 763 if (pipe_ == -1) |
| 764 return false; | 764 return false; |
| 765 | 765 |
| 766 // Write out all the messages we can till the write blocks or there are no | 766 // Write out all the messages we can till the write blocks or there are no |
| 767 // more outgoing messages. | 767 // more outgoing messages. |
| 768 while (!output_queue_.empty()) { | 768 while (!output_queue_.empty()) { |
| 769 Message* msg = output_queue_.front(); | 769 Message* msg = output_queue_.front(); |
| 770 | 770 |
| 771 size_t amt_to_write = msg->size() - message_send_bytes_written_; | 771 size_t amt_to_write = msg->size() - message_send_bytes_written_; |
| 772 DCHECK(amt_to_write != 0); | 772 DCHECK_NE(0U, amt_to_write); |
| 773 const char* out_bytes = reinterpret_cast<const char*>(msg->data()) + | 773 const char* out_bytes = reinterpret_cast<const char*>(msg->data()) + |
| 774 message_send_bytes_written_; | 774 message_send_bytes_written_; |
| 775 | 775 |
| 776 struct msghdr msgh = {0}; | 776 struct msghdr msgh = {0}; |
| 777 struct iovec iov = {const_cast<char*>(out_bytes), amt_to_write}; | 777 struct iovec iov = {const_cast<char*>(out_bytes), amt_to_write}; |
| 778 msgh.msg_iov = &iov; | 778 msgh.msg_iov = &iov; |
| 779 msgh.msg_iovlen = 1; | 779 msgh.msg_iovlen = 1; |
| 780 char buf[CMSG_SPACE( | 780 char buf[CMSG_SPACE( |
| 781 sizeof(int[FileDescriptorSet::MAX_DESCRIPTORS_PER_MESSAGE]))]; | 781 sizeof(int[FileDescriptorSet::MAX_DESCRIPTORS_PER_MESSAGE]))]; |
| 782 | 782 |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1050 // only send our handshake message after we've processed the client's. | 1050 // only send our handshake message after we've processed the client's. |
| 1051 // This gives us a chance to kill the client if the incoming handshake | 1051 // This gives us a chance to kill the client if the incoming handshake |
| 1052 // is invalid. | 1052 // is invalid. |
| 1053 if (send_server_hello_msg) { | 1053 if (send_server_hello_msg) { |
| 1054 ProcessOutgoingMessages(); | 1054 ProcessOutgoingMessages(); |
| 1055 } | 1055 } |
| 1056 } | 1056 } |
| 1057 | 1057 |
| 1058 // Called by libevent when we can write to the pipe without blocking. | 1058 // Called by libevent when we can write to the pipe without blocking. |
| 1059 void Channel::ChannelImpl::OnFileCanWriteWithoutBlocking(int fd) { | 1059 void Channel::ChannelImpl::OnFileCanWriteWithoutBlocking(int fd) { |
| 1060 DCHECK(fd == pipe_); | 1060 DCHECK_EQ(pipe_, fd); |
| 1061 is_blocked_on_write_ = false; | 1061 is_blocked_on_write_ = false; |
| 1062 if (!ProcessOutgoingMessages()) { | 1062 if (!ProcessOutgoingMessages()) { |
| 1063 ClosePipeOnError(); | 1063 ClosePipeOnError(); |
| 1064 } | 1064 } |
| 1065 } | 1065 } |
| 1066 | 1066 |
| 1067 bool Channel::ChannelImpl::AcceptConnection() { | 1067 bool Channel::ChannelImpl::AcceptConnection() { |
| 1068 MessageLoopForIO::current()->WatchFileDescriptor(pipe_, | 1068 MessageLoopForIO::current()->WatchFileDescriptor(pipe_, |
| 1069 true, | 1069 true, |
| 1070 MessageLoopForIO::WATCH_READ, | 1070 MessageLoopForIO::WATCH_READ, |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1192 | 1192 |
| 1193 bool Channel::GetClientEuid(uid_t* client_euid) const { | 1193 bool Channel::GetClientEuid(uid_t* client_euid) const { |
| 1194 return channel_impl_->GetClientEuid(client_euid); | 1194 return channel_impl_->GetClientEuid(client_euid); |
| 1195 } | 1195 } |
| 1196 | 1196 |
| 1197 void Channel::ResetToAcceptingConnectionState() { | 1197 void Channel::ResetToAcceptingConnectionState() { |
| 1198 channel_impl_->ResetToAcceptingConnectionState(); | 1198 channel_impl_->ResetToAcceptingConnectionState(); |
| 1199 } | 1199 } |
| 1200 | 1200 |
| 1201 } // namespace IPC | 1201 } // namespace IPC |
| OLD | NEW |