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> |
11 #include <sys/stat.h> | 11 #include <sys/stat.h> |
12 #include <sys/types.h> | 12 #include <sys/types.h> |
13 #include <unistd.h> | 13 #include <unistd.h> |
14 | 14 |
15 #if defined(OS_OPENBSD) | 15 #if defined(OS_OPENBSD) |
16 #include <sys/uio.h> | 16 #include <sys/uio.h> |
17 #endif | 17 #endif |
18 | 18 |
19 #if !defined(__native_client_nonsfi__) | 19 #if !defined(OS_NACL_NONSFI) |
20 #include <sys/un.h> | 20 #include <sys/un.h> |
21 #endif | 21 #endif |
22 | 22 |
23 #include <map> | 23 #include <map> |
24 #include <string> | 24 #include <string> |
25 | 25 |
26 #include "base/command_line.h" | 26 #include "base/command_line.h" |
27 #include "base/files/file_path.h" | 27 #include "base/files/file_path.h" |
28 #include "base/files/file_util.h" | 28 #include "base/files/file_util.h" |
29 #include "base/location.h" | 29 #include "base/location.h" |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
251 if (value == -1) { | 251 if (value == -1) { |
252 PLOG(ERROR) << "fcntl(F_GETFL) " << pipe_name_; | 252 PLOG(ERROR) << "fcntl(F_GETFL) " << pipe_name_; |
253 return false; | 253 return false; |
254 } | 254 } |
255 if (!(value & O_NONBLOCK)) { | 255 if (!(value & O_NONBLOCK)) { |
256 LOG(ERROR) << "Socket " << pipe_name_ << " must be O_NONBLOCK"; | 256 LOG(ERROR) << "Socket " << pipe_name_ << " must be O_NONBLOCK"; |
257 return false; | 257 return false; |
258 } | 258 } |
259 #endif // IPC_USES_READWRITE | 259 #endif // IPC_USES_READWRITE |
260 } else if (mode_ & MODE_NAMED_FLAG) { | 260 } else if (mode_ & MODE_NAMED_FLAG) { |
261 #if defined(__native_client_nonsfi__) | 261 #if defined(OS_NACL_NONSFI) |
262 LOG(FATAL) | 262 LOG(FATAL) |
263 << "IPC channels in nacl_helper_nonsfi should not be in NAMED mode."; | 263 << "IPC channels in nacl_helper_nonsfi should not be in NAMED mode."; |
264 #else | 264 #else |
265 // Case 2 from comment above. | 265 // Case 2 from comment above. |
266 int local_pipe_fd = -1; | 266 int local_pipe_fd = -1; |
267 | 267 |
268 if (mode_ & MODE_SERVER_FLAG) { | 268 if (mode_ & MODE_SERVER_FLAG) { |
269 if (!CreateServerUnixDomainSocket(base::FilePath(pipe_name_), | 269 if (!CreateServerUnixDomainSocket(base::FilePath(pipe_name_), |
270 &local_pipe_fd)) { | 270 &local_pipe_fd)) { |
271 return false; | 271 return false; |
272 } | 272 } |
273 | 273 |
274 must_unlink_ = true; | 274 must_unlink_ = true; |
275 } else if (mode_ & MODE_CLIENT_FLAG) { | 275 } else if (mode_ & MODE_CLIENT_FLAG) { |
276 if (!CreateClientUnixDomainSocket(base::FilePath(pipe_name_), | 276 if (!CreateClientUnixDomainSocket(base::FilePath(pipe_name_), |
277 &local_pipe_fd)) { | 277 &local_pipe_fd)) { |
278 return false; | 278 return false; |
279 } | 279 } |
280 } else { | 280 } else { |
281 LOG(ERROR) << "Bad mode: " << mode_; | 281 LOG(ERROR) << "Bad mode: " << mode_; |
282 return false; | 282 return false; |
283 } | 283 } |
284 | 284 |
285 local_pipe.reset(local_pipe_fd); | 285 local_pipe.reset(local_pipe_fd); |
286 #endif // !defined(__native_client_nonsfi__) | 286 #endif // !defined(OS_NACL_NONSFI) |
287 } else { | 287 } else { |
288 local_pipe.reset(PipeMap::GetInstance()->Lookup(pipe_name_)); | 288 local_pipe.reset(PipeMap::GetInstance()->Lookup(pipe_name_)); |
289 if (mode_ & MODE_CLIENT_FLAG) { | 289 if (mode_ & MODE_CLIENT_FLAG) { |
290 if (local_pipe.is_valid()) { | 290 if (local_pipe.is_valid()) { |
291 // Case 3 from comment above. | 291 // Case 3 from comment above. |
292 // We only allow one connection. | 292 // We only allow one connection. |
293 local_pipe.reset(HANDLE_EINTR(dup(local_pipe.release()))); | 293 local_pipe.reset(HANDLE_EINTR(dup(local_pipe.release()))); |
294 PipeMap::GetInstance()->Remove(pipe_name_); | 294 PipeMap::GetInstance()->Remove(pipe_name_); |
295 } else { | 295 } else { |
296 // Case 4a from comment above. | 296 // Case 4a from comment above. |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
338 if (!SocketPair(&fd_pipe_fd, &remote_fd_pipe_fd)) { | 338 if (!SocketPair(&fd_pipe_fd, &remote_fd_pipe_fd)) { |
339 return false; | 339 return false; |
340 } | 340 } |
341 | 341 |
342 fd_pipe_.reset(fd_pipe_fd); | 342 fd_pipe_.reset(fd_pipe_fd); |
343 remote_fd_pipe_.reset(remote_fd_pipe_fd); | 343 remote_fd_pipe_.reset(remote_fd_pipe_fd); |
344 } | 344 } |
345 #endif // IPC_USES_READWRITE | 345 #endif // IPC_USES_READWRITE |
346 | 346 |
347 if ((mode_ & MODE_SERVER_FLAG) && (mode_ & MODE_NAMED_FLAG)) { | 347 if ((mode_ & MODE_SERVER_FLAG) && (mode_ & MODE_NAMED_FLAG)) { |
348 #if defined(__native_client_nonsfi__) | 348 #if defined(OS_NACL_NONSFI) |
349 LOG(FATAL) << "IPC channels in nacl_helper_nonsfi " | 349 LOG(FATAL) << "IPC channels in nacl_helper_nonsfi " |
350 << "should not be in NAMED or SERVER mode."; | 350 << "should not be in NAMED or SERVER mode."; |
351 #else | 351 #else |
352 server_listen_pipe_.reset(local_pipe.release()); | 352 server_listen_pipe_.reset(local_pipe.release()); |
353 #endif | 353 #endif |
354 } else { | 354 } else { |
355 pipe_.reset(local_pipe.release()); | 355 pipe_.reset(local_pipe.release()); |
356 } | 356 } |
357 return true; | 357 return true; |
358 } | 358 } |
359 | 359 |
360 bool ChannelPosix::Connect() { | 360 bool ChannelPosix::Connect() { |
361 if (!server_listen_pipe_.is_valid() && !pipe_.is_valid()) { | 361 if (!server_listen_pipe_.is_valid() && !pipe_.is_valid()) { |
362 DLOG(WARNING) << "Channel creation failed: " << pipe_name_; | 362 DLOG(WARNING) << "Channel creation failed: " << pipe_name_; |
363 return false; | 363 return false; |
364 } | 364 } |
365 | 365 |
366 bool did_connect = true; | 366 bool did_connect = true; |
367 if (server_listen_pipe_.is_valid()) { | 367 if (server_listen_pipe_.is_valid()) { |
368 #if defined(__native_client_nonsfi__) | 368 #if defined(OS_NACL_NONSFI) |
369 LOG(FATAL) << "IPC channels in nacl_helper_nonsfi " | 369 LOG(FATAL) << "IPC channels in nacl_helper_nonsfi " |
370 << "should always be in client mode."; | 370 << "should always be in client mode."; |
371 #else | 371 #else |
372 // Watch the pipe for connections, and turn any connections into | 372 // Watch the pipe for connections, and turn any connections into |
373 // active sockets. | 373 // active sockets. |
374 base::MessageLoopForIO::current()->WatchFileDescriptor( | 374 base::MessageLoopForIO::current()->WatchFileDescriptor( |
375 server_listen_pipe_.get(), | 375 server_listen_pipe_.get(), |
376 true, | 376 true, |
377 base::MessageLoopForIO::WATCH_READ, | 377 base::MessageLoopForIO::WATCH_READ, |
378 &server_listen_connection_watcher_, | 378 &server_listen_connection_watcher_, |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
593 } | 593 } |
594 | 594 |
595 bool ChannelPosix::AcceptsConnections() const { | 595 bool ChannelPosix::AcceptsConnections() const { |
596 return server_listen_pipe_.is_valid(); | 596 return server_listen_pipe_.is_valid(); |
597 } | 597 } |
598 | 598 |
599 bool ChannelPosix::HasAcceptedConnection() const { | 599 bool ChannelPosix::HasAcceptedConnection() const { |
600 return AcceptsConnections() && pipe_.is_valid(); | 600 return AcceptsConnections() && pipe_.is_valid(); |
601 } | 601 } |
602 | 602 |
603 #if !defined(__native_client_nonsfi__) | 603 #if !defined(OS_NACL_NONSFI) |
604 // GetPeerEuid is not supported in nacl_helper_nonsfi. | 604 // GetPeerEuid is not supported in nacl_helper_nonsfi. |
605 bool ChannelPosix::GetPeerEuid(uid_t* peer_euid) const { | 605 bool ChannelPosix::GetPeerEuid(uid_t* peer_euid) const { |
606 DCHECK(!(mode_ & MODE_SERVER) || HasAcceptedConnection()); | 606 DCHECK(!(mode_ & MODE_SERVER) || HasAcceptedConnection()); |
607 return IPC::GetPeerEuid(pipe_.get(), peer_euid); | 607 return IPC::GetPeerEuid(pipe_.get(), peer_euid); |
608 } | 608 } |
609 #endif | 609 #endif |
610 | 610 |
611 void ChannelPosix::ResetToAcceptingConnectionState() { | 611 void ChannelPosix::ResetToAcceptingConnectionState() { |
612 // Unregister libevent for the unix domain socket and close it. | 612 // Unregister libevent for the unix domain socket and close it. |
613 read_watcher_.StopWatchingFileDescriptor(); | 613 read_watcher_.StopWatchingFileDescriptor(); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
648 #if defined(OS_LINUX) | 648 #if defined(OS_LINUX) |
649 // static | 649 // static |
650 void ChannelPosix::SetGlobalPid(int pid) { | 650 void ChannelPosix::SetGlobalPid(int pid) { |
651 global_pid_ = pid; | 651 global_pid_ = pid; |
652 } | 652 } |
653 #endif // OS_LINUX | 653 #endif // OS_LINUX |
654 | 654 |
655 // Called by libevent when we can read from the pipe without blocking. | 655 // Called by libevent when we can read from the pipe without blocking. |
656 void ChannelPosix::OnFileCanReadWithoutBlocking(int fd) { | 656 void ChannelPosix::OnFileCanReadWithoutBlocking(int fd) { |
657 if (fd == server_listen_pipe_.get()) { | 657 if (fd == server_listen_pipe_.get()) { |
658 #if defined(__native_client_nonsfi__) | 658 #if defined(OS_NACL_NONSFI) |
659 LOG(FATAL) | 659 LOG(FATAL) |
660 << "IPC channels in nacl_helper_nonsfi should not be SERVER mode."; | 660 << "IPC channels in nacl_helper_nonsfi should not be SERVER mode."; |
661 #else | 661 #else |
662 int new_pipe = 0; | 662 int new_pipe = 0; |
663 if (!ServerAcceptConnection(server_listen_pipe_.get(), &new_pipe) || | 663 if (!ServerAcceptConnection(server_listen_pipe_.get(), &new_pipe) || |
664 new_pipe < 0) { | 664 new_pipe < 0) { |
665 Close(); | 665 Close(); |
666 listener()->OnChannelListenError(); | 666 listener()->OnChannelListenError(); |
667 } | 667 } |
668 | 668 |
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
943 cmsg = CMSG_NXTHDR(msg, cmsg)) { | 943 cmsg = CMSG_NXTHDR(msg, cmsg)) { |
944 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) { | 944 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) { |
945 unsigned payload_len = cmsg->cmsg_len - CMSG_LEN(0); | 945 unsigned payload_len = cmsg->cmsg_len - CMSG_LEN(0); |
946 DCHECK_EQ(0U, payload_len % sizeof(int)); | 946 DCHECK_EQ(0U, payload_len % sizeof(int)); |
947 const int* file_descriptors = reinterpret_cast<int*>(CMSG_DATA(cmsg)); | 947 const int* file_descriptors = reinterpret_cast<int*>(CMSG_DATA(cmsg)); |
948 unsigned num_file_descriptors = payload_len / 4; | 948 unsigned num_file_descriptors = payload_len / 4; |
949 input_fds_.insert(input_fds_.end(), | 949 input_fds_.insert(input_fds_.end(), |
950 file_descriptors, | 950 file_descriptors, |
951 file_descriptors + num_file_descriptors); | 951 file_descriptors + num_file_descriptors); |
952 | 952 |
953 #if !defined(__native_client_nonsfi__) | 953 #if !defined(OS_NACL_NONSFI) |
954 // The PNaCl toolchain for Non-SFI binary build does not support | 954 // The PNaCl toolchain for Non-SFI binary build does not support |
955 // MSG_CTRUNC. | 955 // MSG_CTRUNC. |
956 // Check this after adding the FDs so we don't leak them. | 956 // Check this after adding the FDs so we don't leak them. |
957 if (msg->msg_flags & MSG_CTRUNC) { | 957 if (msg->msg_flags & MSG_CTRUNC) { |
958 ClearInputFDs(); | 958 ClearInputFDs(); |
959 return false; | 959 return false; |
960 } | 960 } |
961 #endif | 961 #endif |
962 | 962 |
963 return true; | 963 return true; |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1056 // idempotent. | 1056 // idempotent. |
1057 | 1057 |
1058 ResetToAcceptingConnectionState(); | 1058 ResetToAcceptingConnectionState(); |
1059 | 1059 |
1060 if (must_unlink_) { | 1060 if (must_unlink_) { |
1061 unlink(pipe_name_.c_str()); | 1061 unlink(pipe_name_.c_str()); |
1062 must_unlink_ = false; | 1062 must_unlink_ = false; |
1063 } | 1063 } |
1064 | 1064 |
1065 if (server_listen_pipe_.is_valid()) { | 1065 if (server_listen_pipe_.is_valid()) { |
1066 #if defined(__native_client_nonsfi__) | 1066 #if defined(OS_NACL_NONSFI) |
1067 LOG(FATAL) | 1067 LOG(FATAL) |
1068 << "IPC channels in nacl_helper_nonsfi should not be SERVER mode."; | 1068 << "IPC channels in nacl_helper_nonsfi should not be SERVER mode."; |
1069 #else | 1069 #else |
1070 server_listen_pipe_.reset(); | 1070 server_listen_pipe_.reset(); |
1071 // Unregister libevent for the listening socket and close it. | 1071 // Unregister libevent for the listening socket and close it. |
1072 server_listen_connection_watcher_.StopWatchingFileDescriptor(); | 1072 server_listen_connection_watcher_.StopWatchingFileDescriptor(); |
1073 #endif | 1073 #endif |
1074 } | 1074 } |
1075 | 1075 |
1076 CloseClientFileDescriptor(); | 1076 CloseClientFileDescriptor(); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1112 } | 1112 } |
1113 | 1113 |
1114 #if defined(OS_LINUX) | 1114 #if defined(OS_LINUX) |
1115 // static | 1115 // static |
1116 void Channel::SetGlobalPid(int pid) { | 1116 void Channel::SetGlobalPid(int pid) { |
1117 ChannelPosix::SetGlobalPid(pid); | 1117 ChannelPosix::SetGlobalPid(pid); |
1118 } | 1118 } |
1119 #endif // OS_LINUX | 1119 #endif // OS_LINUX |
1120 | 1120 |
1121 } // namespace IPC | 1121 } // namespace IPC |
OLD | NEW |