| // Copyright 2016 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 "components/arc/standalone/service_helper.h" |
| |
| #include "base/files/file_util.h" |
| #include "base/logging.h" |
| #include "base/message_loop/message_loop.h" |
| #include "base/posix/eintr_wrapper.h" |
| |
| namespace arc { |
| |
| // static |
| ServiceHelper* ServiceHelper::self_ = nullptr; |
| |
| ServiceHelper::ServiceHelper() { |
| } |
| |
| ServiceHelper::~ServiceHelper() { |
| // Best efforts clean up, ignore the return values. |
| sigaction(SIGINT, &old_sigint_, NULL); |
| sigaction(SIGTERM, &old_sigterm_, NULL); |
| } |
| |
| void ServiceHelper::Init(const base::Closure& closure) { |
| CHECK(!ServiceHelper::self_); |
| ServiceHelper::self_ = this; |
| closure_ = closure; |
| |
| // Initialize pipe |
| int pipe_fd[2]; |
| CHECK_EQ(0, pipe(pipe_fd)); |
| read_fd_.reset(pipe_fd[0]); |
| write_fd_.reset(pipe_fd[1]); |
| CHECK(base::SetNonBlocking(write_fd_.get())); |
| CHECK(base::MessageLoopForIO::current()->WatchFileDescriptor( |
| read_fd_.get(), |
| true, /* persistent */ |
| base::MessageLoopForIO::WATCH_READ, |
| &watcher_, |
| this)); |
| |
| struct sigaction action = {}; |
| CHECK_EQ(0, sigemptyset(&action.sa_mask)); |
| action.sa_handler = ServiceHelper::TerminationHandler; |
| action.sa_flags = 0; |
| |
| CHECK_EQ(0, sigaction(SIGINT, &action, &old_sigint_)); |
| CHECK_EQ(0, sigaction(SIGTERM, &action, &old_sigterm_)); |
| } |
| |
| // static |
| void ServiceHelper::TerminationHandler(int /* signum */) { |
| if (HANDLE_EINTR(write(self_->write_fd_.get(), "1", 1)) < 0) { |
| _exit(2); // We still need to exit the program, but in a brute force way. |
| } |
| } |
| |
| void ServiceHelper::OnFileCanReadWithoutBlocking(int fd) { |
| CHECK_EQ(read_fd_.get(), fd); |
| |
| char c; |
| // We don't really care about the return value, since it indicates closing. |
| HANDLE_EINTR(read(read_fd_.get(), &c, 1)); |
| closure_.Run(); |
| } |
| |
| void ServiceHelper::OnFileCanWriteWithoutBlocking(int fd) { |
| NOTREACHED(); |
| } |
| |
| } // namespace arc |