| Index: mojo/shell/incoming_connection_listener_posix.cc
|
| diff --git a/mojo/shell/incoming_connection_listener_posix.cc b/mojo/shell/incoming_connection_listener_posix.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..820917b8da5bc79be290bbfaea1a6b836e4af3c1
|
| --- /dev/null
|
| +++ b/mojo/shell/incoming_connection_listener_posix.cc
|
| @@ -0,0 +1,103 @@
|
| +// Copyright 2014 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 "mojo/shell/incoming_connection_listener_posix.h"
|
| +
|
| +#include "base/callback.h"
|
| +#include "base/files/file_path.h"
|
| +#include "base/files/file_util.h"
|
| +#include "base/logging.h"
|
| +#include "base/memory/scoped_ptr.h"
|
| +#include "base/sequenced_task_runner.h"
|
| +#include "base/tracked_objects.h"
|
| +#include "net/base/net_errors.h"
|
| +#include "net/socket/socket_descriptor.h"
|
| +#include "net/socket/unix_domain_server_socket_posix.h"
|
| +
|
| +namespace mojo {
|
| +namespace shell {
|
| +
|
| +namespace {
|
| +// TODO(cmasone): Figure out what we should be doing about "authenticating" the
|
| +// process trying to connect.
|
| +bool Yes(const net::UnixDomainServerSocket::Credentials& ignored) {
|
| + return true;
|
| +}
|
| +} // anonymous namespace
|
| +
|
| +IncomingConnectionListenerPosix::IncomingConnectionListenerPosix(
|
| + const base::FilePath& socket_path,
|
| + Delegate* delegate)
|
| + : delegate_(delegate),
|
| + socket_path_(socket_path),
|
| + listen_socket_(base::Bind(&Yes), false),
|
| + incoming_socket_(net::kInvalidSocket),
|
| + weak_ptr_factory_(this) {
|
| + DCHECK(delegate_);
|
| +}
|
| +
|
| +IncomingConnectionListenerPosix::~IncomingConnectionListenerPosix() {
|
| + weak_ptr_factory_.InvalidateWeakPtrs();
|
| + if (!base::DeleteFile(socket_path_, false))
|
| + PLOG(ERROR) << "Listening Unix domain socket can't be destroyed.";
|
| +}
|
| +
|
| +void IncomingConnectionListenerPosix::StartListening() {
|
| + DCHECK(listen_thread_checker_.CalledOnValidThread());
|
| +
|
| + int rv = net::OK;
|
| + if (base::PathExists(socket_path_)) {
|
| + LOG(ERROR) << "Listening socket file already exists.";
|
| + rv = net::ERR_FILE_EXISTS;
|
| + } else if (!base::DirectoryExists(socket_path_.DirName())) {
|
| + LOG(ERROR) << "Directorty for listening socket does not exist.";
|
| + rv = net::ERR_FILE_NOT_FOUND;
|
| + } else if (!base::PathIsWritable(socket_path_.DirName())) {
|
| + LOG(ERROR) << "Listening socket file path is not writable.";
|
| + rv = net::ERR_ACCESS_DENIED;
|
| + } else {
|
| + const std::string& socket_address = socket_path_.value();
|
| + rv = listen_socket_.ListenWithAddressAndPort(socket_address, 0, 100);
|
| + }
|
| +
|
| + // Call OnListening() before Accept(), so that the delegate is certain to
|
| + // hear about listening before a connection might be accepted below.
|
| + delegate_->OnListening(rv);
|
| + if (rv == net::OK)
|
| + Accept();
|
| +}
|
| +
|
| +void IncomingConnectionListenerPosix::Accept() {
|
| + DCHECK(listen_thread_checker_.CalledOnValidThread());
|
| + int rv = listen_socket_.AcceptSocketDescriptor(
|
| + &incoming_socket_,
|
| + base::Bind(&IncomingConnectionListenerPosix::OnAccept,
|
| + weak_ptr_factory_.GetWeakPtr()));
|
| +
|
| + // If rv == net::ERR_IO_PENDING), listen_socket_ will call
|
| + // OnAccept() later, when a connection attempt comes in.
|
| + if (rv != net::ERR_IO_PENDING) {
|
| + DVLOG_IF(1, rv == net::OK) << "Accept succeeded immediately";
|
| + OnAccept(rv);
|
| + }
|
| +}
|
| +
|
| +void IncomingConnectionListenerPosix::OnAccept(int rv) {
|
| + DCHECK(listen_thread_checker_.CalledOnValidThread());
|
| +
|
| + if (rv != net::OK || incoming_socket_ == net::kInvalidSocket) {
|
| + LOG_IF(ERROR, rv != net::OK) << "Accept failed " << net::ErrorToString(rv);
|
| + PLOG_IF(ERROR, rv == net::OK) << "Socket invalid";
|
| + } else {
|
| + // Passes ownership of incoming_socket_ to delegate_.
|
| + delegate_->OnConnection(incoming_socket_);
|
| + incoming_socket_ = net::kInvalidSocket;
|
| + }
|
| +
|
| + // Continue waiting to accept incoming connections...
|
| + Accept();
|
| +}
|
| +
|
| +} // namespace shell
|
| +} // namespace mojo
|
|
|