From 2a7d6e7e7e6b9fcfebb34c281de93aea1a1de2bf Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Tue, 5 May 2015 19:25:23 -0700 Subject: Split adb_main.cpp into client and daemon. The name "client" is somewhat misleading as it also contains the host side adb server, but it's a part of the client binary. Change-Id: I128b7bab213e330eb21b5010cd1fec5f7a62c8af --- client/main.cpp | 180 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 client/main.cpp (limited to 'client/main.cpp') diff --git a/client/main.cpp b/client/main.cpp new file mode 100644 index 0000000..61fd6c5 --- /dev/null +++ b/client/main.cpp @@ -0,0 +1,180 @@ +/* + * 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 +#include +#include + +// We only build the affinity WAR code for Linux. +#if defined(__linux__) +#include +#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 + +// We only build the affinity WAR code for Linux. +#if defined(__linux__) +static void adb_set_affinity(void) { + 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]); +} +#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"; + char temp_path[MAX_PATH - sizeof(log_name) + 1]; + + // https://msdn.microsoft.com/en-us/library/windows/desktop/aa364992%28v=vs.85%29.aspx + DWORD nchars = GetTempPath(sizeof(temp_path), temp_path); + CHECK_LE(nchars, sizeof(temp_path)); + if (nchars == 0) { + // TODO(danalbert): Log the error message from FormatError(). + // Windows unfortunately has two errnos, errno and GetLastError(), so + // I'm not sure what to do about PLOG here. Probably better to just + // ignore it and add a simplified version of FormatError() for use in + // log messages. + LOG(ERROR) << "Error creating log file"; + } + + return std::string(temp_path) + log_name; +} +#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); + adb_close(fd); +} + +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); + adb_close(fd); + fprintf(stderr, "--- adb starting (pid %d) ---\n", getpid()); +} + +int adb_main(int is_daemon, int server_port) { + HOST = 1; + +#if defined(_WIN32) + SetConsoleCtrlHandler(ctrlc_handler, TRUE); +#else + signal(SIGPIPE, SIG_IGN); +#endif + + init_transport_registration(); + +#if defined(__linux__) + if (kWorkaroundBug6558362 && is_daemon) { + adb_set_affinity(); + } +#endif + + usb_init(); + local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT); + adb_auth_init(); + + std::string local_name = android::base::StringPrintf("tcp:%d", server_port); + if (install_listener(local_name, "*smartsocket*", nullptr, 0)) { + LOG(FATAL) << "Could not install *smartsocket* listener"; + } + + if (is_daemon) { + // Inform our parent that we are up and running. + // TODO(danalbert): Can't use SendOkay because we're sending "OK\n", not + // "OKAY". + // TODO(danalbert): Why do we use stdout for Windows? +#if defined(_WIN32) + int reply_fd = STDOUT_FILENO; +#else + int reply_fd = STDERR_FILENO; +#endif + android::base::WriteStringToFd("OK\n", reply_fd); + close_stdin(); + setup_daemon_logging(); + } + + D("Event loop starting\n"); + fdevent_loop(); + + return 0; +} + +int main(int argc, char** argv) { + // adb client/server + adb_sysdeps_init(); + adb_trace_init(); + D("Handling commandline()\n"); + return adb_commandline(argc - 1, const_cast(argv + 1)); +} -- cgit v1.2.3