| // Copyright 2013 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "remoting/host/ipc_util.h" |
| |
| #include <fcntl.h> |
| #include <sys/socket.h> |
| #include <sys/types.h> |
| #include <unistd.h> |
| |
| #include "base/files/file.h" |
| #include "base/logging.h" |
| #include "base/posix/eintr_wrapper.h" |
| #include "base/single_thread_task_runner.h" |
| #include "ipc/ipc_channel.h" |
| #include "ipc/ipc_channel_proxy.h" |
| |
| namespace remoting { |
| |
| bool CreateConnectedIpcChannel( |
| scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, |
| IPC::Listener* listener, |
| base::File* client_out, |
| scoped_ptr<IPC::ChannelProxy>* server_out) { |
| // Create a socket pair. |
| int pipe_fds[2]; |
| if (socketpair(AF_UNIX, SOCK_STREAM, 0, pipe_fds) != 0) { |
| PLOG(ERROR) << "socketpair()"; |
| return false; |
| } |
| |
| // Set both ends to be non-blocking. |
| if (fcntl(pipe_fds[0], F_SETFL, O_NONBLOCK) == -1 || |
| fcntl(pipe_fds[1], F_SETFL, O_NONBLOCK) == -1) { |
| PLOG(ERROR) << "fcntl(O_NONBLOCK)"; |
| if (IGNORE_EINTR(close(pipe_fds[0])) < 0) |
| PLOG(ERROR) << "close()"; |
| if (IGNORE_EINTR(close(pipe_fds[1])) < 0) |
| PLOG(ERROR) << "close()"; |
| return false; |
| } |
| |
| std::string socket_name = "Chromoting socket"; |
| |
| // Wrap the pipe into an IPC channel. |
| base::FileDescriptor fd(pipe_fds[0], false); |
| IPC::ChannelHandle handle(socket_name, fd); |
| *server_out = IPC::ChannelProxy::Create(IPC::ChannelHandle(socket_name, fd), |
| IPC::Channel::MODE_SERVER, |
| listener, |
| io_task_runner.get()); |
| |
| *client_out = base::File(pipe_fds[1]); |
| return true; |
| } |
| |
| } // namespace remoting |