diff options
author | morrita@chromium.org <morrita@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-07-18 22:44:10 +0000 |
---|---|---|
committer | morrita@chromium.org <morrita@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-07-18 22:44:10 +0000 |
commit | d9674614bfd88227209c54849aaeedccdedd0b84 (patch) | |
tree | be2a438fde0cb36646fe0d4dab2bded68f107bcc /apps | |
parent | 6d9e0587c46c5b6d0218bc40590798c9942b2313 (diff) | |
download | chromium_src-d9674614bfd88227209c54849aaeedccdedd0b84.zip chromium_src-d9674614bfd88227209c54849aaeedccdedd0b84.tar.gz chromium_src-d9674614bfd88227209c54849aaeedccdedd0b84.tar.bz2 |
Rename IPC::ChannelFactory to UnixDomainSocketAcceptor.
ChannelFactory doesn't create any channel and it just listens on
and accepts from a unix socket. So this change renames it to
represent what it actually does.
R=darin@chromium.org,cpu@chromium.org,jeremya@chromium.org,tapted@chromium.org
TEST=none
BUG=377980
Review URL: https://codereview.chromium.org/305973002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@284231 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'apps')
-rw-r--r-- | apps/app_shim/app_shim.gypi | 2 | ||||
-rw-r--r-- | apps/app_shim/app_shim_host_mac.h | 4 | ||||
-rw-r--r-- | apps/app_shim/app_shim_host_manager_browsertest_mac.mm | 4 | ||||
-rw-r--r-- | apps/app_shim/app_shim_host_manager_mac.h | 18 | ||||
-rw-r--r-- | apps/app_shim/app_shim_host_manager_mac.mm | 12 | ||||
-rw-r--r-- | apps/app_shim/test/app_shim_host_manager_test_api_mac.cc | 4 | ||||
-rw-r--r-- | apps/app_shim/test/app_shim_host_manager_test_api_mac.h | 6 | ||||
-rw-r--r-- | apps/app_shim/unix_domain_socket_acceptor.cc | 90 | ||||
-rw-r--r-- | apps/app_shim/unix_domain_socket_acceptor.h | 57 |
9 files changed, 173 insertions, 24 deletions
diff --git a/apps/app_shim/app_shim.gypi b/apps/app_shim/app_shim.gypi index b08e698..51a729a 100644 --- a/apps/app_shim/app_shim.gypi +++ b/apps/app_shim/app_shim.gypi @@ -28,6 +28,8 @@ 'chrome_main_app_mode_mac.mm', 'extension_app_shim_handler_mac.cc', 'extension_app_shim_handler_mac.h', + 'unix_domain_socket_acceptor.cc', + 'unix_domain_socket_acceptor.h', ], }, ], # targets diff --git a/apps/app_shim/app_shim_host_mac.h b/apps/app_shim/app_shim_host_mac.h index 606ea87..63828f7 100644 --- a/apps/app_shim/app_shim_host_mac.h +++ b/apps/app_shim/app_shim_host_mac.h @@ -34,8 +34,8 @@ class AppShimHost : public IPC::Listener, virtual ~AppShimHost(); // Creates a new server-side IPC channel at |handle|, which should contain a - // file descriptor of a channel created by an IPC::ChannelFactory, and begins - // listening for messages on it. + // file descriptor of a channel created by an UnixDomainSocketAcceptor, + // and begins listening for messages on it. void ServeChannel(const IPC::ChannelHandle& handle); protected: diff --git a/apps/app_shim/app_shim_host_manager_browsertest_mac.mm b/apps/app_shim/app_shim_host_manager_browsertest_mac.mm index efd2278..3e92cbf 100644 --- a/apps/app_shim/app_shim_host_manager_browsertest_mac.mm +++ b/apps/app_shim/app_shim_host_manager_browsertest_mac.mm @@ -205,7 +205,7 @@ IN_PROC_BROWSER_TEST_F(AppShimHostManagerBrowserTest, PRE_ReCreate) { test::AppShimHostManagerTestApi test_api( g_browser_process->platform_part()->app_shim_host_manager()); - EXPECT_TRUE(test_api.factory()); + EXPECT_TRUE(test_api.acceptor()); } // Ensure the domain socket can be re-created after a prior browser process has @@ -214,7 +214,7 @@ IN_PROC_BROWSER_TEST_F(AppShimHostManagerBrowserTest, ReCreate) { test::AppShimHostManagerTestApi test_api( g_browser_process->platform_part()->app_shim_host_manager()); - EXPECT_TRUE(test_api.factory()); + EXPECT_TRUE(test_api.acceptor()); } // Tests for the files created by AppShimHostManager. diff --git a/apps/app_shim/app_shim_host_manager_mac.h b/apps/app_shim/app_shim_host_manager_mac.h index 0e3a9d2..037c4f2 100644 --- a/apps/app_shim/app_shim_host_manager_mac.h +++ b/apps/app_shim/app_shim_host_manager_mac.h @@ -6,9 +6,9 @@ #define APPS_APP_SHIM_APP_SHIM_HOST_MANAGER_MAC_H_ #include "apps/app_shim/extension_app_shim_handler_mac.h" +#include "apps/app_shim/unix_domain_socket_acceptor.h" #include "base/memory/ref_counted.h" #include "content/public/browser/browser_thread.h" -#include "ipc/ipc_channel_factory.h" namespace base { class FilePath; @@ -19,11 +19,11 @@ class AppShimHostManagerTestApi; } // The AppShimHostManager receives connections from app shims on a UNIX -// socket (|factory_|) and creates a helper object to manage the connection. -class AppShimHostManager - : public IPC::ChannelFactory::Delegate, - public base::RefCountedThreadSafe< - AppShimHostManager, content::BrowserThread::DeleteOnUIThread> { +// socket (|acceptor_|) and creates a helper object to manage the connection. +class AppShimHostManager : public apps::UnixDomainSocketAcceptor::Delegate, + public base::RefCountedThreadSafe< + AppShimHostManager, + content::BrowserThread::DeleteOnUIThread> { public: AppShimHostManager(); @@ -44,11 +44,11 @@ class AppShimHostManager friend class test::AppShimHostManagerTestApi; virtual ~AppShimHostManager(); - // IPC::ChannelFactory::Delegate implementation. + // UnixDomainSocketAcceptor::Delegate implementation. virtual void OnClientConnected(const IPC::ChannelHandle& handle) OVERRIDE; virtual void OnListenError() OVERRIDE; - // The |factory_| must be created on a thread which allows blocking I/O, so + // The |acceptor_| must be created on a thread which allows blocking I/O, so // part of the initialization of this class must be carried out on the file // thread. void InitOnFileThread(); @@ -63,7 +63,7 @@ class AppShimHostManager base::FilePath directory_in_tmp_; - scoped_ptr<IPC::ChannelFactory> factory_; + scoped_ptr<apps::UnixDomainSocketAcceptor> acceptor_; apps::ExtensionAppShimHandler extension_app_shim_handler_; diff --git a/apps/app_shim/app_shim_host_manager_mac.mm b/apps/app_shim/app_shim_host_manager_mac.mm index 769b166..799d32d 100644 --- a/apps/app_shim/app_shim_host_manager_mac.mm +++ b/apps/app_shim/app_shim_host_manager_mac.mm @@ -64,7 +64,7 @@ void AppShimHostManager::Init() { } AppShimHostManager::~AppShimHostManager() { - factory_.reset(); + acceptor_.reset(); if (!did_init_) return; @@ -105,10 +105,10 @@ void AppShimHostManager::InitOnFileThread() { return; } - // IPC::ChannelFactory creates the socket immediately. + // UnixDomainSocketAcceptor creates the socket immediately. base::FilePath socket_path = directory_in_tmp_.Append(app_mode::kAppShimSocketShortName); - factory_.reset(new IPC::ChannelFactory(socket_path, this)); + acceptor_.reset(new apps::UnixDomainSocketAcceptor(socket_path, this)); // Create a symlink to the socket in the user data dir. This lets the shim // process started from Finder find the actual socket path by following the @@ -125,7 +125,7 @@ void AppShimHostManager::InitOnFileThread() { void AppShimHostManager::ListenOnIOThread() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - if (!factory_->Listen()) { + if (!acceptor_->Listen()) { BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, base::Bind(&AppShimHostManager::OnListenError, this)); @@ -142,7 +142,7 @@ void AppShimHostManager::OnClientConnected( void AppShimHostManager::OnListenError() { // TODO(tapted): Set a timeout and attempt to reconstruct the channel. Until - // cases where the error could occur are better known, just reset the factory + // cases where the error could occur are better known, just reset the acceptor // to allow failure to be communicated via the test API. - factory_.reset(); + acceptor_.reset(); } diff --git a/apps/app_shim/test/app_shim_host_manager_test_api_mac.cc b/apps/app_shim/test/app_shim_host_manager_test_api_mac.cc index 67c6544..6fbdd8c 100644 --- a/apps/app_shim/test/app_shim_host_manager_test_api_mac.cc +++ b/apps/app_shim/test/app_shim_host_manager_test_api_mac.cc @@ -15,8 +15,8 @@ AppShimHostManagerTestApi::AppShimHostManagerTestApi( DCHECK(host_manager_); } -IPC::ChannelFactory* AppShimHostManagerTestApi::factory() { - return host_manager_->factory_.get(); +apps::UnixDomainSocketAcceptor* AppShimHostManagerTestApi::acceptor() { + return host_manager_->acceptor_.get(); } const base::FilePath& AppShimHostManagerTestApi::directory_in_tmp() { diff --git a/apps/app_shim/test/app_shim_host_manager_test_api_mac.h b/apps/app_shim/test/app_shim_host_manager_test_api_mac.h index c6851666..b42e389 100644 --- a/apps/app_shim/test/app_shim_host_manager_test_api_mac.h +++ b/apps/app_shim/test/app_shim_host_manager_test_api_mac.h @@ -13,8 +13,8 @@ namespace base { class FilePath; } -namespace IPC { -class ChannelFactory; +namespace apps { +class UnixDomainSocketAcceptor; } namespace test { @@ -23,7 +23,7 @@ class AppShimHostManagerTestApi { public: explicit AppShimHostManagerTestApi(AppShimHostManager* host_manager); - IPC::ChannelFactory* factory(); + apps::UnixDomainSocketAcceptor* acceptor(); const base::FilePath& directory_in_tmp(); diff --git a/apps/app_shim/unix_domain_socket_acceptor.cc b/apps/app_shim/unix_domain_socket_acceptor.cc new file mode 100644 index 0000000..f837a16 --- /dev/null +++ b/apps/app_shim/unix_domain_socket_acceptor.cc @@ -0,0 +1,90 @@ +// 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 "apps/app_shim/unix_domain_socket_acceptor.h" + +#include "base/file_util.h" +#include "base/files/scoped_file.h" +#include "base/logging.h" +#include "ipc/unix_domain_socket_util.h" + +namespace apps { + +UnixDomainSocketAcceptor::UnixDomainSocketAcceptor(const base::FilePath& path, + Delegate* delegate) + : path_(path), delegate_(delegate), listen_fd_(-1) { + DCHECK(delegate_); + CreateSocket(); +} + +UnixDomainSocketAcceptor::~UnixDomainSocketAcceptor() { + Close(); +} + +bool UnixDomainSocketAcceptor::CreateSocket() { + DCHECK(listen_fd_ < 0); + + // Create the socket. + return IPC::CreateServerUnixDomainSocket(path_, &listen_fd_); +} + +bool UnixDomainSocketAcceptor::Listen() { + if (listen_fd_ < 0) + return false; + + // Watch the fd for connections, and turn any connections into + // active sockets. + base::MessageLoopForIO::current()->WatchFileDescriptor( + listen_fd_, + true, + base::MessageLoopForIO::WATCH_READ, + &server_listen_connection_watcher_, + this); + return true; +} + +// Called by libevent when we can read from the fd without blocking. +void UnixDomainSocketAcceptor::OnFileCanReadWithoutBlocking(int fd) { + DCHECK(fd == listen_fd_); + int new_fd = -1; + if (!IPC::ServerAcceptConnection(listen_fd_, &new_fd)) { + Close(); + delegate_->OnListenError(); + return; + } + base::ScopedFD scoped_fd(new_fd); + + if (!scoped_fd.is_valid()) { + // The accept() failed, but not in such a way that the factory needs to be + // shut down. + return; + } + + // Verify that the IPC channel peer is running as the same user. + if (!IPC::IsPeerAuthorized(scoped_fd.get())) + return; + + IPC::ChannelHandle handle(std::string(), + base::FileDescriptor(scoped_fd.release(), true)); + delegate_->OnClientConnected(handle); +} + +void UnixDomainSocketAcceptor::OnFileCanWriteWithoutBlocking(int fd) { + NOTREACHED() << "Listen fd should never be writable."; +} + +void UnixDomainSocketAcceptor::Close() { + if (listen_fd_ < 0) + return; + if (IGNORE_EINTR(close(listen_fd_)) < 0) + PLOG(ERROR) << "close"; + listen_fd_ = -1; + if (unlink(path_.value().c_str()) < 0) + PLOG(ERROR) << "unlink"; + + // Unregister libevent for the listening socket and close it. + server_listen_connection_watcher_.StopWatchingFileDescriptor(); +} + +} // namespace apps diff --git a/apps/app_shim/unix_domain_socket_acceptor.h b/apps/app_shim/unix_domain_socket_acceptor.h new file mode 100644 index 0000000..64ee306 --- /dev/null +++ b/apps/app_shim/unix_domain_socket_acceptor.h @@ -0,0 +1,57 @@ +// 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. + +#ifndef APPS_APP_SHIM_UNIX_DOMAIN_SOCKET_ACCEPTOR_H_ +#define APPS_APP_SHIM_UNIX_DOMAIN_SOCKET_ACCEPTOR_H_ + +#include "base/files/file_path.h" +#include "base/message_loop/message_loop.h" +#include "ipc/ipc_channel_handle.h" + +namespace apps { + +// A UnixDomainSocketAcceptor listens on a UNIX domain socket. When a +// client connects to the socket, it accept()s the connection and +// passes the new FD to the delegate. The delegate is then responsible +// for creating a new IPC::Channel for the FD. +class UnixDomainSocketAcceptor : public base::MessageLoopForIO::Watcher { + public: + class Delegate { + public: + // Called when a client connects to the factory. It is the delegate's + // responsibility to create an IPC::Channel for the handle, or else close + // the file descriptor contained therein. + virtual void OnClientConnected(const IPC::ChannelHandle& handle) = 0; + + // Called when an error occurs and the channel is closed. + virtual void OnListenError() = 0; + }; + + UnixDomainSocketAcceptor(const base::FilePath& path, Delegate* delegate); + + virtual ~UnixDomainSocketAcceptor(); + + // Call this to start listening on the socket. + bool Listen(); + + // Close and unlink the socket, and stop accepting connections. + void Close(); + + private: + bool CreateSocket(); + virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE; + virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE; + + base::MessageLoopForIO::FileDescriptorWatcher + server_listen_connection_watcher_; + base::FilePath path_; + Delegate* delegate_; + int listen_fd_; + + DISALLOW_COPY_AND_ASSIGN(UnixDomainSocketAcceptor); +}; + +} // namespace apps + +#endif // APPS_APP_SHIM_UNIX_DOMAIN_SOCKET_ACCEPTOR_H_ |