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