Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(41)

Side by Side Diff: ipc/ipc_channel_posix.cc

Issue 1139703005: ipc: remove IPC_USES_READWRITE (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Apply unifdef to header too Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ipc/ipc_channel_posix.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 // 3) It's for a client that we implement ourself. This is used 240 // 3) It's for a client that we implement ourself. This is used
241 // in single-process unittesting. 241 // in single-process unittesting.
242 // 4) It's the initial IPC channel: 242 // 4) It's the initial IPC channel:
243 // 4a) Client side: Pull the pipe out of the GlobalDescriptors set. 243 // 4a) Client side: Pull the pipe out of the GlobalDescriptors set.
244 // 4b) Server side: create the pipe. 244 // 4b) Server side: create the pipe.
245 245
246 base::ScopedFD local_pipe; 246 base::ScopedFD local_pipe;
247 if (channel_handle.socket.fd != -1) { 247 if (channel_handle.socket.fd != -1) {
248 // Case 1 from comment above. 248 // Case 1 from comment above.
249 local_pipe.reset(channel_handle.socket.fd); 249 local_pipe.reset(channel_handle.socket.fd);
250 #if defined(IPC_USES_READWRITE)
251 // Test the socket passed into us to make sure it is nonblocking.
252 // We don't want to call read/write on a blocking socket.
253 int value = fcntl(local_pipe.get(), F_GETFL);
254 if (value == -1) {
255 PLOG(ERROR) << "fcntl(F_GETFL) " << pipe_name_;
256 return false;
257 }
258 if (!(value & O_NONBLOCK)) {
259 LOG(ERROR) << "Socket " << pipe_name_ << " must be O_NONBLOCK";
260 return false;
261 }
262 #endif // IPC_USES_READWRITE
263 } else if (mode_ & MODE_NAMED_FLAG) { 250 } else if (mode_ & MODE_NAMED_FLAG) {
264 #if defined(OS_NACL_NONSFI) 251 #if defined(OS_NACL_NONSFI)
265 LOG(FATAL) 252 LOG(FATAL)
266 << "IPC channels in nacl_helper_nonsfi should not be in NAMED mode."; 253 << "IPC channels in nacl_helper_nonsfi should not be in NAMED mode.";
267 #else 254 #else
268 // Case 2 from comment above. 255 // Case 2 from comment above.
269 int local_pipe_fd = -1; 256 int local_pipe_fd = -1;
270 257
271 if (mode_ & MODE_SERVER_FLAG) { 258 if (mode_ & MODE_SERVER_FLAG) {
272 if (!CreateServerUnixDomainSocket(base::FilePath(pipe_name_), 259 if (!CreateServerUnixDomainSocket(base::FilePath(pipe_name_),
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
325 if (!SocketPair(&local_pipe_fd, &client_pipe_fd)) 312 if (!SocketPair(&local_pipe_fd, &client_pipe_fd))
326 return false; 313 return false;
327 local_pipe.reset(local_pipe_fd); 314 local_pipe.reset(local_pipe_fd);
328 client_pipe_.reset(client_pipe_fd); 315 client_pipe_.reset(client_pipe_fd);
329 PipeMap::GetInstance()->Insert(pipe_name_, client_pipe_fd); 316 PipeMap::GetInstance()->Insert(pipe_name_, client_pipe_fd);
330 } else { 317 } else {
331 LOG(ERROR) << "Bad mode: " << mode_; 318 LOG(ERROR) << "Bad mode: " << mode_;
332 return false; 319 return false;
333 } 320 }
334 } 321 }
335 322
hidehiko 2015/05/18 04:54:05 nit: unnecessary empty line?
mdempsky 2015/05/18 17:58:37 Done.
336 #if defined(IPC_USES_READWRITE)
337 // Create a dedicated socketpair() for exchanging file descriptors.
338 // See comments for IPC_USES_READWRITE for details.
339 if (mode_ & MODE_CLIENT_FLAG) {
340 int fd_pipe_fd = 1, remote_fd_pipe_fd = -1;
341 if (!SocketPair(&fd_pipe_fd, &remote_fd_pipe_fd)) {
342 return false;
343 }
344
345 fd_pipe_.reset(fd_pipe_fd);
346 remote_fd_pipe_.reset(remote_fd_pipe_fd);
347 }
348 #endif // IPC_USES_READWRITE
349 323
350 if ((mode_ & MODE_SERVER_FLAG) && (mode_ & MODE_NAMED_FLAG)) { 324 if ((mode_ & MODE_SERVER_FLAG) && (mode_ & MODE_NAMED_FLAG)) {
351 #if defined(OS_NACL_NONSFI) 325 #if defined(OS_NACL_NONSFI)
352 LOG(FATAL) << "IPC channels in nacl_helper_nonsfi " 326 LOG(FATAL) << "IPC channels in nacl_helper_nonsfi "
353 << "should not be in NAMED or SERVER mode."; 327 << "should not be in NAMED or SERVER mode.";
354 #else 328 #else
355 server_listen_pipe_.reset(local_pipe.release()); 329 server_listen_pipe_.reset(local_pipe.release());
356 #endif 330 #endif
357 } else { 331 } else {
358 pipe_.reset(local_pipe.release()); 332 pipe_.reset(local_pipe.release());
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
459 cmsg->cmsg_level = SOL_SOCKET; 433 cmsg->cmsg_level = SOL_SOCKET;
460 cmsg->cmsg_type = SCM_RIGHTS; 434 cmsg->cmsg_type = SCM_RIGHTS;
461 cmsg->cmsg_len = CMSG_LEN(sizeof(int) * num_fds); 435 cmsg->cmsg_len = CMSG_LEN(sizeof(int) * num_fds);
462 msg->attachment_set()->PeekDescriptors( 436 msg->attachment_set()->PeekDescriptors(
463 reinterpret_cast<int*>(CMSG_DATA(cmsg))); 437 reinterpret_cast<int*>(CMSG_DATA(cmsg)));
464 msgh.msg_controllen = cmsg->cmsg_len; 438 msgh.msg_controllen = cmsg->cmsg_len;
465 439
466 // DCHECK_LE above already checks that 440 // DCHECK_LE above already checks that
467 // num_fds < kMaxDescriptorsPerMessage so no danger of overflow. 441 // num_fds < kMaxDescriptorsPerMessage so no danger of overflow.
468 msg->header()->num_fds = static_cast<uint16>(num_fds); 442 msg->header()->num_fds = static_cast<uint16>(num_fds);
469 443
hidehiko 2015/05/18 04:54:05 nit: unnecessary empty line?
mdempsky 2015/05/18 17:58:36 Done.
470 #if defined(IPC_USES_READWRITE)
471 if (!IsHelloMessage(*msg)) {
472 // Only the Hello message sends the file descriptor with the message.
473 // Subsequently, we can send file descriptors on the dedicated
474 // fd_pipe_ which makes Seccomp sandbox operation more efficient.
475 struct iovec fd_pipe_iov = { const_cast<char *>(""), 1 };
476 msgh.msg_iov = &fd_pipe_iov;
477 fd_written = fd_pipe_.get();
478 bytes_written =
479 HANDLE_EINTR(sendmsg(fd_pipe_.get(), &msgh, MSG_DONTWAIT));
480 msgh.msg_iov = &iov;
481 msgh.msg_controllen = 0;
482 if (bytes_written > 0) {
483 CloseFileDescriptors(msg);
484 }
485 }
486 #endif // IPC_USES_READWRITE
487 } 444 }
488 445
489 if (bytes_written == 1) { 446 if (bytes_written == 1) {
490 fd_written = pipe_.get(); 447 fd_written = pipe_.get();
491 #if defined(IPC_USES_READWRITE)
492 if ((mode_ & MODE_CLIENT_FLAG) && IsHelloMessage(*msg)) {
493 DCHECK_EQ(msg->attachment_set()->size(), 1U);
494 }
495 if (!msgh.msg_controllen) {
496 bytes_written =
497 HANDLE_EINTR(write(pipe_.get(), out_bytes, amt_to_write));
498 } else
499 #endif // IPC_USES_READWRITE
500 { 448 {
hidehiko 2015/05/18 04:54:05 nit: you do not need this brace pair.
mdempsky 2015/05/18 17:58:37 Done.
501 bytes_written = HANDLE_EINTR(sendmsg(pipe_.get(), &msgh, MSG_DONTWAIT)); 449 bytes_written = HANDLE_EINTR(sendmsg(pipe_.get(), &msgh, MSG_DONTWAIT));
502 } 450 }
503 } 451 }
504 if (bytes_written > 0) 452 if (bytes_written > 0)
505 CloseFileDescriptors(msg); 453 CloseFileDescriptors(msg);
506 454
507 if (bytes_written < 0 && !SocketWriteErrorIsRecoverable()) { 455 if (bytes_written < 0 && !SocketWriteErrorIsRecoverable()) {
508 // We can't close the pipe here, because calling OnChannelError 456 // We can't close the pipe here, because calling OnChannelError
509 // may destroy this object, and that would be bad if we are 457 // may destroy this object, and that would be bad if we are
510 // called from Send(). Instead, we return false and hope the 458 // called from Send(). Instead, we return false and hope the
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
609 DCHECK(!(mode_ & MODE_SERVER) || HasAcceptedConnection()); 557 DCHECK(!(mode_ & MODE_SERVER) || HasAcceptedConnection());
610 return IPC::GetPeerEuid(pipe_.get(), peer_euid); 558 return IPC::GetPeerEuid(pipe_.get(), peer_euid);
611 } 559 }
612 #endif 560 #endif
613 561
614 void ChannelPosix::ResetToAcceptingConnectionState() { 562 void ChannelPosix::ResetToAcceptingConnectionState() {
615 // Unregister libevent for the unix domain socket and close it. 563 // Unregister libevent for the unix domain socket and close it.
616 read_watcher_.StopWatchingFileDescriptor(); 564 read_watcher_.StopWatchingFileDescriptor();
617 write_watcher_.StopWatchingFileDescriptor(); 565 write_watcher_.StopWatchingFileDescriptor();
618 ResetSafely(&pipe_); 566 ResetSafely(&pipe_);
619 #if defined(IPC_USES_READWRITE)
620 fd_pipe_.reset();
621 remote_fd_pipe_.reset();
622 #endif // IPC_USES_READWRITE
623 567
624 while (!output_queue_.empty()) { 568 while (!output_queue_.empty()) {
625 Message* m = output_queue_.front(); 569 Message* m = output_queue_.front();
626 output_queue_.pop(); 570 output_queue_.pop();
627 delete m; 571 delete m;
628 } 572 }
629 573
630 // Close any outstanding, received file descriptors. 574 // Close any outstanding, received file descriptors.
631 ClearInputFDs(); 575 ClearInputFDs();
632 576
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
791 } 735 }
792 736
793 void ChannelPosix::QueueHelloMessage() { 737 void ChannelPosix::QueueHelloMessage() {
794 // Create the Hello message 738 // Create the Hello message
795 scoped_ptr<Message> msg(new Message(MSG_ROUTING_NONE, 739 scoped_ptr<Message> msg(new Message(MSG_ROUTING_NONE,
796 HELLO_MESSAGE_TYPE, 740 HELLO_MESSAGE_TYPE,
797 IPC::Message::PRIORITY_NORMAL)); 741 IPC::Message::PRIORITY_NORMAL));
798 if (!msg->WriteInt(GetHelloMessageProcId())) { 742 if (!msg->WriteInt(GetHelloMessageProcId())) {
799 NOTREACHED() << "Unable to pickle hello message proc id"; 743 NOTREACHED() << "Unable to pickle hello message proc id";
800 } 744 }
801 #if defined(IPC_USES_READWRITE)
802 scoped_ptr<Message> hello;
803 if (remote_fd_pipe_.is_valid()) {
804 if (!msg->WriteAttachment(
805 new internal::PlatformFileAttachment(remote_fd_pipe_.get()))) {
806 NOTREACHED() << "Unable to pickle hello message file descriptors";
807 }
808 DCHECK_EQ(msg->attachment_set()->size(), 1U);
809 }
810 #endif // IPC_USES_READWRITE
811 output_queue_.push(msg.release()); 745 output_queue_.push(msg.release());
812 } 746 }
813 747
814 ChannelPosix::ReadState ChannelPosix::ReadData( 748 ChannelPosix::ReadState ChannelPosix::ReadData(
815 char* buffer, 749 char* buffer,
816 int buffer_len, 750 int buffer_len,
817 int* bytes_read) { 751 int* bytes_read) {
818 if (!pipe_.is_valid()) 752 if (!pipe_.is_valid())
819 return READ_FAILED; 753 return READ_FAILED;
820 754
821 struct msghdr msg = {0}; 755 struct msghdr msg = {0};
822 756
823 struct iovec iov = {buffer, static_cast<size_t>(buffer_len)}; 757 struct iovec iov = {buffer, static_cast<size_t>(buffer_len)};
824 msg.msg_iov = &iov; 758 msg.msg_iov = &iov;
825 msg.msg_iovlen = 1; 759 msg.msg_iovlen = 1;
826 760
827 msg.msg_control = input_cmsg_buf_; 761 msg.msg_control = input_cmsg_buf_;
828 762
829 // recvmsg() returns 0 if the connection has closed or EAGAIN if no data 763 // recvmsg() returns 0 if the connection has closed or EAGAIN if no data
830 // is waiting on the pipe. 764 // is waiting on the pipe.
831 #if defined(IPC_USES_READWRITE)
832 if (fd_pipe_.is_valid()) {
833 *bytes_read = HANDLE_EINTR(read(pipe_.get(), buffer, buffer_len));
834 msg.msg_controllen = 0;
835 } else
836 #endif // IPC_USES_READWRITE
837 { 765 {
hidehiko 2015/05/18 04:54:05 nit, you do not need this brace pair.
mdempsky 2015/05/18 17:58:36 Done.
838 msg.msg_controllen = sizeof(input_cmsg_buf_); 766 msg.msg_controllen = sizeof(input_cmsg_buf_);
839 *bytes_read = HANDLE_EINTR(recvmsg(pipe_.get(), &msg, MSG_DONTWAIT)); 767 *bytes_read = HANDLE_EINTR(recvmsg(pipe_.get(), &msg, MSG_DONTWAIT));
840 } 768 }
841 if (*bytes_read < 0) { 769 if (*bytes_read < 0) {
842 if (errno == EAGAIN) { 770 if (errno == EAGAIN) {
843 return READ_PENDING; 771 return READ_PENDING;
844 #if defined(OS_MACOSX) 772 #if defined(OS_MACOSX)
845 } else if (errno == EPERM) { 773 } else if (errno == EPERM) {
846 // On OSX, reading from a pipe with no listener returns EPERM 774 // On OSX, reading from a pipe with no listener returns EPERM
847 // treat this as a special case to prevent spurious error messages 775 // treat this as a special case to prevent spurious error messages
(...skipping 13 matching lines...) Expand all
861 DCHECK(*bytes_read); 789 DCHECK(*bytes_read);
862 790
863 CloseClientFileDescriptor(); 791 CloseClientFileDescriptor();
864 792
865 // Read any file descriptors from the message. 793 // Read any file descriptors from the message.
866 if (!ExtractFileDescriptorsFromMsghdr(&msg)) 794 if (!ExtractFileDescriptorsFromMsghdr(&msg))
867 return READ_FAILED; 795 return READ_FAILED;
868 return READ_SUCCEEDED; 796 return READ_SUCCEEDED;
869 } 797 }
870 798
871 #if defined(IPC_USES_READWRITE)
872 bool ChannelPosix::ReadFileDescriptorsFromFDPipe() {
873 char dummy;
874 struct iovec fd_pipe_iov = { &dummy, 1 };
875
876 struct msghdr msg = { 0 };
877 msg.msg_iov = &fd_pipe_iov;
878 msg.msg_iovlen = 1;
879 msg.msg_control = input_cmsg_buf_;
880 msg.msg_controllen = sizeof(input_cmsg_buf_);
881 ssize_t bytes_received =
882 HANDLE_EINTR(recvmsg(fd_pipe_.get(), &msg, MSG_DONTWAIT));
883
884 if (bytes_received != 1)
885 return true; // No message waiting.
886
887 if (!ExtractFileDescriptorsFromMsghdr(&msg))
888 return false;
889 return true;
890 }
891 #endif
892 799
893 // On Posix, we need to fix up the file descriptors before the input message 800 // On Posix, we need to fix up the file descriptors before the input message
894 // is dispatched. 801 // is dispatched.
895 // 802 //
896 // This will read from the input_fds_ (READWRITE mode only) and read more 803 // This will read from the input_fds_ (READWRITE mode only) and read more
897 // handles from the FD pipe if necessary. 804 // handles from the FD pipe if necessary.
898 bool ChannelPosix::WillDispatchInputMessage(Message* msg) { 805 bool ChannelPosix::WillDispatchInputMessage(Message* msg) {
899 uint16 header_fds = msg->header()->num_fds; 806 uint16 header_fds = msg->header()->num_fds;
900 if (!header_fds) 807 if (!header_fds)
901 return true; // Nothing to do. 808 return true; // Nothing to do.
902 809
903 // The message has file descriptors. 810 // The message has file descriptors.
904 const char* error = NULL; 811 const char* error = NULL;
905 if (header_fds > input_fds_.size()) { 812 if (header_fds > input_fds_.size()) {
906 // The message has been completely received, but we didn't get 813 // The message has been completely received, but we didn't get
907 // enough file descriptors. 814 // enough file descriptors.
908 #if defined(IPC_USES_READWRITE)
909 if (!ReadFileDescriptorsFromFDPipe())
910 return false;
911 if (header_fds > input_fds_.size())
912 #endif // IPC_USES_READWRITE
913 error = "Message needs unreceived descriptors"; 815 error = "Message needs unreceived descriptors";
hidehiko 2015/05/18 04:54:05 nit: indent?
mdempsky 2015/05/18 17:58:37 Done.
914 } 816 }
915 817
916 if (header_fds > MessageAttachmentSet::kMaxDescriptorsPerMessage) 818 if (header_fds > MessageAttachmentSet::kMaxDescriptorsPerMessage)
917 error = "Message requires an excessive number of descriptors"; 819 error = "Message requires an excessive number of descriptors";
918 820
919 if (error) { 821 if (error) {
920 LOG(WARNING) << error 822 LOG(WARNING) << error
921 << " channel:" << this 823 << " channel:" << this
922 << " message-type:" << msg->type() 824 << " message-type:" << msg->type()
923 << " header()->num_fds:" << header_fds; 825 << " header()->num_fds:" << header_fds;
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1010 switch (msg.type()) { 912 switch (msg.type()) {
1011 default: 913 default:
1012 NOTREACHED(); 914 NOTREACHED();
1013 break; 915 break;
1014 916
1015 case Channel::HELLO_MESSAGE_TYPE: 917 case Channel::HELLO_MESSAGE_TYPE:
1016 int pid; 918 int pid;
1017 if (!iter.ReadInt(&pid)) 919 if (!iter.ReadInt(&pid))
1018 NOTREACHED(); 920 NOTREACHED();
1019 921
1020 #if defined(IPC_USES_READWRITE)
1021 if (mode_ & MODE_SERVER_FLAG) {
1022 // With IPC_USES_READWRITE, the Hello message from the client to the
1023 // server also contains the fd_pipe_, which will be used for all
1024 // subsequent file descriptor passing.
1025 DCHECK_EQ(msg.attachment_set()->size(), 1U);
1026 scoped_refptr<MessageAttachment> attachment;
1027 if (!msg.ReadAttachment(&iter, &attachment)) {
1028 NOTREACHED();
1029 }
1030 fd_pipe_.reset(attachment->TakePlatformFile());
1031 }
1032 #endif // IPC_USES_READWRITE
1033 peer_pid_ = pid; 922 peer_pid_ = pid;
1034 listener()->OnChannelConnected(pid); 923 listener()->OnChannelConnected(pid);
1035 break; 924 break;
1036 925
1037 #if defined(OS_MACOSX) 926 #if defined(OS_MACOSX)
1038 case Channel::CLOSE_FD_MESSAGE_TYPE: 927 case Channel::CLOSE_FD_MESSAGE_TYPE:
1039 int fd, hops; 928 int fd, hops;
1040 if (!iter.ReadInt(&hops)) 929 if (!iter.ReadInt(&hops))
1041 NOTREACHED(); 930 NOTREACHED();
1042 if (!iter.ReadInt(&fd)) 931 if (!iter.ReadInt(&fd))
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
1136 } 1025 }
1137 1026
1138 #if defined(OS_LINUX) 1027 #if defined(OS_LINUX)
1139 // static 1028 // static
1140 void Channel::SetGlobalPid(int pid) { 1029 void Channel::SetGlobalPid(int pid) {
1141 ChannelPosix::SetGlobalPid(pid); 1030 ChannelPosix::SetGlobalPid(pid);
1142 } 1031 }
1143 #endif // OS_LINUX 1032 #endif // OS_LINUX
1144 1033
1145 } // namespace IPC 1034 } // namespace IPC
OLDNEW
« no previous file with comments | « ipc/ipc_channel_posix.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698