| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "tools/android/forwarder2/daemon.h" | 5 #include "tools/android/forwarder2/daemon.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <fcntl.h> | 8 #include <fcntl.h> |
| 9 #include <signal.h> | 9 #include <signal.h> |
| 10 #include <string.h> | 10 #include <string.h> |
| 11 #include <sys/file.h> | 11 #include <sys/file.h> |
| 12 #include <sys/stat.h> | 12 #include <sys/stat.h> |
| 13 #include <sys/types.h> | 13 #include <sys/types.h> |
| 14 #include <sys/wait.h> | 14 #include <sys/wait.h> |
| 15 #include <unistd.h> | 15 #include <unistd.h> |
| 16 |
| 16 #include <cstdlib> | 17 #include <cstdlib> |
| 17 #include <cstring> | 18 #include <cstring> |
| 19 #include <memory> |
| 18 #include <string> | 20 #include <string> |
| 19 #include <utility> | 21 #include <utility> |
| 20 | 22 |
| 21 #include "base/files/file_path.h" | 23 #include "base/files/file_path.h" |
| 22 #include "base/files/file_util.h" | 24 #include "base/files/file_util.h" |
| 23 #include "base/logging.h" | 25 #include "base/logging.h" |
| 24 #include "base/memory/scoped_ptr.h" | |
| 25 #include "base/posix/eintr_wrapper.h" | 26 #include "base/posix/eintr_wrapper.h" |
| 26 #include "base/strings/string_number_conversions.h" | 27 #include "base/strings/string_number_conversions.h" |
| 27 #include "base/strings/stringprintf.h" | 28 #include "base/strings/stringprintf.h" |
| 28 #include "tools/android/forwarder2/common.h" | 29 #include "tools/android/forwarder2/common.h" |
| 29 #include "tools/android/forwarder2/socket.h" | 30 #include "tools/android/forwarder2/socket.h" |
| 30 | 31 |
| 31 namespace forwarder2 { | 32 namespace forwarder2 { |
| 32 namespace { | 33 namespace { |
| 33 | 34 |
| 34 const int kBufferSize = 256; | 35 const int kBufferSize = 256; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 46 settings.log_file = log_file.c_str(); | 47 settings.log_file = log_file.c_str(); |
| 47 settings.lock_log = logging::DONT_LOCK_LOG_FILE; | 48 settings.lock_log = logging::DONT_LOCK_LOG_FILE; |
| 48 CHECK(logging::InitLogging(settings)); | 49 CHECK(logging::InitLogging(settings)); |
| 49 } | 50 } |
| 50 | 51 |
| 51 bool RunServerAcceptLoop(const std::string& welcome_message, | 52 bool RunServerAcceptLoop(const std::string& welcome_message, |
| 52 Socket* server_socket, | 53 Socket* server_socket, |
| 53 Daemon::ServerDelegate* server_delegate) { | 54 Daemon::ServerDelegate* server_delegate) { |
| 54 bool failed = false; | 55 bool failed = false; |
| 55 for (;;) { | 56 for (;;) { |
| 56 scoped_ptr<Socket> client_socket(new Socket()); | 57 std::unique_ptr<Socket> client_socket(new Socket()); |
| 57 if (!server_socket->Accept(client_socket.get())) { | 58 if (!server_socket->Accept(client_socket.get())) { |
| 58 if (server_socket->DidReceiveEvent()) | 59 if (server_socket->DidReceiveEvent()) |
| 59 break; | 60 break; |
| 60 PError("Accept()"); | 61 PError("Accept()"); |
| 61 failed = true; | 62 failed = true; |
| 62 break; | 63 break; |
| 63 } | 64 } |
| 64 if (!client_socket->Write(welcome_message.c_str(), | 65 if (!client_socket->Write(welcome_message.c_str(), |
| 65 welcome_message.length() + 1)) { | 66 welcome_message.length() + 1)) { |
| 66 PError("Write()"); | 67 PError("Write()"); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 90 string_builder.Append("Daemon (pid=%d) died unexpectedly with ", child_pid); | 91 string_builder.Append("Daemon (pid=%d) died unexpectedly with ", child_pid); |
| 91 if (WIFEXITED(status)) | 92 if (WIFEXITED(status)) |
| 92 string_builder.Append("status %d.", WEXITSTATUS(status)); | 93 string_builder.Append("status %d.", WEXITSTATUS(status)); |
| 93 else if (WIFSIGNALED(status)) | 94 else if (WIFSIGNALED(status)) |
| 94 string_builder.Append("signal %d.", WTERMSIG(status)); | 95 string_builder.Append("signal %d.", WTERMSIG(status)); |
| 95 else | 96 else |
| 96 string_builder.Append("unknown reason."); | 97 string_builder.Append("unknown reason."); |
| 97 SIGNAL_SAFE_LOG(ERROR, string_builder.buffer()); | 98 SIGNAL_SAFE_LOG(ERROR, string_builder.buffer()); |
| 98 } | 99 } |
| 99 | 100 |
| 100 scoped_ptr<Socket> ConnectToUnixDomainSocket( | 101 std::unique_ptr<Socket> ConnectToUnixDomainSocket( |
| 101 const std::string& socket_name, | 102 const std::string& socket_name, |
| 102 int tries_count, | 103 int tries_count, |
| 103 int idle_time_msec, | 104 int idle_time_msec, |
| 104 const std::string& expected_welcome_message) { | 105 const std::string& expected_welcome_message) { |
| 105 for (int i = 0; i < tries_count; ++i) { | 106 for (int i = 0; i < tries_count; ++i) { |
| 106 scoped_ptr<Socket> socket(new Socket()); | 107 std::unique_ptr<Socket> socket(new Socket()); |
| 107 if (!socket->ConnectUnix(socket_name)) { | 108 if (!socket->ConnectUnix(socket_name)) { |
| 108 if (idle_time_msec) | 109 if (idle_time_msec) |
| 109 usleep(idle_time_msec * 1000); | 110 usleep(idle_time_msec * 1000); |
| 110 continue; | 111 continue; |
| 111 } | 112 } |
| 112 char buf[kBufferSize]; | 113 char buf[kBufferSize]; |
| 113 DCHECK(expected_welcome_message.length() + 1 <= sizeof(buf)); | 114 DCHECK(expected_welcome_message.length() + 1 <= sizeof(buf)); |
| 114 memset(buf, 0, sizeof(buf)); | 115 memset(buf, 0, sizeof(buf)); |
| 115 if (socket->Read(buf, expected_welcome_message.length() + 1) < 0) { | 116 if (socket->Read(buf, expected_welcome_message.length() + 1) < 0) { |
| 116 perror("read"); | 117 perror("read"); |
| 117 continue; | 118 continue; |
| 118 } | 119 } |
| 119 if (expected_welcome_message != buf) { | 120 if (expected_welcome_message != buf) { |
| 120 LOG(ERROR) << "Unexpected message read from daemon: " << buf; | 121 LOG(ERROR) << "Unexpected message read from daemon: " << buf; |
| 121 break; | 122 break; |
| 122 } | 123 } |
| 123 return socket; | 124 return socket; |
| 124 } | 125 } |
| 125 return scoped_ptr<Socket>(); | 126 return nullptr; |
| 126 } | 127 } |
| 127 | 128 |
| 128 } // namespace | 129 } // namespace |
| 129 | 130 |
| 130 Daemon::Daemon(const std::string& log_file_path, | 131 Daemon::Daemon(const std::string& log_file_path, |
| 131 const std::string& identifier, | 132 const std::string& identifier, |
| 132 ClientDelegate* client_delegate, | 133 ClientDelegate* client_delegate, |
| 133 ServerDelegate* server_delegate, | 134 ServerDelegate* server_delegate, |
| 134 GetExitNotifierFDCallback get_exit_fd_callback) | 135 GetExitNotifierFDCallback get_exit_fd_callback) |
| 135 : log_file_path_(log_file_path), | 136 : log_file_path_(log_file_path), |
| 136 identifier_(identifier), | 137 identifier_(identifier), |
| 137 client_delegate_(client_delegate), | 138 client_delegate_(client_delegate), |
| 138 server_delegate_(server_delegate), | 139 server_delegate_(server_delegate), |
| 139 get_exit_fd_callback_(get_exit_fd_callback) { | 140 get_exit_fd_callback_(get_exit_fd_callback) { |
| 140 DCHECK(client_delegate_); | 141 DCHECK(client_delegate_); |
| 141 DCHECK(server_delegate_); | 142 DCHECK(server_delegate_); |
| 142 DCHECK(get_exit_fd_callback_); | 143 DCHECK(get_exit_fd_callback_); |
| 143 } | 144 } |
| 144 | 145 |
| 145 Daemon::~Daemon() {} | 146 Daemon::~Daemon() {} |
| 146 | 147 |
| 147 bool Daemon::SpawnIfNeeded() { | 148 bool Daemon::SpawnIfNeeded() { |
| 148 const int kSingleTry = 1; | 149 const int kSingleTry = 1; |
| 149 const int kNoIdleTime = 0; | 150 const int kNoIdleTime = 0; |
| 150 scoped_ptr<Socket> client_socket = ConnectToUnixDomainSocket( | 151 std::unique_ptr<Socket> client_socket = ConnectToUnixDomainSocket( |
| 151 identifier_, kSingleTry, kNoIdleTime, identifier_); | 152 identifier_, kSingleTry, kNoIdleTime, identifier_); |
| 152 if (!client_socket) { | 153 if (!client_socket) { |
| 153 switch (fork()) { | 154 switch (fork()) { |
| 154 case -1: | 155 case -1: |
| 155 PError("fork()"); | 156 PError("fork()"); |
| 156 return false; | 157 return false; |
| 157 // Child. | 158 // Child. |
| 158 case 0: { | 159 case 0: { |
| 159 if (setsid() < 0) { // Detach the child process from its parent. | 160 if (setsid() < 0) { // Detach the child process from its parent. |
| 160 PError("setsid()"); | 161 PError("setsid()"); |
| 161 exit(1); | 162 exit(1); |
| 162 } | 163 } |
| 163 InitLoggingForDaemon(log_file_path_); | 164 InitLoggingForDaemon(log_file_path_); |
| 164 CloseFD(STDIN_FILENO); | 165 CloseFD(STDIN_FILENO); |
| 165 CloseFD(STDOUT_FILENO); | 166 CloseFD(STDOUT_FILENO); |
| 166 CloseFD(STDERR_FILENO); | 167 CloseFD(STDERR_FILENO); |
| 167 const int null_fd = open("/dev/null", O_RDWR); | 168 const int null_fd = open("/dev/null", O_RDWR); |
| 168 CHECK_EQ(null_fd, STDIN_FILENO); | 169 CHECK_EQ(null_fd, STDIN_FILENO); |
| 169 CHECK_EQ(dup(null_fd), STDOUT_FILENO); | 170 CHECK_EQ(dup(null_fd), STDOUT_FILENO); |
| 170 CHECK_EQ(dup(null_fd), STDERR_FILENO); | 171 CHECK_EQ(dup(null_fd), STDERR_FILENO); |
| 171 Socket command_socket; | 172 Socket command_socket; |
| 172 if (!command_socket.BindUnix(identifier_)) { | 173 if (!command_socket.BindUnix(identifier_)) { |
| 173 scoped_ptr<Socket> client_socket = ConnectToUnixDomainSocket( | 174 std::unique_ptr<Socket> client_socket = ConnectToUnixDomainSocket( |
| 174 identifier_, kSingleTry, kNoIdleTime, identifier_); | 175 identifier_, kSingleTry, kNoIdleTime, identifier_); |
| 175 if (client_socket.get()) { | 176 if (client_socket.get()) { |
| 176 // The daemon was spawned by a concurrent process. | 177 // The daemon was spawned by a concurrent process. |
| 177 exit(0); | 178 exit(0); |
| 178 } | 179 } |
| 179 PError("bind()"); | 180 PError("bind()"); |
| 180 exit(1); | 181 exit(1); |
| 181 } | 182 } |
| 182 server_delegate_->Init(); | 183 server_delegate_->Init(); |
| 183 command_socket.AddEventFd(get_exit_fd_callback_()); | 184 command_socket.AddEventFd(get_exit_fd_callback_()); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 255 return true; | 256 return true; |
| 256 } | 257 } |
| 257 usleep(kIdleTimeMSec * 1000); | 258 usleep(kIdleTimeMSec * 1000); |
| 258 } | 259 } |
| 259 LOG(ERROR) << "Timed out while killing daemon. " | 260 LOG(ERROR) << "Timed out while killing daemon. " |
| 260 "It might still be tearing down."; | 261 "It might still be tearing down."; |
| 261 return false; | 262 return false; |
| 262 } | 263 } |
| 263 | 264 |
| 264 } // namespace forwarder2 | 265 } // namespace forwarder2 |
| OLD | NEW |