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), | |
193 must_unlink_(false) { | 192 must_unlink_(false) { |
194 memset(input_cmsg_buf_, 0, sizeof(input_cmsg_buf_)); | 193 memset(input_cmsg_buf_, 0, sizeof(input_cmsg_buf_)); |
195 if (!CreatePipe(channel_handle)) { | 194 if (!CreatePipe(channel_handle)) { |
196 // The pipe may have been closed already. | 195 // The pipe may have been closed already. |
197 const char *modestr = (mode_ & MODE_SERVER_FLAG) ? "server" : "client"; | 196 const char *modestr = (mode_ & MODE_SERVER_FLAG) ? "server" : "client"; |
198 LOG(WARNING) << "Unable to create pipe named \"" << channel_handle.name | 197 LOG(WARNING) << "Unable to create pipe named \"" << channel_handle.name |
199 << "\" in " << modestr << " mode"; | 198 << "\" in " << modestr << " mode"; |
200 } | 199 } |
201 } | 200 } |
202 | 201 |
203 ChannelPosix::~ChannelPosix() { | 202 ChannelPosix::~ChannelPosix() { |
204 in_dtor_ = true; | |
205 Close(); | 203 Close(); |
206 } | 204 } |
207 | 205 |
208 bool SocketPair(int* fd1, int* fd2) { | 206 bool SocketPair(int* fd1, int* fd2) { |
209 int pipe_fds[2]; | 207 int pipe_fds[2]; |
210 if (socketpair(AF_UNIX, SOCK_STREAM, 0, pipe_fds) != 0) { | 208 if (socketpair(AF_UNIX, SOCK_STREAM, 0, pipe_fds) != 0) { |
211 PLOG(ERROR) << "socketpair()"; | 209 PLOG(ERROR) << "socketpair()"; |
212 return false; | 210 return false; |
213 } | 211 } |
214 | 212 |
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
606 bool ChannelPosix::GetPeerEuid(uid_t* peer_euid) const { | 604 bool ChannelPosix::GetPeerEuid(uid_t* peer_euid) const { |
607 DCHECK(!(mode_ & MODE_SERVER) || HasAcceptedConnection()); | 605 DCHECK(!(mode_ & MODE_SERVER) || HasAcceptedConnection()); |
608 return IPC::GetPeerEuid(pipe_.get(), peer_euid); | 606 return IPC::GetPeerEuid(pipe_.get(), peer_euid); |
609 } | 607 } |
610 #endif | 608 #endif |
611 | 609 |
612 void ChannelPosix::ResetToAcceptingConnectionState() { | 610 void ChannelPosix::ResetToAcceptingConnectionState() { |
613 // Unregister libevent for the unix domain socket and close it. | 611 // Unregister libevent for the unix domain socket and close it. |
614 read_watcher_.StopWatchingFileDescriptor(); | 612 read_watcher_.StopWatchingFileDescriptor(); |
615 write_watcher_.StopWatchingFileDescriptor(); | 613 write_watcher_.StopWatchingFileDescriptor(); |
616 ResetSafely(&pipe_); | 614 pipe_.reset(); |
617 #if defined(IPC_USES_READWRITE) | 615 #if defined(IPC_USES_READWRITE) |
618 fd_pipe_.reset(); | 616 fd_pipe_.reset(); |
619 remote_fd_pipe_.reset(); | 617 remote_fd_pipe_.reset(); |
620 #endif // IPC_USES_READWRITE | 618 #endif // IPC_USES_READWRITE |
621 | 619 |
622 while (!output_queue_.empty()) { | 620 while (!output_queue_.empty()) { |
623 Message* m = output_queue_.front(); | 621 Message* m = output_queue_.front(); |
624 output_queue_.pop(); | 622 output_queue_.pop(); |
625 delete m; | 623 delete m; |
626 } | 624 } |
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1073 } | 1071 } |
1074 | 1072 |
1075 base::ProcessId ChannelPosix::GetPeerPID() const { | 1073 base::ProcessId ChannelPosix::GetPeerPID() const { |
1076 return peer_pid_; | 1074 return peer_pid_; |
1077 } | 1075 } |
1078 | 1076 |
1079 base::ProcessId ChannelPosix::GetSelfPID() const { | 1077 base::ProcessId ChannelPosix::GetSelfPID() const { |
1080 return GetHelloMessageProcId(); | 1078 return GetHelloMessageProcId(); |
1081 } | 1079 } |
1082 | 1080 |
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 DPCHECK(0 == IGNORE_EINTR(close(fd_to_close))); | |
1098 } | |
1099 | |
1100 //------------------------------------------------------------------------------ | 1081 //------------------------------------------------------------------------------ |
1101 // Channel's methods | 1082 // Channel's methods |
1102 | 1083 |
1103 // static | 1084 // static |
1104 scoped_ptr<Channel> Channel::Create( | 1085 scoped_ptr<Channel> Channel::Create( |
1105 const IPC::ChannelHandle &channel_handle, Mode mode, Listener* listener) { | 1086 const IPC::ChannelHandle &channel_handle, Mode mode, Listener* listener) { |
1106 return make_scoped_ptr(new ChannelPosix(channel_handle, mode, listener)); | 1087 return make_scoped_ptr(new ChannelPosix(channel_handle, mode, listener)); |
1107 } | 1088 } |
1108 | 1089 |
1109 // static | 1090 // static |
(...skipping 15 matching lines...) Expand all Loading... |
1125 } | 1106 } |
1126 | 1107 |
1127 #if defined(OS_LINUX) | 1108 #if defined(OS_LINUX) |
1128 // static | 1109 // static |
1129 void Channel::SetGlobalPid(int pid) { | 1110 void Channel::SetGlobalPid(int pid) { |
1130 ChannelPosix::SetGlobalPid(pid); | 1111 ChannelPosix::SetGlobalPid(pid); |
1131 } | 1112 } |
1132 #endif // OS_LINUX | 1113 #endif // OS_LINUX |
1133 | 1114 |
1134 } // namespace IPC | 1115 } // namespace IPC |
OLD | NEW |