| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/socket.h> | 10 #include <sys/socket.h> |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 182 | 182 |
| 183 ChannelPosix::ChannelPosix(const IPC::ChannelHandle& channel_handle, | 183 ChannelPosix::ChannelPosix(const IPC::ChannelHandle& channel_handle, |
| 184 Mode mode, Listener* listener) | 184 Mode mode, Listener* listener) |
| 185 : ChannelReader(listener), | 185 : ChannelReader(listener), |
| 186 mode_(mode), | 186 mode_(mode), |
| 187 peer_pid_(base::kNullProcessId), | 187 peer_pid_(base::kNullProcessId), |
| 188 is_blocked_on_write_(false), | 188 is_blocked_on_write_(false), |
| 189 waiting_connect_(true), | 189 waiting_connect_(true), |
| 190 message_send_bytes_written_(0), | 190 message_send_bytes_written_(0), |
| 191 pipe_name_(channel_handle.name), | 191 pipe_name_(channel_handle.name), |
| 192 in_dtor_(false), |
| 192 must_unlink_(false) { | 193 must_unlink_(false) { |
| 193 memset(input_cmsg_buf_, 0, sizeof(input_cmsg_buf_)); | 194 memset(input_cmsg_buf_, 0, sizeof(input_cmsg_buf_)); |
| 194 if (!CreatePipe(channel_handle)) { | 195 if (!CreatePipe(channel_handle)) { |
| 195 // The pipe may have been closed already. | 196 // The pipe may have been closed already. |
| 196 const char *modestr = (mode_ & MODE_SERVER_FLAG) ? "server" : "client"; | 197 const char *modestr = (mode_ & MODE_SERVER_FLAG) ? "server" : "client"; |
| 197 LOG(WARNING) << "Unable to create pipe named \"" << channel_handle.name | 198 LOG(WARNING) << "Unable to create pipe named \"" << channel_handle.name |
| 198 << "\" in " << modestr << " mode"; | 199 << "\" in " << modestr << " mode"; |
| 199 } | 200 } |
| 200 } | 201 } |
| 201 | 202 |
| 202 ChannelPosix::~ChannelPosix() { | 203 ChannelPosix::~ChannelPosix() { |
| 204 in_dtor_ = true; |
| 203 Close(); | 205 Close(); |
| 204 } | 206 } |
| 205 | 207 |
| 206 bool SocketPair(int* fd1, int* fd2) { | 208 bool SocketPair(int* fd1, int* fd2) { |
| 207 int pipe_fds[2]; | 209 int pipe_fds[2]; |
| 208 if (socketpair(AF_UNIX, SOCK_STREAM, 0, pipe_fds) != 0) { | 210 if (socketpair(AF_UNIX, SOCK_STREAM, 0, pipe_fds) != 0) { |
| 209 PLOG(ERROR) << "socketpair()"; | 211 PLOG(ERROR) << "socketpair()"; |
| 210 return false; | 212 return false; |
| 211 } | 213 } |
| 212 | 214 |
| (...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 604 bool ChannelPosix::GetPeerEuid(uid_t* peer_euid) const { | 606 bool ChannelPosix::GetPeerEuid(uid_t* peer_euid) const { |
| 605 DCHECK(!(mode_ & MODE_SERVER) || HasAcceptedConnection()); | 607 DCHECK(!(mode_ & MODE_SERVER) || HasAcceptedConnection()); |
| 606 return IPC::GetPeerEuid(pipe_.get(), peer_euid); | 608 return IPC::GetPeerEuid(pipe_.get(), peer_euid); |
| 607 } | 609 } |
| 608 #endif | 610 #endif |
| 609 | 611 |
| 610 void ChannelPosix::ResetToAcceptingConnectionState() { | 612 void ChannelPosix::ResetToAcceptingConnectionState() { |
| 611 // Unregister libevent for the unix domain socket and close it. | 613 // Unregister libevent for the unix domain socket and close it. |
| 612 read_watcher_.StopWatchingFileDescriptor(); | 614 read_watcher_.StopWatchingFileDescriptor(); |
| 613 write_watcher_.StopWatchingFileDescriptor(); | 615 write_watcher_.StopWatchingFileDescriptor(); |
| 614 pipe_.reset(); | 616 ResetSafely(&pipe_); |
| 615 #if defined(IPC_USES_READWRITE) | 617 #if defined(IPC_USES_READWRITE) |
| 616 fd_pipe_.reset(); | 618 fd_pipe_.reset(); |
| 617 remote_fd_pipe_.reset(); | 619 remote_fd_pipe_.reset(); |
| 618 #endif // IPC_USES_READWRITE | 620 #endif // IPC_USES_READWRITE |
| 619 | 621 |
| 620 while (!output_queue_.empty()) { | 622 while (!output_queue_.empty()) { |
| 621 Message* m = output_queue_.front(); | 623 Message* m = output_queue_.front(); |
| 622 output_queue_.pop(); | 624 output_queue_.pop(); |
| 623 delete m; | 625 delete m; |
| 624 } | 626 } |
| (...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1071 } | 1073 } |
| 1072 | 1074 |
| 1073 base::ProcessId ChannelPosix::GetPeerPID() const { | 1075 base::ProcessId ChannelPosix::GetPeerPID() const { |
| 1074 return peer_pid_; | 1076 return peer_pid_; |
| 1075 } | 1077 } |
| 1076 | 1078 |
| 1077 base::ProcessId ChannelPosix::GetSelfPID() const { | 1079 base::ProcessId ChannelPosix::GetSelfPID() const { |
| 1078 return GetHelloMessageProcId(); | 1080 return GetHelloMessageProcId(); |
| 1079 } | 1081 } |
| 1080 | 1082 |
| 1083 void ChannelPosix::ResetSafely(base::ScopedFD* fd) { |
| 1084 if (!in_dtor_) { |
| 1085 fd->reset(); |
| 1086 return; |
| 1087 } |
| 1088 |
| 1089 // crbug.com/449233 |
| 1090 // The CL [1] tightened the error check for closing FDs, but it turned |
| 1091 // out that there are existing cases that hit the newly added check. |
| 1092 // ResetSafely() is the workaround for that crash, turning it from |
| 1093 // from PCHECK() to DPCHECK() so that it doesn't crash in production. |
| 1094 // [1] https://crrev.com/ce44fef5fd60dd2be5c587d4b084bdcd36adcee4 |
| 1095 int fd_to_close = fd->release(); |
| 1096 if (-1 != fd_to_close) { |
| 1097 int rv = IGNORE_EINTR(close(fd_to_close)); |
| 1098 DPCHECK(0 == rv); |
| 1099 } |
| 1100 } |
| 1101 |
| 1081 //------------------------------------------------------------------------------ | 1102 //------------------------------------------------------------------------------ |
| 1082 // Channel's methods | 1103 // Channel's methods |
| 1083 | 1104 |
| 1084 // static | 1105 // static |
| 1085 scoped_ptr<Channel> Channel::Create( | 1106 scoped_ptr<Channel> Channel::Create( |
| 1086 const IPC::ChannelHandle &channel_handle, Mode mode, Listener* listener) { | 1107 const IPC::ChannelHandle &channel_handle, Mode mode, Listener* listener) { |
| 1087 return make_scoped_ptr(new ChannelPosix(channel_handle, mode, listener)); | 1108 return make_scoped_ptr(new ChannelPosix(channel_handle, mode, listener)); |
| 1088 } | 1109 } |
| 1089 | 1110 |
| 1090 // static | 1111 // static |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1106 } | 1127 } |
| 1107 | 1128 |
| 1108 #if defined(OS_LINUX) | 1129 #if defined(OS_LINUX) |
| 1109 // static | 1130 // static |
| 1110 void Channel::SetGlobalPid(int pid) { | 1131 void Channel::SetGlobalPid(int pid) { |
| 1111 ChannelPosix::SetGlobalPid(pid); | 1132 ChannelPosix::SetGlobalPid(pid); |
| 1112 } | 1133 } |
| 1113 #endif // OS_LINUX | 1134 #endif // OS_LINUX |
| 1114 | 1135 |
| 1115 } // namespace IPC | 1136 } // namespace IPC |
| OLD | NEW |