main.cpp revision f39c56456d1f9bb910a9bc1187027a75942c8658
1bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert/* 2bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert * Copyright (C) 2015 The Android Open Source Project 3bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert * 4bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert * Licensed under the Apache License, Version 2.0 (the "License"); 5bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert * you may not use this file except in compliance with the License. 6bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert * You may obtain a copy of the License at 7bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert * 8bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert * http://www.apache.org/licenses/LICENSE-2.0 9bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert * 10bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert * Unless required by applicable law or agreed to in writing, software 11bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert * distributed under the License is distributed on an "AS IS" BASIS, 12bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert * See the License for the specific language governing permissions and 14bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert * limitations under the License. 15bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert */ 16bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert 17aed3c61c4437ebb05eadfb3bf85d6962c30b9935Yabin Cui#define TRACE_TAG ADB 183313426fad9eaaf53017cdbde889ebcec91358ecDan Albert 193313426fad9eaaf53017cdbde889ebcec91358ecDan Albert#include "sysdeps.h" 20bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert 21bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert#include <errno.h> 22bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert#include <signal.h> 23bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert#include <stdio.h> 24bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert#include <stdlib.h> 25bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert#include <getopt.h> 266795cd8db5ffab674f2a477d8b7b8cc0e3ab406eDan Albert#include <sys/prctl.h> 27bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert 28c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert#include "base/logging.h" 29c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert#include "base/stringprintf.h" 30bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert#include "cutils/properties.h" 31bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert#include "private/android_filesystem_config.h" 32bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert#include "selinux/selinux.h" 33bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert 34c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert#include "adb.h" 35c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert#include "adb_auth.h" 36c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert#include "adb_listeners.h" 37c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert#include "transport.h" 38218dbccefa3d874d988e4784bda5e45b7643cb5aDan Albert 39c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albertstatic const char* root_seclabel = nullptr; 40bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert 41bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albertstatic void drop_capabilities_bounding_set_if_needed() { 42bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert#ifdef ALLOW_ADBD_ROOT 43bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert char value[PROPERTY_VALUE_MAX]; 44bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert property_get("ro.debuggable", value, ""); 45bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert if (strcmp(value, "1") == 0) { 46bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert return; 47bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert } 48bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert#endif 49c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert for (int i = 0; prctl(PR_CAPBSET_READ, i, 0, 0, 0) >= 0; i++) { 50bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert if (i == CAP_SETUID || i == CAP_SETGID) { 51bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert // CAP_SETUID CAP_SETGID needed by /system/bin/run-as 52bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert continue; 53bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert } 54c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert 55bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert int err = prctl(PR_CAPBSET_DROP, i, 0, 0, 0); 56bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert 57bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert // Some kernels don't have file capabilities compiled in, and 58bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert // prctl(PR_CAPBSET_DROP) returns EINVAL. Don't automatically 59bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert // die when we see such misconfigured kernels. 60bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert if ((err < 0) && (errno != EINVAL)) { 61c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert PLOG(FATAL) << "Could not drop capabilities"; 62bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert } 63bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert } 64bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert} 65bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert 66bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albertstatic bool should_drop_privileges() { 67bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert#if defined(ALLOW_ADBD_ROOT) 68bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert char value[PROPERTY_VALUE_MAX]; 69bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert 7013f9c406d7ae58bb3f5c3ac0b0e50f8760c5cf46Dan Albert // The properties that affect `adb root` and `adb unroot` are ro.secure and 7113f9c406d7ae58bb3f5c3ac0b0e50f8760c5cf46Dan Albert // ro.debuggable. In this context the names don't make the expected behavior 7213f9c406d7ae58bb3f5c3ac0b0e50f8760c5cf46Dan Albert // particularly obvious. 7313f9c406d7ae58bb3f5c3ac0b0e50f8760c5cf46Dan Albert // 7413f9c406d7ae58bb3f5c3ac0b0e50f8760c5cf46Dan Albert // ro.debuggable: 7513f9c406d7ae58bb3f5c3ac0b0e50f8760c5cf46Dan Albert // Allowed to become root, but not necessarily the default. Set to 1 on 7613f9c406d7ae58bb3f5c3ac0b0e50f8760c5cf46Dan Albert // eng and userdebug builds. 7713f9c406d7ae58bb3f5c3ac0b0e50f8760c5cf46Dan Albert // 7813f9c406d7ae58bb3f5c3ac0b0e50f8760c5cf46Dan Albert // ro.secure: 7913f9c406d7ae58bb3f5c3ac0b0e50f8760c5cf46Dan Albert // Drop privileges by default. Set to 1 on userdebug and user builds. 80bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert property_get("ro.secure", value, "1"); 81bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert bool ro_secure = (strcmp(value, "1") == 0); 82bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert 8313f9c406d7ae58bb3f5c3ac0b0e50f8760c5cf46Dan Albert property_get("ro.debuggable", value, ""); 8413f9c406d7ae58bb3f5c3ac0b0e50f8760c5cf46Dan Albert bool ro_debuggable = (strcmp(value, "1") == 0); 8513f9c406d7ae58bb3f5c3ac0b0e50f8760c5cf46Dan Albert 86bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert // Drop privileges if ro.secure is set... 87bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert bool drop = ro_secure; 88bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert 89bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert property_get("service.adb.root", value, ""); 90bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert bool adb_root = (strcmp(value, "1") == 0); 91bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert bool adb_unroot = (strcmp(value, "0") == 0); 92bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert 93bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert // ...except "adb root" lets you keep privileges in a debuggable build. 94bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert if (ro_debuggable && adb_root) { 95bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert drop = false; 96bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert } 97bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert 98bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert // ...and "adb unroot" lets you explicitly drop privileges. 99bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert if (adb_unroot) { 100bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert drop = true; 101bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert } 102bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert 103bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert return drop; 104bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert#else 105bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert return true; // "adb root" not allowed, always drop privileges. 106c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert#endif // ALLOW_ADBD_ROOT 107218dbccefa3d874d988e4784bda5e45b7643cb5aDan Albert} 108218dbccefa3d874d988e4784bda5e45b7643cb5aDan Albert 109c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albertint adbd_main(int server_port) { 110c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert umask(0); 111218dbccefa3d874d988e4784bda5e45b7643cb5aDan Albert 112bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert signal(SIGPIPE, SIG_IGN); 113bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert 114bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert init_transport_registration(); 115bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert 11664d9adcea807aa1d31574b5b3bb5aad4b9025134Pavel Labath // We need to call this even if auth isn't enabled because the file 11764d9adcea807aa1d31574b5b3bb5aad4b9025134Pavel Labath // descriptor will always be open. 11864d9adcea807aa1d31574b5b3bb5aad4b9025134Pavel Labath adbd_cloexec_auth_socket(); 11964d9adcea807aa1d31574b5b3bb5aad4b9025134Pavel Labath 1205cba504215ea91187cc36ec7aec5dce1b0f4b0feElliott Hughes if (ALLOW_ADBD_NO_AUTH && property_get_bool("ro.adb.secure", 0) == 0) { 1215cba504215ea91187cc36ec7aec5dce1b0f4b0feElliott Hughes auth_required = false; 122c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert } 123bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert 1245cba504215ea91187cc36ec7aec5dce1b0f4b0feElliott Hughes adbd_auth_init(); 1255cba504215ea91187cc36ec7aec5dce1b0f4b0feElliott Hughes 126bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert // Our external storage path may be different than apps, since 127bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert // we aren't able to bind mount after dropping root. 128bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert const char* adb_external_storage = getenv("ADB_EXTERNAL_STORAGE"); 129c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert if (adb_external_storage != nullptr) { 130bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert setenv("EXTERNAL_STORAGE", adb_external_storage, 1); 131bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert } else { 132bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert D("Warning: ADB_EXTERNAL_STORAGE is not set. Leaving EXTERNAL_STORAGE" 133bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert " unchanged.\n"); 134bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert } 135bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert 136c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert // Add extra groups: 137c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert // AID_ADB to access the USB driver 138c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert // AID_LOG to read system logs (adb logcat) 139c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert // AID_INPUT to diagnose input issues (getevent) 140c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert // AID_INET to diagnose network issues (ping) 141c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert // AID_NET_BT and AID_NET_BT_ADMIN to diagnose bluetooth (hcidump) 142c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert // AID_SDCARD_R to allow reading from the SD card 143c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert // AID_SDCARD_RW to allow writing to the SD card 144c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert // AID_NET_BW_STATS to read out qtaguid statistics 145c39ba5ae32afb6329d42e61d2941d87ff66d92e3Nick Kralevich // AID_READPROC for reading /proc entries across UID boundaries 146c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert gid_t groups[] = {AID_ADB, AID_LOG, AID_INPUT, 147c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert AID_INET, AID_NET_BT, AID_NET_BT_ADMIN, 148c39ba5ae32afb6329d42e61d2941d87ff66d92e3Nick Kralevich AID_SDCARD_R, AID_SDCARD_RW, AID_NET_BW_STATS, 149c39ba5ae32afb6329d42e61d2941d87ff66d92e3Nick Kralevich AID_READPROC }; 150c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert if (setgroups(sizeof(groups) / sizeof(groups[0]), groups) != 0) { 151f39c56456d1f9bb910a9bc1187027a75942c8658Jorge Lucangeli Obes PLOG(FATAL) << "Could not set supplemental groups"; 152bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert } 153bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert 154bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert /* don't listen on a port (default 5037) if running in secure mode */ 155bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert /* don't run as root if we are running in secure mode */ 156bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert if (should_drop_privileges()) { 157bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert drop_capabilities_bounding_set_if_needed(); 158bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert 159bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert /* then switch user and group to "shell" */ 160bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert if (setgid(AID_SHELL) != 0) { 161c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert PLOG(FATAL) << "Could not setgid"; 162bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert } 163bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert if (setuid(AID_SHELL) != 0) { 164c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert PLOG(FATAL) << "Could not setuid"; 165bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert } 166bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert 1677a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("Local port disabled"); 168bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert } else { 1694d87095ebfefdb9e641492462f0a0e21d5b96ecfNick Kralevich if (root_seclabel != nullptr) { 170c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert if (setcon(root_seclabel) < 0) { 171f39c56456d1f9bb910a9bc1187027a75942c8658Jorge Lucangeli Obes LOG(FATAL) << "Could not set SELinux context"; 172bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert } 173bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert } 1745200c6670f041550c23821fec8e8e49b30ef6d29Spencer Low std::string error; 175c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert std::string local_name = 176c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert android::base::StringPrintf("tcp:%d", server_port); 1775200c6670f041550c23821fec8e8e49b30ef6d29Spencer Low if (install_listener(local_name, "*smartsocket*", nullptr, 0, 1785200c6670f041550c23821fec8e8e49b30ef6d29Spencer Low &error)) { 1795200c6670f041550c23821fec8e8e49b30ef6d29Spencer Low LOG(FATAL) << "Could not install *smartsocket* listener: " 1805200c6670f041550c23821fec8e8e49b30ef6d29Spencer Low << error; 181bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert } 182bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert } 183bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert 184c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert bool is_usb = false; 185bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert if (access(USB_ADB_PATH, F_OK) == 0 || access(USB_FFS_ADB_EP0, F_OK) == 0) { 186c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert // Listen on USB. 187bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert usb_init(); 188c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert is_usb = true; 189bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert } 190bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert 191c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert // If one of these properties is set, also listen on that port. 192c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert // If one of the properties isn't set and we couldn't listen on usb, listen 193c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert // on the default port. 194c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert char prop_port[PROPERTY_VALUE_MAX]; 195c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert property_get("service.adb.tcp.port", prop_port, ""); 196c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert if (prop_port[0] == '\0') { 197c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert property_get("persist.adb.tcp.port", prop_port, ""); 198bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert } 199c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert 200c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert int port; 201c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert if (sscanf(prop_port, "%d", &port) == 1 && port > 0) { 2027a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("using port=%d", port); 203c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert // Listen on TCP port specified by service.adb.tcp.port property. 204bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert local_init(port); 205c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert } else if (!is_usb) { 206c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert // Listen on default port. 207bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT); 208bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert } 209bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert 2107a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("adbd_main(): pre init_jdwp()"); 211bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert init_jdwp(); 2127a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("adbd_main(): post init_jdwp()"); 213bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert 2147a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("Event loop starting"); 215bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert fdevent_loop(); 216bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert 217bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert return 0; 218bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert} 219bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert 220c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albertstatic void close_stdin() { 2218743ef98414b336f222327253f2cde6bf6aee386Dan Albert int fd = unix_open("/dev/null", O_RDONLY); 2228743ef98414b336f222327253f2cde6bf6aee386Dan Albert if (fd == -1) { 2238743ef98414b336f222327253f2cde6bf6aee386Dan Albert perror("failed to open /dev/null, stdin will remain open"); 2248743ef98414b336f222327253f2cde6bf6aee386Dan Albert return; 2258743ef98414b336f222327253f2cde6bf6aee386Dan Albert } 226c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert dup2(fd, STDIN_FILENO); 2276ac5d7dc56a016718d2a26803435505e983e5d80Spencer Low unix_close(fd); 2288743ef98414b336f222327253f2cde6bf6aee386Dan Albert} 2298743ef98414b336f222327253f2cde6bf6aee386Dan Albert 230c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albertint main(int argc, char** argv) { 231a7090b94c181f3efe5b53d2c8367b78d99074dfeElliott Hughes while (true) { 232bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert static struct option opts[] = { 2331ba1d7c1ee644967ff4743b0d257290cbeca7a83Dan Albert {"root_seclabel", required_argument, nullptr, 's'}, 2341ba1d7c1ee644967ff4743b0d257290cbeca7a83Dan Albert {"device_banner", required_argument, nullptr, 'b'}, 2351ba1d7c1ee644967ff4743b0d257290cbeca7a83Dan Albert {"version", no_argument, nullptr, 'v'}, 236bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert }; 2371ba1d7c1ee644967ff4743b0d257290cbeca7a83Dan Albert 2381ba1d7c1ee644967ff4743b0d257290cbeca7a83Dan Albert int option_index = 0; 2391ba1d7c1ee644967ff4743b0d257290cbeca7a83Dan Albert int c = getopt_long(argc, argv, "", opts, &option_index); 240c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert if (c == -1) { 241218dbccefa3d874d988e4784bda5e45b7643cb5aDan Albert break; 242c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert } 243c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert 244bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert switch (c) { 245bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert case 's': 246bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert root_seclabel = optarg; 247bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert break; 248bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert case 'b': 249bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert adb_device_banner = optarg; 250bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert break; 2511ba1d7c1ee644967ff4743b0d257290cbeca7a83Dan Albert case 'v': 2521ba1d7c1ee644967ff4743b0d257290cbeca7a83Dan Albert printf("Android Debug Bridge Daemon version %d.%d.%d %s\n", 2531ba1d7c1ee644967ff4743b0d257290cbeca7a83Dan Albert ADB_VERSION_MAJOR, ADB_VERSION_MINOR, ADB_SERVER_VERSION, 2541ba1d7c1ee644967ff4743b0d257290cbeca7a83Dan Albert ADB_REVISION); 2551ba1d7c1ee644967ff4743b0d257290cbeca7a83Dan Albert return 0; 256bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert default: 257c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert // getopt already prints "adbd: invalid option -- %c" for us. 258c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert return 1; 259bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert } 260bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert } 261bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert 2621ba1d7c1ee644967ff4743b0d257290cbeca7a83Dan Albert close_stdin(); 2631ba1d7c1ee644967ff4743b0d257290cbeca7a83Dan Albert 2649313c0df20d7cc8ea6a074a3d53022c4b3b5ea05Dan Albert adb_trace_init(argv); 2651ba1d7c1ee644967ff4743b0d257290cbeca7a83Dan Albert 2667a3f8d6691b3fbd8014a98de8455dbcfcc9629e4Yabin Cui D("Handling main()"); 267c89e0ccd40624e8b2ce30d425e8bed0264fae548Dan Albert return adbd_main(DEFAULT_ADB_PORT); 268bd0b750897bebaa10e16507fdd08dbc746cd228dDan Albert} 269