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