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