OLD | NEW |
1 // Copyright (c) 2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2008 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 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
234 if (HANDLE_EINTR(connect(fd, reinterpret_cast<sockaddr*>(&server_unix_addr), | 234 if (HANDLE_EINTR(connect(fd, reinterpret_cast<sockaddr*>(&server_unix_addr), |
235 server_unix_addr_len)) != 0) { | 235 server_unix_addr_len)) != 0) { |
236 HANDLE_EINTR(close(fd)); | 236 HANDLE_EINTR(close(fd)); |
237 return false; | 237 return false; |
238 } | 238 } |
239 | 239 |
240 *client_socket = fd; | 240 *client_socket = fd; |
241 return true; | 241 return true; |
242 } | 242 } |
243 | 243 |
| 244 bool SocketWriteErrorIsRecoverable() { |
| 245 #if defined(OS_MACOSX) |
| 246 // On OS X if sendmsg() is trying to send fds between processes and there |
| 247 // isn't enough room in the output buffer to send the fd structure over |
| 248 // atomically then EMSGSIZE is returned. |
| 249 return errno == EAGAIN || errno == EMSGSIZE; |
| 250 #else |
| 251 return errno == EAGAIN; |
| 252 #endif |
| 253 } |
| 254 |
244 } // namespace | 255 } // namespace |
245 //------------------------------------------------------------------------------ | 256 //------------------------------------------------------------------------------ |
246 | 257 |
247 Channel::ChannelImpl::ChannelImpl(const std::string& channel_id, Mode mode, | 258 Channel::ChannelImpl::ChannelImpl(const std::string& channel_id, Mode mode, |
248 Listener* listener) | 259 Listener* listener) |
249 : mode_(mode), | 260 : mode_(mode), |
250 is_blocked_on_write_(false), | 261 is_blocked_on_write_(false), |
251 message_send_bytes_written_(0), | 262 message_send_bytes_written_(0), |
252 uses_fifo_(CommandLine::ForCurrentProcess()->HasSwitch( | 263 uses_fifo_(CommandLine::ForCurrentProcess()->HasSwitch( |
253 switches::kIPCUseFIFO)), | 264 switches::kIPCUseFIFO)), |
(...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
808 bytes_written = HANDLE_EINTR(write(pipe_, out_bytes, amt_to_write)); | 819 bytes_written = HANDLE_EINTR(write(pipe_, out_bytes, amt_to_write)); |
809 } else | 820 } else |
810 #endif | 821 #endif |
811 { | 822 { |
812 bytes_written = HANDLE_EINTR(sendmsg(pipe_, &msgh, MSG_DONTWAIT)); | 823 bytes_written = HANDLE_EINTR(sendmsg(pipe_, &msgh, MSG_DONTWAIT)); |
813 } | 824 } |
814 } | 825 } |
815 if (bytes_written > 0) | 826 if (bytes_written > 0) |
816 msg->file_descriptor_set()->CommitAll(); | 827 msg->file_descriptor_set()->CommitAll(); |
817 | 828 |
818 if (bytes_written < 0 && errno != EAGAIN) { | 829 if (bytes_written < 0 && !SocketWriteErrorIsRecoverable()) { |
819 #if defined(OS_MACOSX) | 830 #if defined(OS_MACOSX) |
820 // On OSX writing to a pipe with no listener returns EPERM. | 831 // On OSX writing to a pipe with no listener returns EPERM. |
821 if (errno == EPERM) { | 832 if (errno == EPERM) { |
822 Close(); | 833 Close(); |
823 return false; | 834 return false; |
824 } | 835 } |
825 #endif // OS_MACOSX | 836 #endif // OS_MACOSX |
826 if (errno == EPIPE) { | 837 if (errno == EPIPE) { |
827 Close(); | 838 Close(); |
828 return false; | 839 return false; |
829 } | 840 } |
830 PLOG(ERROR) << "pipe error on " | 841 PLOG(ERROR) << "pipe error on " |
831 << fd_written | 842 << fd_written |
832 << " Currently writing message of size:" | 843 << " Currently writing message of size:" |
833 << msg->size() | 844 << msg->size(); |
834 << " msgh.msg_iovlen:" | |
835 << msgh.msg_iovlen | |
836 << " amt_to_write: " | |
837 << amt_to_write | |
838 << " num FDs to send:" | |
839 << msg->file_descriptor_set()->size(); | |
840 return false; | 845 return false; |
841 } | 846 } |
842 | 847 |
843 if (static_cast<size_t>(bytes_written) != amt_to_write) { | 848 if (static_cast<size_t>(bytes_written) != amt_to_write) { |
844 if (bytes_written > 0) { | 849 if (bytes_written > 0) { |
845 // If write() fails with EAGAIN then bytes_written will be -1. | 850 // If write() fails with EAGAIN then bytes_written will be -1. |
846 message_send_bytes_written_ += bytes_written; | 851 message_send_bytes_written_ += bytes_written; |
847 } | 852 } |
848 | 853 |
849 // Tell libevent to call us back once things are unblocked. | 854 // Tell libevent to call us back once things are unblocked. |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1030 | 1035 |
1031 bool Channel::Send(Message* message) { | 1036 bool Channel::Send(Message* message) { |
1032 return channel_impl_->Send(message); | 1037 return channel_impl_->Send(message); |
1033 } | 1038 } |
1034 | 1039 |
1035 int Channel::GetClientFileDescriptor() const { | 1040 int Channel::GetClientFileDescriptor() const { |
1036 return channel_impl_->GetClientFileDescriptor(); | 1041 return channel_impl_->GetClientFileDescriptor(); |
1037 } | 1042 } |
1038 | 1043 |
1039 } // namespace IPC | 1044 } // namespace IPC |
OLD | NEW |