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 |