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