• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define TRACE_TAG ADB
18 
19 #include "sysdeps.h"
20 
21 #include <signal.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25 
26 #include <thread>
27 
28 #include <android-base/errors.h>
29 #include <android-base/file.h>
30 #include <android-base/logging.h>
31 #include <android-base/quick_exit.h>
32 #include <android-base/stringprintf.h>
33 
34 #include "adb.h"
35 #include "adb_auth.h"
36 #include "adb_listeners.h"
37 #include "adb_utils.h"
38 #include "commandline.h"
39 #include "sysdeps/chrono.h"
40 #include "transport.h"
41 
GetLogFilePath()42 static std::string GetLogFilePath() {
43 #if defined(_WIN32)
44     const char log_name[] = "adb.log";
45     WCHAR temp_path[MAX_PATH];
46 
47     // https://msdn.microsoft.com/en-us/library/windows/desktop/aa364992%28v=vs.85%29.aspx
48     DWORD nchars = GetTempPathW(arraysize(temp_path), temp_path);
49     if (nchars >= arraysize(temp_path) || nchars == 0) {
50         // If string truncation or some other error.
51         fatal("cannot retrieve temporary file path: %s\n",
52               android::base::SystemErrorCodeToString(GetLastError()).c_str());
53     }
54 
55     std::string temp_path_utf8;
56     if (!android::base::WideToUTF8(temp_path, &temp_path_utf8)) {
57         fatal_errno("cannot convert temporary file path from UTF-16 to UTF-8");
58     }
59 
60     return temp_path_utf8 + log_name;
61 #else
62     const char* tmp_dir = getenv("TMPDIR");
63     if (tmp_dir == nullptr) tmp_dir = "/tmp";
64     return android::base::StringPrintf("%s/adb.%u.log", tmp_dir, getuid());
65 #endif
66 }
67 
setup_daemon_logging(void)68 static void setup_daemon_logging(void) {
69     const std::string log_file_path(GetLogFilePath());
70     int fd = unix_open(log_file_path.c_str(), O_WRONLY | O_CREAT | O_APPEND, 0640);
71     if (fd == -1) {
72         fatal("cannot open '%s': %s", log_file_path.c_str(), strerror(errno));
73     }
74     if (dup2(fd, STDOUT_FILENO) == -1) {
75         fatal("cannot redirect stdout: %s", strerror(errno));
76     }
77     if (dup2(fd, STDERR_FILENO) == -1) {
78         fatal("cannot redirect stderr: %s", strerror(errno));
79     }
80     unix_close(fd);
81 
82     fprintf(stderr, "--- adb starting (pid %d) ---\n", getpid());
83     LOG(INFO) << adb_version();
84 }
85 
86 #if defined(_WIN32)
ctrlc_handler(DWORD type)87 static BOOL WINAPI ctrlc_handler(DWORD type) {
88     // TODO: Consider trying to kill a starting up adb server (if we're in
89     // launch_server) by calling GenerateConsoleCtrlEvent().
90     android::base::quick_exit(STATUS_CONTROL_C_EXIT);
91     return TRUE;
92 }
93 #endif
94 
adb_server_main(int is_daemon,const std::string & socket_spec,int ack_reply_fd)95 int adb_server_main(int is_daemon, const std::string& socket_spec, int ack_reply_fd) {
96 #if defined(_WIN32)
97     // adb start-server starts us up with stdout and stderr hooked up to
98     // anonymous pipes. When the C Runtime sees this, it makes stderr and
99     // stdout buffered, but to improve the chance that error output is seen,
100     // unbuffer stdout and stderr just like if we were run at the console.
101     // This also keeps stderr unbuffered when it is redirected to adb.log.
102     if (is_daemon) {
103         if (setvbuf(stdout, NULL, _IONBF, 0) == -1) {
104             fatal("cannot make stdout unbuffered: %s", strerror(errno));
105         }
106         if (setvbuf(stderr, NULL, _IONBF, 0) == -1) {
107             fatal("cannot make stderr unbuffered: %s", strerror(errno));
108         }
109     }
110 
111     SetConsoleCtrlHandler(ctrlc_handler, TRUE);
112 #else
113     signal(SIGINT, [](int) {
114         android::base::quick_exit(0);
115     });
116 #endif
117 
118     init_transport_registration();
119 
120     init_mdns_transport_discovery();
121 
122     usb_init();
123     local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT);
124 
125     std::string error;
126 
127     auto start = std::chrono::steady_clock::now();
128 
129     // If we told a previous adb server to quit because of version mismatch, we can get to this
130     // point before it's finished exiting. Retry for a while to give it some time.
131     while (install_listener(socket_spec, "*smartsocket*", nullptr, 0, nullptr, &error) !=
132            INSTALL_STATUS_OK) {
133         if (std::chrono::steady_clock::now() - start > 0.5s) {
134             fatal("could not install *smartsocket* listener: %s", error.c_str());
135         }
136 
137         std::this_thread::sleep_for(100ms);
138     }
139 
140     if (is_daemon) {
141         close_stdin();
142         setup_daemon_logging();
143     }
144 
145     adb_auth_init();
146 
147     if (is_daemon) {
148 #if !defined(_WIN32)
149         // Start a new session for the daemon. Do this here instead of after the fork so
150         // that a ctrl-c between the "starting server" and "done starting server" messages
151         // gets a chance to terminate the server.
152         // setsid will fail with EPERM if it's already been a lead process of new session.
153         // Ignore such error.
154         if (setsid() == -1 && errno != EPERM) {
155             fatal("setsid() failed: %s", strerror(errno));
156         }
157 #endif
158 
159         // Inform our parent that we are up and running.
160 
161         // Any error output written to stderr now goes to adb.log. We could
162         // keep around a copy of the stderr fd and use that to write any errors
163         // encountered by the following code, but that is probably overkill.
164 #if defined(_WIN32)
165         const HANDLE ack_reply_handle = cast_int_to_handle(ack_reply_fd);
166         const CHAR ack[] = "OK\n";
167         const DWORD bytes_to_write = arraysize(ack) - 1;
168         DWORD written = 0;
169         if (!WriteFile(ack_reply_handle, ack, bytes_to_write, &written, NULL)) {
170             fatal("adb: cannot write ACK to handle 0x%p: %s", ack_reply_handle,
171                   android::base::SystemErrorCodeToString(GetLastError()).c_str());
172         }
173         if (written != bytes_to_write) {
174             fatal("adb: cannot write %lu bytes of ACK: only wrote %lu bytes",
175                   bytes_to_write, written);
176         }
177         CloseHandle(ack_reply_handle);
178 #else
179         // TODO(danalbert): Can't use SendOkay because we're sending "OK\n", not
180         // "OKAY".
181         if (!android::base::WriteStringToFd("OK\n", ack_reply_fd)) {
182             fatal_errno("error writing ACK to fd %d", ack_reply_fd);
183         }
184         unix_close(ack_reply_fd);
185 #endif
186     }
187 
188     D("Event loop starting");
189     fdevent_loop();
190 
191     return 0;
192 }
193 
main(int argc,char ** argv)194 int main(int argc, char** argv) {
195     adb_trace_init(argv);
196     return adb_commandline(argc - 1, const_cast<const char**>(argv + 1));
197 }
198