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 |