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

Side by Side Diff: ipc/ipc_channel_posix.cc

Issue 5563005: Define IPC_USES_READWRITE (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Created 10 years 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 | Annotate | Revision Log
« 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) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 Listener* listener) 278 Listener* listener)
279 : mode_(mode), 279 : mode_(mode),
280 is_blocked_on_write_(false), 280 is_blocked_on_write_(false),
281 message_send_bytes_written_(0), 281 message_send_bytes_written_(0),
282 uses_fifo_( 282 uses_fifo_(
283 CommandLine::ForCurrentProcess()->HasSwitch(switches::kIPCUseFIFO) || 283 CommandLine::ForCurrentProcess()->HasSwitch(switches::kIPCUseFIFO) ||
284 mode == MODE_NAMED_SERVER || mode == MODE_NAMED_CLIENT), 284 mode == MODE_NAMED_SERVER || mode == MODE_NAMED_CLIENT),
285 server_listen_pipe_(-1), 285 server_listen_pipe_(-1),
286 pipe_(-1), 286 pipe_(-1),
287 client_pipe_(-1), 287 client_pipe_(-1),
288 #if !defined(OS_MACOSX) 288 #if defined(IPC_USES_READWRITE)
289 fd_pipe_(-1), 289 fd_pipe_(-1),
290 remote_fd_pipe_(-1), 290 remote_fd_pipe_(-1),
291 #endif 291 #endif
292 listener_(listener), 292 listener_(listener),
293 waiting_connect_(true), 293 waiting_connect_(true),
294 factory_(this) { 294 factory_(this) {
295 if (mode_ == MODE_NAMED_SERVER) 295 if (mode_ == MODE_NAMED_SERVER)
296 mode_ = MODE_SERVER; 296 mode_ = MODE_SERVER;
297 if (mode_ == MODE_NAMED_CLIENT) 297 if (mode_ == MODE_NAMED_CLIENT)
298 mode_ = MODE_CLIENT; 298 mode_ = MODE_CLIENT;
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 } 400 }
401 } else { 401 } else {
402 waiting_connect_ = mode == MODE_SERVER; 402 waiting_connect_ = mode == MODE_SERVER;
403 } 403 }
404 } 404 }
405 405
406 // Create the Hello message to be sent when Connect is called 406 // Create the Hello message to be sent when Connect is called
407 scoped_ptr<Message> msg(new Message(MSG_ROUTING_NONE, 407 scoped_ptr<Message> msg(new Message(MSG_ROUTING_NONE,
408 HELLO_MESSAGE_TYPE, 408 HELLO_MESSAGE_TYPE,
409 IPC::Message::PRIORITY_NORMAL)); 409 IPC::Message::PRIORITY_NORMAL));
410 #if !defined(OS_MACOSX) 410 #if defined(IPC_USES_READWRITE)
411 if (!uses_fifo_) { 411 if (!uses_fifo_) {
412 // On Linux, the seccomp sandbox makes it very expensive to call 412 // Create a dedicated socketpair() for exchanging file descriptors.
413 // recvmsg() and sendmsg(). Often, we are perfectly OK with resorting to 413 // See comments for IPC_USES_READWRITE for details.
414 // read() and write(), which are cheap.
415 //
416 // As we cannot anticipate, when the sender will provide us with file
417 // handles, we have to make the decision about whether we call read() or
418 // recvmsg() before we actually make the call. The easiest option is to
419 // create a dedicated socketpair() for exchanging file handles.
420 if (mode == MODE_SERVER) { 414 if (mode == MODE_SERVER) {
421 fd_pipe_ = -1; 415 fd_pipe_ = -1;
422 } else if (remote_fd_pipe_ == -1) { 416 } else if (remote_fd_pipe_ == -1) {
423 if (!SocketPair(&fd_pipe_, &remote_fd_pipe_)) { 417 if (!SocketPair(&fd_pipe_, &remote_fd_pipe_)) {
424 return false; 418 return false;
425 } 419 }
426 } 420 }
427 } 421 }
428 #endif 422 #endif
429 if (!msg->WriteInt(base::GetCurrentProcId())) { 423 if (!msg->WriteInt(base::GetCurrentProcId())) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 for (;;) { 470 for (;;) {
477 msg.msg_iov = &iov; 471 msg.msg_iov = &iov;
478 472
479 if (bytes_read == 0) { 473 if (bytes_read == 0) {
480 if (pipe_ == -1) 474 if (pipe_ == -1)
481 return false; 475 return false;
482 476
483 // Read from pipe. 477 // Read from pipe.
484 // recvmsg() returns 0 if the connection has closed or EAGAIN if no data 478 // recvmsg() returns 0 if the connection has closed or EAGAIN if no data
485 // is waiting on the pipe. 479 // is waiting on the pipe.
486 #if !defined(OS_MACOSX) 480 #if defined(IPC_USES_READWRITE)
487 if (fd_pipe_ >= 0) { 481 if (fd_pipe_ >= 0) {
488 bytes_read = HANDLE_EINTR(read(pipe_, input_buf_, 482 bytes_read = HANDLE_EINTR(read(pipe_, input_buf_,
489 Channel::kReadBufferSize)); 483 Channel::kReadBufferSize));
490 msg.msg_controllen = 0; 484 msg.msg_controllen = 0;
491 } else 485 } else
492 #endif 486 #endif
493 { 487 {
494 msg.msg_controllen = sizeof(input_cmsg_buf_); 488 msg.msg_controllen = sizeof(input_cmsg_buf_);
495 bytes_read = HANDLE_EINTR(recvmsg(pipe_, &msg, MSG_DONTWAIT)); 489 bytes_read = HANDLE_EINTR(recvmsg(pipe_, &msg, MSG_DONTWAIT));
496 } 490 }
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
609 if (message_tail) { 603 if (message_tail) {
610 int len = static_cast<int>(message_tail - p); 604 int len = static_cast<int>(message_tail - p);
611 Message m(p, len); 605 Message m(p, len);
612 606
613 if (m.header()->num_fds) { 607 if (m.header()->num_fds) {
614 // the message has file descriptors 608 // the message has file descriptors
615 const char* error = NULL; 609 const char* error = NULL;
616 if (m.header()->num_fds > num_fds - fds_i) { 610 if (m.header()->num_fds > num_fds - fds_i) {
617 // the message has been completely received, but we didn't get 611 // the message has been completely received, but we didn't get
618 // enough file descriptors. 612 // enough file descriptors.
619 #if !defined(OS_MACOSX) 613 #if defined(IPC_USES_READWRITE)
620 if (!uses_fifo_) { 614 if (!uses_fifo_) {
621 char dummy; 615 char dummy;
622 struct iovec fd_pipe_iov = { &dummy, 1 }; 616 struct iovec fd_pipe_iov = { &dummy, 1 };
623 msg.msg_iov = &fd_pipe_iov; 617 msg.msg_iov = &fd_pipe_iov;
624 msg.msg_controllen = sizeof(input_cmsg_buf_); 618 msg.msg_controllen = sizeof(input_cmsg_buf_);
625 ssize_t n = HANDLE_EINTR(recvmsg(fd_pipe_, &msg, MSG_DONTWAIT)); 619 ssize_t n = HANDLE_EINTR(recvmsg(fd_pipe_, &msg, MSG_DONTWAIT));
626 if (n == 1 && msg.msg_controllen > 0) { 620 if (n == 1 && msg.msg_controllen > 0) {
627 for (struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg); cmsg; 621 for (struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg); cmsg;
628 cmsg = CMSG_NXTHDR(&msg, cmsg)) { 622 cmsg = CMSG_NXTHDR(&msg, cmsg)) {
629 if (cmsg->cmsg_level == SOL_SOCKET && 623 if (cmsg->cmsg_level == SOL_SOCKET &&
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
699 DVLOG(2) << "received message on channel @" << this 693 DVLOG(2) << "received message on channel @" << this
700 << " with type " << m.type(); 694 << " with type " << m.type();
701 if (m.routing_id() == MSG_ROUTING_NONE && 695 if (m.routing_id() == MSG_ROUTING_NONE &&
702 m.type() == HELLO_MESSAGE_TYPE) { 696 m.type() == HELLO_MESSAGE_TYPE) {
703 // The Hello message contains only the process id. 697 // The Hello message contains only the process id.
704 void *iter = NULL; 698 void *iter = NULL;
705 int pid; 699 int pid;
706 if (!m.ReadInt(&iter, &pid)) { 700 if (!m.ReadInt(&iter, &pid)) {
707 NOTREACHED(); 701 NOTREACHED();
708 } 702 }
709 #if !defined(OS_MACOSX) 703 #if defined(IPC_USES_READWRITE)
710 if (mode_ == MODE_SERVER && !uses_fifo_) { 704 if (mode_ == MODE_SERVER && !uses_fifo_) {
711 // On non-Mac, the Hello message from the client to the server 705 // On non-Mac, the Hello message from the client to the server
712 // also contains the fd_pipe_, which will be used for all 706 // also contains the fd_pipe_, which will be used for all
713 // subsequent file descriptor passing. 707 // subsequent file descriptor passing.
714 DCHECK_EQ(m.file_descriptor_set()->size(), 1U); 708 DCHECK_EQ(m.file_descriptor_set()->size(), 1U);
715 base::FileDescriptor descriptor; 709 base::FileDescriptor descriptor;
716 if (!m.ReadFileDescriptor(&iter, &descriptor)) { 710 if (!m.ReadFileDescriptor(&iter, &descriptor)) {
717 NOTREACHED(); 711 NOTREACHED();
718 } 712 }
719 fd_pipe_ = descriptor.fd; 713 fd_pipe_ = descriptor.fd;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
762 756
763 if (pipe_ == -1) { 757 if (pipe_ == -1) {
764 return false; 758 return false;
765 } 759 }
766 760
767 // Write out all the messages we can till the write blocks or there are no 761 // Write out all the messages we can till the write blocks or there are no
768 // more outgoing messages. 762 // more outgoing messages.
769 while (!output_queue_.empty()) { 763 while (!output_queue_.empty()) {
770 Message* msg = output_queue_.front(); 764 Message* msg = output_queue_.front();
771 765
772 #if !defined(OS_MACOSX) 766 #if defined(IPC_USES_READWRITE)
773 scoped_ptr<Message> hello; 767 scoped_ptr<Message> hello;
774 if (remote_fd_pipe_ != -1 && 768 if (remote_fd_pipe_ != -1 &&
775 msg->routing_id() == MSG_ROUTING_NONE && 769 msg->routing_id() == MSG_ROUTING_NONE &&
776 msg->type() == HELLO_MESSAGE_TYPE) { 770 msg->type() == HELLO_MESSAGE_TYPE) {
777 hello.reset(new Message(MSG_ROUTING_NONE, 771 hello.reset(new Message(MSG_ROUTING_NONE,
778 HELLO_MESSAGE_TYPE, 772 HELLO_MESSAGE_TYPE,
779 IPC::Message::PRIORITY_NORMAL)); 773 IPC::Message::PRIORITY_NORMAL));
780 void* iter = NULL; 774 void* iter = NULL;
781 int pid; 775 int pid;
782 if (!msg->ReadInt(&iter, &pid) || 776 if (!msg->ReadInt(&iter, &pid) ||
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
832 cmsg->cmsg_type = SCM_RIGHTS; 826 cmsg->cmsg_type = SCM_RIGHTS;
833 cmsg->cmsg_len = CMSG_LEN(sizeof(int) * num_fds); 827 cmsg->cmsg_len = CMSG_LEN(sizeof(int) * num_fds);
834 msg->file_descriptor_set()->GetDescriptors( 828 msg->file_descriptor_set()->GetDescriptors(
835 reinterpret_cast<int*>(CMSG_DATA(cmsg))); 829 reinterpret_cast<int*>(CMSG_DATA(cmsg)));
836 msgh.msg_controllen = cmsg->cmsg_len; 830 msgh.msg_controllen = cmsg->cmsg_len;
837 831
838 // DCHECK_LE above already checks that 832 // DCHECK_LE above already checks that
839 // num_fds < MAX_DESCRIPTORS_PER_MESSAGE so no danger of overflow. 833 // num_fds < MAX_DESCRIPTORS_PER_MESSAGE so no danger of overflow.
840 msg->header()->num_fds = static_cast<uint16>(num_fds); 834 msg->header()->num_fds = static_cast<uint16>(num_fds);
841 835
842 #if !defined(OS_MACOSX) 836 #if defined(IPC_USES_READWRITE)
843 if (!uses_fifo_ && 837 if (!uses_fifo_ &&
844 (msg->routing_id() != MSG_ROUTING_NONE || 838 (msg->routing_id() != MSG_ROUTING_NONE ||
845 msg->type() != HELLO_MESSAGE_TYPE)) { 839 msg->type() != HELLO_MESSAGE_TYPE)) {
846 // Only the Hello message sends the file descriptor with the message. 840 // Only the Hello message sends the file descriptor with the message.
847 // Subsequently, we can send file descriptors on the dedicated 841 // Subsequently, we can send file descriptors on the dedicated
848 // fd_pipe_ which makes Seccomp sandbox operation more efficient. 842 // fd_pipe_ which makes Seccomp sandbox operation more efficient.
849 struct iovec fd_pipe_iov = { const_cast<char *>(""), 1 }; 843 struct iovec fd_pipe_iov = { const_cast<char *>(""), 1 };
850 msgh.msg_iov = &fd_pipe_iov; 844 msgh.msg_iov = &fd_pipe_iov;
851 fd_written = fd_pipe_; 845 fd_written = fd_pipe_;
852 bytes_written = HANDLE_EINTR(sendmsg(fd_pipe_, &msgh, MSG_DONTWAIT)); 846 bytes_written = HANDLE_EINTR(sendmsg(fd_pipe_, &msgh, MSG_DONTWAIT));
853 msgh.msg_iov = &iov; 847 msgh.msg_iov = &iov;
854 msgh.msg_controllen = 0; 848 msgh.msg_controllen = 0;
855 if (bytes_written > 0) { 849 if (bytes_written > 0) {
856 msg->file_descriptor_set()->CommitAll(); 850 msg->file_descriptor_set()->CommitAll();
857 } 851 }
858 } 852 }
859 #endif 853 #endif
860 } 854 }
861 855
862 if (bytes_written == 1) { 856 if (bytes_written == 1) {
863 fd_written = pipe_; 857 fd_written = pipe_;
864 #if !defined(OS_MACOSX) 858 #if defined(IPC_USES_READWRITE)
865 if (mode_ != MODE_SERVER && !uses_fifo_ && 859 if (mode_ != MODE_SERVER && !uses_fifo_ &&
866 msg->routing_id() == MSG_ROUTING_NONE && 860 msg->routing_id() == MSG_ROUTING_NONE &&
867 msg->type() == HELLO_MESSAGE_TYPE) { 861 msg->type() == HELLO_MESSAGE_TYPE) {
868 DCHECK_EQ(msg->file_descriptor_set()->size(), 1U); 862 DCHECK_EQ(msg->file_descriptor_set()->size(), 1U);
869 } 863 }
870 if (!uses_fifo_ && !msgh.msg_controllen) { 864 if (!uses_fifo_ && !msgh.msg_controllen) {
871 bytes_written = HANDLE_EINTR(write(pipe_, out_bytes, amt_to_write)); 865 bytes_written = HANDLE_EINTR(write(pipe_, out_bytes, amt_to_write));
872 } else 866 } else
873 #endif 867 #endif
874 { 868 {
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
1023 write_watcher_.StopWatchingFileDescriptor(); 1017 write_watcher_.StopWatchingFileDescriptor();
1024 if (pipe_ != -1) { 1018 if (pipe_ != -1) {
1025 if (HANDLE_EINTR(close(pipe_)) < 0) 1019 if (HANDLE_EINTR(close(pipe_)) < 0)
1026 PLOG(ERROR) << "close"; 1020 PLOG(ERROR) << "close";
1027 pipe_ = -1; 1021 pipe_ = -1;
1028 } 1022 }
1029 if (client_pipe_ != -1) { 1023 if (client_pipe_ != -1) {
1030 PipeMap::GetInstance()->RemoveAndClose(pipe_name_); 1024 PipeMap::GetInstance()->RemoveAndClose(pipe_name_);
1031 client_pipe_ = -1; 1025 client_pipe_ = -1;
1032 } 1026 }
1033 #if !defined(OS_MACOSX) 1027 #if defined(IPC_USES_READWRITE)
1034 if (fd_pipe_ != -1) { 1028 if (fd_pipe_ != -1) {
1035 if (HANDLE_EINTR(close(fd_pipe_)) < 0) 1029 if (HANDLE_EINTR(close(fd_pipe_)) < 0)
1036 PLOG(ERROR) << "close"; 1030 PLOG(ERROR) << "close";
1037 fd_pipe_ = -1; 1031 fd_pipe_ = -1;
1038 } 1032 }
1039 if (remote_fd_pipe_ != -1) { 1033 if (remote_fd_pipe_ != -1) {
1040 if (HANDLE_EINTR(close(remote_fd_pipe_)) < 0) 1034 if (HANDLE_EINTR(close(remote_fd_pipe_)) < 0)
1041 PLOG(ERROR) << "close"; 1035 PLOG(ERROR) << "close";
1042 remote_fd_pipe_ = -1; 1036 remote_fd_pipe_ = -1;
1043 } 1037 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1088 1082
1089 bool Channel::Send(Message* message) { 1083 bool Channel::Send(Message* message) {
1090 return channel_impl_->Send(message); 1084 return channel_impl_->Send(message);
1091 } 1085 }
1092 1086
1093 int Channel::GetClientFileDescriptor() const { 1087 int Channel::GetClientFileDescriptor() const {
1094 return channel_impl_->GetClientFileDescriptor(); 1088 return channel_impl_->GetClientFileDescriptor();
1095 } 1089 }
1096 1090
1097 } // namespace IPC 1091 } // 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