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
3 // found in the LICENSE file.
5 #ifndef IPC_IPC_CHANNEL_POSIX_H_
6 #define IPC_IPC_CHANNEL_POSIX_H_
8 #include "ipc/ipc_channel.h"
10 #include <sys/socket.h> // for CMSG macros
17 #include "base/files/scoped_file.h"
18 #include "base/message_loop/message_loop.h"
19 #include "base/process/process.h"
20 #include "ipc/ipc_channel_reader.h"
21 #include "ipc/ipc_message_attachment_set.h"
25 class IPC_EXPORT ChannelPosix
: public Channel
,
26 public internal::ChannelReader
,
27 public base::MessageLoopForIO::Watcher
{
29 ChannelPosix(const IPC::ChannelHandle
& channel_handle
, Mode mode
,
31 ~ChannelPosix() override
;
33 // Channel implementation
34 bool Connect() override
;
35 void Close() override
;
36 bool Send(Message
* message
) override
;
37 base::ProcessId
GetPeerPID() const override
;
38 base::ProcessId
GetSelfPID() const override
;
39 int GetClientFileDescriptor() const override
;
40 base::ScopedFD
TakeClientFileDescriptor() override
;
42 // Returns true if the channel supports listening for connections.
43 bool AcceptsConnections() const;
45 // Returns true if the channel supports listening for connections and is
46 // currently connected.
47 bool HasAcceptedConnection() const;
49 // Closes any currently connected socket, and returns to a listening state
50 // for more connections.
51 void ResetToAcceptingConnectionState();
53 // Returns true if the peer process' effective user id can be determined, in
54 // which case the supplied peer_euid is updated with it.
55 bool GetPeerEuid(uid_t
* peer_euid
) const;
57 void CloseClientFileDescriptor();
59 static bool IsNamedServerInitialized(const std::string
& channel_id
);
61 static void SetGlobalPid(int pid
);
65 bool CreatePipe(const IPC::ChannelHandle
& channel_handle
);
67 bool ProcessOutgoingMessages();
69 bool AcceptConnection();
70 void ClosePipeOnError();
71 int GetHelloMessageProcId() const;
72 void QueueHelloMessage();
73 void CloseFileDescriptors(Message
* msg
);
74 void QueueCloseFDMessage(int fd
, int hops
);
76 // ChannelReader implementation.
77 ReadState
ReadData(char* buffer
, int buffer_len
, int* bytes_read
) override
;
78 bool WillDispatchInputMessage(Message
* msg
) override
;
79 bool DidEmptyInputBuffers() override
;
80 void HandleInternalMessage(const Message
& msg
) override
;
82 // Finds the set of file descriptors in the given message. On success,
83 // appends the descriptors to the input_fds_ member and returns true
85 // Returns false if the message was truncated. In this case, any handles that
86 // were sent will be closed.
87 bool ExtractFileDescriptorsFromMsghdr(msghdr
* msg
);
89 // Closes all handles in the input_fds_ list and clears the list. This is
90 // used to clean up handles in error conditions to avoid leaking the handles.
93 // MessageLoopForIO::Watcher implementation.
94 void OnFileCanReadWithoutBlocking(int fd
) override
;
95 void OnFileCanWriteWithoutBlocking(int fd
) override
;
99 base::ProcessId peer_pid_
;
101 // After accepting one client connection on our server socket we want to
103 base::MessageLoopForIO::FileDescriptorWatcher
104 server_listen_connection_watcher_
;
105 base::MessageLoopForIO::FileDescriptorWatcher read_watcher_
;
106 base::MessageLoopForIO::FileDescriptorWatcher write_watcher_
;
108 // Indicates whether we're currently blocked waiting for a write to complete.
109 bool is_blocked_on_write_
;
110 bool waiting_connect_
;
112 // If sending a message blocks then we use this variable
113 // to keep track of where we are.
114 size_t message_send_bytes_written_
;
116 // File descriptor we're listening on for new connections if we listen
118 base::ScopedFD server_listen_pipe_
;
120 // The pipe used for communication.
121 base::ScopedFD pipe_
;
123 // For a server, the client end of our socketpair() -- the other end of our
124 // pipe_ that is passed to the client.
125 base::ScopedFD client_pipe_
;
126 mutable base::Lock client_pipe_lock_
; // Lock that protects |client_pipe_|.
128 // The "name" of our pipe. On Windows this is the global identifier for
129 // the pipe. On POSIX it's used as a key in a local map of file descriptors.
130 std::string pipe_name_
;
132 // Messages to be sent are queued here.
133 std::queue
<Message
*> output_queue_
;
135 // We assume a worst case: kReadBufferSize bytes of messages, where each
136 // message has no payload and a full complement of descriptors.
137 static const size_t kMaxReadFDs
=
138 (Channel::kReadBufferSize
/ sizeof(IPC::Message::Header
)) *
139 MessageAttachmentSet::kMaxDescriptorsPerMessage
;
141 // Buffer size for file descriptors used for recvmsg. On Mac the CMSG macros
142 // don't seem to be constant so we have to pick a "large enough" value.
143 #if defined(OS_MACOSX)
144 static const size_t kMaxReadFDBuffer
= 1024;
146 static const size_t kMaxReadFDBuffer
= CMSG_SPACE(sizeof(int) * kMaxReadFDs
);
149 // Temporary buffer used to receive the file descriptors from recvmsg.
150 // Code that writes into this should immediately read them out and save
151 // them to input_fds_, since this buffer will be re-used anytime we call
153 char input_cmsg_buf_
[kMaxReadFDBuffer
];
155 // File descriptors extracted from messages coming off of the channel. The
156 // handles may span messages and come off different channels from the message
157 // data (in the case of READWRITE), and are processed in FIFO here.
158 // NOTE: The implementation assumes underlying storage here is contiguous, so
159 // don't change to something like std::deque<> without changing the
161 std::vector
<int> input_fds_
;
164 void ResetSafely(base::ScopedFD
* fd
);
167 #if defined(OS_MACOSX)
168 // On OSX, sent FDs must not be closed until we get an ack.
169 // Keep track of sent FDs here to make sure the remote is not
170 // trying to bamboozle us.
171 std::set
<int> fds_to_close_
;
174 // True if we are responsible for unlinking the unix domain socket file.
177 #if defined(OS_LINUX)
178 // If non-zero, overrides the process ID sent in the hello message.
179 static int global_pid_
;
182 DISALLOW_IMPLICIT_CONSTRUCTORS(ChannelPosix
);
187 #endif // IPC_IPC_CHANNEL_POSIX_H_