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 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 return i->second; | 86 return i->second; |
87 } | 87 } |
88 | 88 |
89 // Remove the mapping for the given channel id. No error is signaled if the | 89 // Remove the mapping for the given channel id. No error is signaled if the |
90 // channel_id doesn't exist | 90 // channel_id doesn't exist |
91 void RemoveAndClose(const std::string& channel_id) { | 91 void RemoveAndClose(const std::string& channel_id) { |
92 AutoLock locked(lock_); | 92 AutoLock locked(lock_); |
93 | 93 |
94 ChannelToFDMap::iterator i = map_.find(channel_id); | 94 ChannelToFDMap::iterator i = map_.find(channel_id); |
95 if (i != map_.end()) { | 95 if (i != map_.end()) { |
96 if (HANDLE_EINTR(close(i->second)) < 0) | 96 HANDLE_EINTR(close(i->second)); |
97 PLOG(ERROR) << "close"; | |
98 map_.erase(i); | 97 map_.erase(i); |
99 } | 98 } |
100 } | 99 } |
101 | 100 |
102 // Insert a mapping from @channel_id to @fd. It's a fatal error to insert a | 101 // Insert a mapping from @channel_id to @fd. It's a fatal error to insert a |
103 // mapping if one already exists for the given channel_id | 102 // mapping if one already exists for the given channel_id |
104 void Insert(const std::string& channel_id, int fd) { | 103 void Insert(const std::string& channel_id, int fd) { |
105 AutoLock locked(lock_); | 104 AutoLock locked(lock_); |
106 DCHECK(fd != -1); | 105 DCHECK(fd != -1); |
107 | 106 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
149 } | 148 } |
150 | 149 |
151 // Create socket. | 150 // Create socket. |
152 int fd = socket(AF_UNIX, SOCK_STREAM, 0); | 151 int fd = socket(AF_UNIX, SOCK_STREAM, 0); |
153 if (fd < 0) { | 152 if (fd < 0) { |
154 return false; | 153 return false; |
155 } | 154 } |
156 | 155 |
157 // Make socket non-blocking | 156 // Make socket non-blocking |
158 if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) { | 157 if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) { |
159 if (HANDLE_EINTR(close(fd)) < 0) | 158 HANDLE_EINTR(close(fd)); |
160 PLOG(ERROR) << "close"; | |
161 return false; | 159 return false; |
162 } | 160 } |
163 | 161 |
164 // Delete any old FS instances. | 162 // Delete any old FS instances. |
165 unlink(pipe_name.c_str()); | 163 unlink(pipe_name.c_str()); |
166 | 164 |
167 // Create unix_addr structure | 165 // Create unix_addr structure |
168 struct sockaddr_un unix_addr; | 166 struct sockaddr_un unix_addr; |
169 memset(&unix_addr, 0, sizeof(unix_addr)); | 167 memset(&unix_addr, 0, sizeof(unix_addr)); |
170 unix_addr.sun_family = AF_UNIX; | 168 unix_addr.sun_family = AF_UNIX; |
171 snprintf(unix_addr.sun_path, kMaxPipeNameLength, "%s", pipe_name.c_str()); | 169 snprintf(unix_addr.sun_path, kMaxPipeNameLength, "%s", pipe_name.c_str()); |
172 size_t unix_addr_len = offsetof(struct sockaddr_un, sun_path) + | 170 size_t unix_addr_len = offsetof(struct sockaddr_un, sun_path) + |
173 strlen(unix_addr.sun_path) + 1; | 171 strlen(unix_addr.sun_path) + 1; |
174 | 172 |
175 // Bind the socket. | 173 // Bind the socket. |
176 if (bind(fd, reinterpret_cast<const sockaddr*>(&unix_addr), | 174 if (bind(fd, reinterpret_cast<const sockaddr*>(&unix_addr), |
177 unix_addr_len) != 0) { | 175 unix_addr_len) != 0) { |
178 if (HANDLE_EINTR(close(fd)) < 0) | 176 HANDLE_EINTR(close(fd)); |
179 PLOG(ERROR) << "close"; | |
180 return false; | 177 return false; |
181 } | 178 } |
182 | 179 |
183 // Start listening on the socket. | 180 // Start listening on the socket. |
184 const int listen_queue_length = 1; | 181 const int listen_queue_length = 1; |
185 if (listen(fd, listen_queue_length) != 0) { | 182 if (listen(fd, listen_queue_length) != 0) { |
186 if (HANDLE_EINTR(close(fd)) < 0) | 183 HANDLE_EINTR(close(fd)); |
187 PLOG(ERROR) << "close"; | |
188 return false; | 184 return false; |
189 } | 185 } |
190 | 186 |
191 *server_listen_fd = fd; | 187 *server_listen_fd = fd; |
192 return true; | 188 return true; |
193 } | 189 } |
194 | 190 |
195 // Accept a connection on a fifo. | 191 // Accept a connection on a fifo. |
196 bool ServerAcceptFifoConnection(int server_listen_fd, int* server_socket) { | 192 bool ServerAcceptFifoConnection(int server_listen_fd, int* server_socket) { |
197 DCHECK(server_socket); | 193 DCHECK(server_socket); |
(...skipping 17 matching lines...) Expand all Loading... |
215 // Create socket. | 211 // Create socket. |
216 int fd = socket(AF_UNIX, SOCK_STREAM, 0); | 212 int fd = socket(AF_UNIX, SOCK_STREAM, 0); |
217 if (fd < 0) { | 213 if (fd < 0) { |
218 LOG(ERROR) << "fd is invalid"; | 214 LOG(ERROR) << "fd is invalid"; |
219 return false; | 215 return false; |
220 } | 216 } |
221 | 217 |
222 // Make socket non-blocking | 218 // Make socket non-blocking |
223 if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) { | 219 if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) { |
224 LOG(ERROR) << "fcntl failed"; | 220 LOG(ERROR) << "fcntl failed"; |
225 if (HANDLE_EINTR(close(fd)) < 0) | 221 HANDLE_EINTR(close(fd)); |
226 PLOG(ERROR) << "close"; | |
227 return false; | 222 return false; |
228 } | 223 } |
229 | 224 |
230 // Create server side of socket. | 225 // Create server side of socket. |
231 struct sockaddr_un server_unix_addr; | 226 struct sockaddr_un server_unix_addr; |
232 memset(&server_unix_addr, 0, sizeof(server_unix_addr)); | 227 memset(&server_unix_addr, 0, sizeof(server_unix_addr)); |
233 server_unix_addr.sun_family = AF_UNIX; | 228 server_unix_addr.sun_family = AF_UNIX; |
234 snprintf(server_unix_addr.sun_path, kMaxPipeNameLength, "%s", | 229 snprintf(server_unix_addr.sun_path, kMaxPipeNameLength, "%s", |
235 pipe_name.c_str()); | 230 pipe_name.c_str()); |
236 size_t server_unix_addr_len = offsetof(struct sockaddr_un, sun_path) + | 231 size_t server_unix_addr_len = offsetof(struct sockaddr_un, sun_path) + |
237 strlen(server_unix_addr.sun_path) + 1; | 232 strlen(server_unix_addr.sun_path) + 1; |
238 | 233 |
239 if (HANDLE_EINTR(connect(fd, reinterpret_cast<sockaddr*>(&server_unix_addr), | 234 if (HANDLE_EINTR(connect(fd, reinterpret_cast<sockaddr*>(&server_unix_addr), |
240 server_unix_addr_len)) != 0) { | 235 server_unix_addr_len)) != 0) { |
241 if (HANDLE_EINTR(close(fd)) < 0) | 236 HANDLE_EINTR(close(fd)); |
242 PLOG(ERROR) << "close"; | |
243 return false; | 237 return false; |
244 } | 238 } |
245 | 239 |
246 *client_socket = fd; | 240 *client_socket = fd; |
247 return true; | 241 return true; |
248 } | 242 } |
249 | 243 |
250 bool SocketWriteErrorIsRecoverable() { | 244 bool SocketWriteErrorIsRecoverable() { |
251 #if defined(OS_MACOSX) | 245 #if defined(OS_MACOSX) |
252 // On OS X if sendmsg() is trying to send fds between processes and there | 246 // On OS X if sendmsg() is trying to send fds between processes and there |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
314 int pipe_fds[2]; | 308 int pipe_fds[2]; |
315 if (socketpair(AF_UNIX, SOCK_STREAM, 0, pipe_fds) != 0) { | 309 if (socketpair(AF_UNIX, SOCK_STREAM, 0, pipe_fds) != 0) { |
316 PLOG(ERROR) << "socketpair()"; | 310 PLOG(ERROR) << "socketpair()"; |
317 return false; | 311 return false; |
318 } | 312 } |
319 | 313 |
320 // Set both ends to be non-blocking. | 314 // Set both ends to be non-blocking. |
321 if (fcntl(pipe_fds[0], F_SETFL, O_NONBLOCK) == -1 || | 315 if (fcntl(pipe_fds[0], F_SETFL, O_NONBLOCK) == -1 || |
322 fcntl(pipe_fds[1], F_SETFL, O_NONBLOCK) == -1) { | 316 fcntl(pipe_fds[1], F_SETFL, O_NONBLOCK) == -1) { |
323 PLOG(ERROR) << "fcntl(O_NONBLOCK)"; | 317 PLOG(ERROR) << "fcntl(O_NONBLOCK)"; |
324 if (HANDLE_EINTR(close(pipe_fds[0])) < 0) | 318 HANDLE_EINTR(close(pipe_fds[0])); |
325 PLOG(ERROR) << "close"; | 319 HANDLE_EINTR(close(pipe_fds[1])); |
326 if (HANDLE_EINTR(close(pipe_fds[1])) < 0) | |
327 PLOG(ERROR) << "close"; | |
328 return false; | 320 return false; |
329 } | 321 } |
330 | 322 |
331 *fd1 = pipe_fds[0]; | 323 *fd1 = pipe_fds[0]; |
332 *fd2 = pipe_fds[1]; | 324 *fd2 = pipe_fds[1]; |
333 | 325 |
334 return true; | 326 return true; |
335 } | 327 } |
336 | 328 |
337 bool Channel::ChannelImpl::CreatePipe(const std::string& channel_id, | 329 bool Channel::ChannelImpl::CreatePipe(const std::string& channel_id, |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
535 const unsigned payload_len = cmsg->cmsg_len - CMSG_LEN(0); | 527 const unsigned payload_len = cmsg->cmsg_len - CMSG_LEN(0); |
536 DCHECK(payload_len % sizeof(int) == 0); | 528 DCHECK(payload_len % sizeof(int) == 0); |
537 wire_fds = reinterpret_cast<int*>(CMSG_DATA(cmsg)); | 529 wire_fds = reinterpret_cast<int*>(CMSG_DATA(cmsg)); |
538 num_wire_fds = payload_len / 4; | 530 num_wire_fds = payload_len / 4; |
539 | 531 |
540 if (msg.msg_flags & MSG_CTRUNC) { | 532 if (msg.msg_flags & MSG_CTRUNC) { |
541 LOG(ERROR) << "SCM_RIGHTS message was truncated" | 533 LOG(ERROR) << "SCM_RIGHTS message was truncated" |
542 << " cmsg_len:" << cmsg->cmsg_len | 534 << " cmsg_len:" << cmsg->cmsg_len |
543 << " fd:" << pipe_; | 535 << " fd:" << pipe_; |
544 for (unsigned i = 0; i < num_wire_fds; ++i) | 536 for (unsigned i = 0; i < num_wire_fds; ++i) |
545 if (HANDLE_EINTR(close(wire_fds[i])) < 0) | 537 HANDLE_EINTR(close(wire_fds[i])); |
546 PLOG(ERROR) << "close" << i; | |
547 return false; | 538 return false; |
548 } | 539 } |
549 break; | 540 break; |
550 } | 541 } |
551 } | 542 } |
552 } | 543 } |
553 | 544 |
554 // Process messages from input buffer. | 545 // Process messages from input buffer. |
555 const char *p; | 546 const char *p; |
556 const char *end; | 547 const char *end; |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
616 const unsigned payload_len = cmsg->cmsg_len - CMSG_LEN(0); | 607 const unsigned payload_len = cmsg->cmsg_len - CMSG_LEN(0); |
617 DCHECK(payload_len % sizeof(int) == 0); | 608 DCHECK(payload_len % sizeof(int) == 0); |
618 wire_fds = reinterpret_cast<int*>(CMSG_DATA(cmsg)); | 609 wire_fds = reinterpret_cast<int*>(CMSG_DATA(cmsg)); |
619 num_wire_fds = payload_len / 4; | 610 num_wire_fds = payload_len / 4; |
620 | 611 |
621 if (msg.msg_flags & MSG_CTRUNC) { | 612 if (msg.msg_flags & MSG_CTRUNC) { |
622 LOG(ERROR) << "SCM_RIGHTS message was truncated" | 613 LOG(ERROR) << "SCM_RIGHTS message was truncated" |
623 << " cmsg_len:" << cmsg->cmsg_len | 614 << " cmsg_len:" << cmsg->cmsg_len |
624 << " fd:" << pipe_; | 615 << " fd:" << pipe_; |
625 for (unsigned i = 0; i < num_wire_fds; ++i) | 616 for (unsigned i = 0; i < num_wire_fds; ++i) |
626 if (HANDLE_EINTR(close(wire_fds[i])) < 0) | 617 HANDLE_EINTR(close(wire_fds[i])); |
627 PLOG(ERROR) << "close" << i; | |
628 return false; | 618 return false; |
629 } | 619 } |
630 break; | 620 break; |
631 } | 621 } |
632 } | 622 } |
633 if (input_overflow_fds_.empty()) { | 623 if (input_overflow_fds_.empty()) { |
634 fds = wire_fds; | 624 fds = wire_fds; |
635 num_fds = num_wire_fds; | 625 num_fds = num_wire_fds; |
636 } else { | 626 } else { |
637 if (num_wire_fds > 0) { | 627 if (num_wire_fds > 0) { |
(...skipping 25 matching lines...) Expand all Loading... |
663 << " header()->num_fds:" << m.header()->num_fds | 653 << " header()->num_fds:" << m.header()->num_fds |
664 << " num_fds:" << num_fds | 654 << " num_fds:" << num_fds |
665 << " fds_i:" << fds_i; | 655 << " fds_i:" << fds_i; |
666 #if defined(CHROMIUM_SELINUX) | 656 #if defined(CHROMIUM_SELINUX) |
667 LOG(WARNING) << "In the case of SELinux this can be caused when " | 657 LOG(WARNING) << "In the case of SELinux this can be caused when " |
668 "using a --user-data-dir to which the default " | 658 "using a --user-data-dir to which the default " |
669 "policy doesn't give the renderer access to. "; | 659 "policy doesn't give the renderer access to. "; |
670 #endif | 660 #endif |
671 // close the existing file descriptors so that we don't leak them | 661 // close the existing file descriptors so that we don't leak them |
672 for (unsigned i = fds_i; i < num_fds; ++i) | 662 for (unsigned i = fds_i; i < num_fds; ++i) |
673 if (HANDLE_EINTR(close(fds[i])) < 0) | 663 HANDLE_EINTR(close(fds[i])); |
674 PLOG(ERROR) << "close" << i; | |
675 input_overflow_fds_.clear(); | 664 input_overflow_fds_.clear(); |
676 // abort the connection | 665 // abort the connection |
677 return false; | 666 return false; |
678 } | 667 } |
679 | 668 |
680 m.file_descriptor_set()->SetDescriptors( | 669 m.file_descriptor_set()->SetDescriptors( |
681 &fds[fds_i], m.header()->num_fds); | 670 &fds[fds_i], m.header()->num_fds); |
682 fds_i += m.header()->num_fds; | 671 fds_i += m.header()->num_fds; |
683 } | 672 } |
684 #ifdef IPC_MESSAGE_DEBUG_EXTRA | 673 #ifdef IPC_MESSAGE_DEBUG_EXTRA |
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
997 } | 986 } |
998 | 987 |
999 void Channel::ChannelImpl::Close() { | 988 void Channel::ChannelImpl::Close() { |
1000 // Close can be called multiple time, so we need to make sure we're | 989 // Close can be called multiple time, so we need to make sure we're |
1001 // idempotent. | 990 // idempotent. |
1002 | 991 |
1003 // Unregister libevent for the listening socket and close it. | 992 // Unregister libevent for the listening socket and close it. |
1004 server_listen_connection_watcher_.StopWatchingFileDescriptor(); | 993 server_listen_connection_watcher_.StopWatchingFileDescriptor(); |
1005 | 994 |
1006 if (server_listen_pipe_ != -1) { | 995 if (server_listen_pipe_ != -1) { |
1007 if (HANDLE_EINTR(close(server_listen_pipe_)) < 0) | 996 HANDLE_EINTR(close(server_listen_pipe_)); |
1008 PLOG(ERROR) << "close"; | |
1009 server_listen_pipe_ = -1; | 997 server_listen_pipe_ = -1; |
1010 } | 998 } |
1011 | 999 |
1012 // Unregister libevent for the FIFO and close it. | 1000 // Unregister libevent for the FIFO and close it. |
1013 read_watcher_.StopWatchingFileDescriptor(); | 1001 read_watcher_.StopWatchingFileDescriptor(); |
1014 write_watcher_.StopWatchingFileDescriptor(); | 1002 write_watcher_.StopWatchingFileDescriptor(); |
1015 if (pipe_ != -1) { | 1003 if (pipe_ != -1) { |
1016 if (HANDLE_EINTR(close(pipe_)) < 0) | 1004 HANDLE_EINTR(close(pipe_)); |
1017 PLOG(ERROR) << "close"; | |
1018 pipe_ = -1; | 1005 pipe_ = -1; |
1019 } | 1006 } |
1020 if (client_pipe_ != -1) { | 1007 if (client_pipe_ != -1) { |
1021 Singleton<PipeMap>()->RemoveAndClose(pipe_name_); | 1008 Singleton<PipeMap>()->RemoveAndClose(pipe_name_); |
1022 client_pipe_ = -1; | 1009 client_pipe_ = -1; |
1023 } | 1010 } |
1024 #if !defined(OS_MACOSX) | 1011 #if !defined(OS_MACOSX) |
1025 if (fd_pipe_ != -1) { | 1012 if (fd_pipe_ != -1) { |
1026 if (HANDLE_EINTR(close(fd_pipe_)) < 0) | 1013 HANDLE_EINTR(close(fd_pipe_)); |
1027 PLOG(ERROR) << "close"; | |
1028 fd_pipe_ = -1; | 1014 fd_pipe_ = -1; |
1029 } | 1015 } |
1030 if (remote_fd_pipe_ != -1) { | 1016 if (remote_fd_pipe_ != -1) { |
1031 if (HANDLE_EINTR(close(remote_fd_pipe_)) < 0) | 1017 HANDLE_EINTR(close(remote_fd_pipe_)); |
1032 PLOG(ERROR) << "close"; | |
1033 remote_fd_pipe_ = -1; | 1018 remote_fd_pipe_ = -1; |
1034 } | 1019 } |
1035 #endif | 1020 #endif |
1036 | 1021 |
1037 if (uses_fifo_) { | 1022 if (uses_fifo_) { |
1038 // Unlink the FIFO | 1023 // Unlink the FIFO |
1039 unlink(pipe_name_.c_str()); | 1024 unlink(pipe_name_.c_str()); |
1040 } | 1025 } |
1041 | 1026 |
1042 while (!output_queue_.empty()) { | 1027 while (!output_queue_.empty()) { |
1043 Message* m = output_queue_.front(); | 1028 Message* m = output_queue_.front(); |
1044 output_queue_.pop(); | 1029 output_queue_.pop(); |
1045 delete m; | 1030 delete m; |
1046 } | 1031 } |
1047 | 1032 |
1048 // Close any outstanding, received file descriptors | 1033 // Close any outstanding, received file descriptors |
1049 for (std::vector<int>::iterator | 1034 for (std::vector<int>::iterator |
1050 i = input_overflow_fds_.begin(); i != input_overflow_fds_.end(); ++i) { | 1035 i = input_overflow_fds_.begin(); i != input_overflow_fds_.end(); ++i) { |
1051 if (HANDLE_EINTR(close(*i)) < 0) | 1036 HANDLE_EINTR(close(*i)); |
1052 PLOG(ERROR) << "close"; | |
1053 } | 1037 } |
1054 input_overflow_fds_.clear(); | 1038 input_overflow_fds_.clear(); |
1055 } | 1039 } |
1056 | 1040 |
1057 //------------------------------------------------------------------------------ | 1041 //------------------------------------------------------------------------------ |
1058 // Channel's methods simply call through to ChannelImpl. | 1042 // Channel's methods simply call through to ChannelImpl. |
1059 Channel::Channel(const std::string& channel_id, Mode mode, | 1043 Channel::Channel(const std::string& channel_id, Mode mode, |
1060 Listener* listener) | 1044 Listener* listener) |
1061 : channel_impl_(new ChannelImpl(channel_id, mode, listener)) { | 1045 : channel_impl_(new ChannelImpl(channel_id, mode, listener)) { |
1062 } | 1046 } |
(...skipping 16 matching lines...) Expand all Loading... |
1079 | 1063 |
1080 bool Channel::Send(Message* message) { | 1064 bool Channel::Send(Message* message) { |
1081 return channel_impl_->Send(message); | 1065 return channel_impl_->Send(message); |
1082 } | 1066 } |
1083 | 1067 |
1084 int Channel::GetClientFileDescriptor() const { | 1068 int Channel::GetClientFileDescriptor() const { |
1085 return channel_impl_->GetClientFileDescriptor(); | 1069 return channel_impl_->GetClientFileDescriptor(); |
1086 } | 1070 } |
1087 | 1071 |
1088 } // namespace IPC | 1072 } // namespace IPC |
OLD | NEW |