2015-05-09 01:13:53 +02:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2015 The Android Open Source Project
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define TRACE_TAG TRACE_ADB
|
|
|
|
|
|
|
|
#include "sysdeps.h"
|
|
|
|
|
|
|
|
#include <signal.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
// We only build the affinity WAR code for Linux.
|
|
|
|
#if defined(__linux__)
|
|
|
|
#include <sched.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "base/file.h"
|
|
|
|
#include "base/logging.h"
|
|
|
|
#include "base/stringprintf.h"
|
|
|
|
|
|
|
|
#include "adb.h"
|
|
|
|
#include "adb_auth.h"
|
|
|
|
#include "adb_listeners.h"
|
|
|
|
#include "transport.h"
|
|
|
|
|
|
|
|
#if defined(WORKAROUND_BUG6558362) && defined(__linux__)
|
|
|
|
static const bool kWorkaroundBug6558362 = true;
|
|
|
|
#else
|
|
|
|
static const bool kWorkaroundBug6558362 = false;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static void adb_workaround_affinity(void) {
|
|
|
|
#if defined(__linux__)
|
|
|
|
const char affinity_env[] = "ADB_CPU_AFFINITY_BUG6558362";
|
|
|
|
const char* cpunum_str = getenv(affinity_env);
|
|
|
|
if (cpunum_str == nullptr || *cpunum_str == '\0') {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
char* strtol_res;
|
|
|
|
int cpu_num = strtol(cpunum_str, &strtol_res, 0);
|
|
|
|
if (*strtol_res != '\0') {
|
|
|
|
fatal("bad number (%s) in env var %s. Expecting 0..n.\n", cpunum_str,
|
|
|
|
affinity_env);
|
|
|
|
}
|
|
|
|
|
|
|
|
cpu_set_t cpu_set;
|
|
|
|
sched_getaffinity(0, sizeof(cpu_set), &cpu_set);
|
|
|
|
D("orig cpu_set[0]=0x%08lx\n", cpu_set.__bits[0]);
|
|
|
|
|
|
|
|
CPU_ZERO(&cpu_set);
|
|
|
|
CPU_SET(cpu_num, &cpu_set);
|
|
|
|
sched_setaffinity(0, sizeof(cpu_set), &cpu_set);
|
|
|
|
|
|
|
|
sched_getaffinity(0, sizeof(cpu_set), &cpu_set);
|
|
|
|
D("new cpu_set[0]=0x%08lx\n", cpu_set.__bits[0]);
|
|
|
|
#else
|
|
|
|
// No workaround was ever implemented for the other platforms.
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
#if defined(_WIN32)
|
|
|
|
static const char kNullFileName[] = "NUL";
|
|
|
|
|
|
|
|
static BOOL WINAPI ctrlc_handler(DWORD type) {
|
|
|
|
exit(STATUS_CONTROL_C_EXIT);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static std::string GetLogFilePath() {
|
|
|
|
const char log_name[] = "adb.log";
|
2015-05-11 10:08:48 +02:00
|
|
|
WCHAR temp_path[MAX_PATH];
|
2015-05-09 01:13:53 +02:00
|
|
|
|
|
|
|
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa364992%28v=vs.85%29.aspx
|
2015-05-11 10:08:48 +02:00
|
|
|
DWORD nchars = GetTempPathW(arraysize(temp_path), temp_path);
|
|
|
|
if ((nchars >= arraysize(temp_path)) || (nchars == 0)) {
|
|
|
|
// If string truncation or some other error.
|
|
|
|
// TODO(danalbert): Log the error message from
|
|
|
|
// FormatMessage(GetLastError()). Pure Windows APIs only touch
|
|
|
|
// GetLastError(), C Runtime APIs touch errno, so maybe there should be
|
|
|
|
// WPLOG or PLOGW (which would read GetLastError() instead of errno),
|
|
|
|
// in addition to PLOG, or maybe better to just ignore it and add a
|
|
|
|
// simplified version of FormatMessage() for use in log messages.
|
2015-05-09 01:13:53 +02:00
|
|
|
LOG(ERROR) << "Error creating log file";
|
|
|
|
}
|
|
|
|
|
2015-05-11 10:08:48 +02:00
|
|
|
return narrow(temp_path) + log_name;
|
2015-05-09 01:13:53 +02:00
|
|
|
}
|
|
|
|
#else
|
|
|
|
static const char kNullFileName[] = "/dev/null";
|
|
|
|
|
|
|
|
static std::string GetLogFilePath() {
|
|
|
|
return std::string("/tmp/adb.log");
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static void close_stdin() {
|
|
|
|
int fd = unix_open(kNullFileName, O_RDONLY);
|
|
|
|
CHECK_NE(fd, -1);
|
|
|
|
dup2(fd, STDIN_FILENO);
|
2015-05-21 08:17:26 +02:00
|
|
|
unix_close(fd);
|
2015-05-09 01:13:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void setup_daemon_logging(void) {
|
|
|
|
int fd = unix_open(GetLogFilePath().c_str(), O_WRONLY | O_CREAT | O_APPEND,
|
|
|
|
0640);
|
|
|
|
if (fd == -1) {
|
|
|
|
fd = unix_open(kNullFileName, O_WRONLY);
|
|
|
|
}
|
|
|
|
dup2(fd, STDOUT_FILENO);
|
|
|
|
dup2(fd, STDERR_FILENO);
|
2015-05-21 08:17:26 +02:00
|
|
|
unix_close(fd);
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
// On Windows, stderr is buffered by default, so switch to non-buffered
|
|
|
|
// to match Linux.
|
|
|
|
setvbuf(stderr, NULL, _IONBF, 0);
|
|
|
|
#endif
|
2015-05-09 01:13:53 +02:00
|
|
|
fprintf(stderr, "--- adb starting (pid %d) ---\n", getpid());
|
|
|
|
}
|
|
|
|
|
2015-08-07 19:10:29 +02:00
|
|
|
int adb_main(int is_daemon, int server_port, int ack_reply_fd) {
|
2015-05-09 01:13:53 +02:00
|
|
|
HOST = 1;
|
|
|
|
|
|
|
|
#if defined(_WIN32)
|
|
|
|
SetConsoleCtrlHandler(ctrlc_handler, TRUE);
|
|
|
|
#else
|
|
|
|
signal(SIGPIPE, SIG_IGN);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
init_transport_registration();
|
|
|
|
|
|
|
|
if (kWorkaroundBug6558362 && is_daemon) {
|
|
|
|
adb_workaround_affinity();
|
|
|
|
}
|
|
|
|
|
|
|
|
usb_init();
|
|
|
|
local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT);
|
|
|
|
adb_auth_init();
|
|
|
|
|
2015-07-31 08:07:55 +02:00
|
|
|
std::string error;
|
2015-05-09 01:13:53 +02:00
|
|
|
std::string local_name = android::base::StringPrintf("tcp:%d", server_port);
|
2015-07-31 08:07:55 +02:00
|
|
|
if (install_listener(local_name, "*smartsocket*", nullptr, 0, &error)) {
|
|
|
|
LOG(FATAL) << "Could not install *smartsocket* listener: " << error;
|
2015-05-09 01:13:53 +02:00
|
|
|
}
|
|
|
|
|
2015-08-07 19:10:29 +02:00
|
|
|
// Inform our parent that we are up and running.
|
2015-05-09 01:13:53 +02:00
|
|
|
if (is_daemon) {
|
|
|
|
#if defined(_WIN32)
|
2015-08-09 00:07:07 +02:00
|
|
|
const HANDLE ack_reply_handle = cast_int_to_handle(ack_reply_fd);
|
|
|
|
const CHAR ack[] = "OK\n";
|
|
|
|
const DWORD bytes_to_write = arraysize(ack) - 1;
|
|
|
|
DWORD written = 0;
|
|
|
|
if (!WriteFile(ack_reply_handle, ack, bytes_to_write, &written, NULL)) {
|
|
|
|
fatal("adb: cannot write ACK to handle 0x%p: %s", ack_reply_handle,
|
|
|
|
SystemErrorCodeToString(GetLastError()).c_str());
|
|
|
|
}
|
|
|
|
if (written != bytes_to_write) {
|
|
|
|
fatal("adb: cannot write %lu bytes of ACK: only wrote %lu bytes",
|
|
|
|
bytes_to_write, written);
|
|
|
|
}
|
|
|
|
CloseHandle(ack_reply_handle);
|
|
|
|
#else
|
2015-08-07 19:10:29 +02:00
|
|
|
// TODO(danalbert): Can't use SendOkay because we're sending "OK\n", not
|
|
|
|
// "OKAY".
|
|
|
|
android::base::WriteStringToFd("OK\n", ack_reply_fd);
|
2015-08-09 00:07:07 +02:00
|
|
|
unix_close(ack_reply_fd);
|
2015-05-09 01:13:53 +02:00
|
|
|
#endif
|
|
|
|
close_stdin();
|
|
|
|
setup_daemon_logging();
|
|
|
|
}
|
|
|
|
|
|
|
|
D("Event loop starting\n");
|
|
|
|
fdevent_loop();
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-05-11 10:08:48 +02:00
|
|
|
#ifdef _WIN32
|
|
|
|
static bool _argv_is_utf8 = false;
|
|
|
|
#endif
|
|
|
|
|
2015-05-09 01:13:53 +02:00
|
|
|
int main(int argc, char** argv) {
|
2015-05-11 10:08:48 +02:00
|
|
|
#ifdef _WIN32
|
|
|
|
if (!_argv_is_utf8) {
|
|
|
|
fatal("_argv_is_utf8 is not set, suggesting that wmain was not "
|
|
|
|
"called. Did you forget to link with -municode?");
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2015-05-09 01:13:53 +02:00
|
|
|
adb_sysdeps_init();
|
2015-05-21 22:58:50 +02:00
|
|
|
adb_trace_init(argv);
|
2015-05-09 01:13:53 +02:00
|
|
|
return adb_commandline(argc - 1, const_cast<const char**>(argv + 1));
|
|
|
|
}
|
2015-05-11 10:08:48 +02:00
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
int wmain(int argc, wchar_t **argv) {
|
|
|
|
// Set diagnostic flag to try to detect if the build system was not
|
|
|
|
// configured to call wmain.
|
|
|
|
_argv_is_utf8 = true;
|
|
|
|
|
|
|
|
// Convert args from UTF-16 to UTF-8 and pass that to main().
|
|
|
|
NarrowArgs narrow_args(argc, argv);
|
|
|
|
return main(argc, narrow_args.data());
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|