Merge changes Ic90fac0b,Id9c12303,I2d9bdcb1,I9d699af1,Ia4d03f9e, ...
* changes: adbd: turn on fdsan warnings. adb: add error-generating overload of adb_close(unique_fd). adb: fix register_socket_transport related double-closes. adb: fix double close in local_connect_arbitrary_ports. adb: use adb's unique_fd instead of android::base. adb: move remount_service.h into daemon. adb: split shell_service.h into client/daemon/protocol parts. adb: split file_sync_service.h into client and daemon parts.
This commit is contained in:
commit
46f281edf5
26 changed files with 200 additions and 169 deletions
|
|
@ -133,7 +133,7 @@ int launch_server(const std::string& socket_spec);
|
|||
int adb_server_main(int is_daemon, const std::string& socket_spec, int ack_reply_fd);
|
||||
|
||||
/* initialize a transport object's func pointers and state */
|
||||
int init_socket_transport(atransport* t, int s, int port, int local);
|
||||
int init_socket_transport(atransport* t, unique_fd s, int port, int local);
|
||||
void init_usb_transport(atransport* t, usb_handle* usb);
|
||||
|
||||
std::string getEmulatorSerialString(int console_port);
|
||||
|
|
|
|||
|
|
@ -31,3 +31,7 @@ using unique_fd = android::base::unique_fd_impl<AdbCloser>;
|
|||
#if !defined(_WIN32)
|
||||
bool Pipe(unique_fd* read, unique_fd* write, int flags = 0);
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
int adb_close(const android::base::unique_fd_impl<T>&)
|
||||
__attribute__((__unavailable__("adb_close called on unique_fd")));
|
||||
|
|
|
|||
|
|
@ -25,8 +25,9 @@
|
|||
#include <android-base/strings.h>
|
||||
|
||||
#include "sysdeps.h"
|
||||
|
||||
#include "adb_utils.h"
|
||||
#include "file_sync_service.h"
|
||||
#include "client/file_sync_client.h"
|
||||
|
||||
static constexpr char BUGZ_BEGIN_PREFIX[] = "BEGIN:";
|
||||
static constexpr char BUGZ_PROGRESS_PREFIX[] = "PROGRESS:";
|
||||
|
|
|
|||
|
|
@ -56,10 +56,10 @@
|
|||
#include "adb_unique_fd.h"
|
||||
#include "adb_utils.h"
|
||||
#include "bugreport.h"
|
||||
#include "client/file_sync_client.h"
|
||||
#include "commandline.h"
|
||||
#include "file_sync_service.h"
|
||||
#include "services.h"
|
||||
#include "shell_service.h"
|
||||
#include "shell_protocol.h"
|
||||
#include "sysdeps/chrono.h"
|
||||
#include "sysdeps/memory.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "client/file_sync_client.h"
|
||||
|
||||
#include <dirent.h>
|
||||
#include <inttypes.h>
|
||||
#include <limits.h>
|
||||
|
|
@ -39,7 +41,7 @@
|
|||
#include "adb_client.h"
|
||||
#include "adb_io.h"
|
||||
#include "adb_utils.h"
|
||||
#include "file_sync_service.h"
|
||||
#include "file_sync_protocol.h"
|
||||
#include "line_printer.h"
|
||||
#include "sysdeps/errno.h"
|
||||
#include "sysdeps/stat.h"
|
||||
|
|
|
|||
27
adb/client/file_sync_client.h
Normal file
27
adb/client/file_sync_client.h
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright (C) 2018 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
bool do_sync_ls(const char* path);
|
||||
bool do_sync_push(const std::vector<const char*>& srcs, const char* dst, bool sync);
|
||||
bool do_sync_pull(const std::vector<const char*>& srcs, const char* dst, bool copy_attrs,
|
||||
const char* name = nullptr);
|
||||
|
||||
bool do_sync_sync(const std::string& lpath, const std::string& rpath, bool list_only);
|
||||
|
|
@ -16,8 +16,9 @@
|
|||
|
||||
#define TRACE_TAG SYNC
|
||||
|
||||
#include "daemon/file_sync_service.h"
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include "file_sync_service.h"
|
||||
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
|
|
@ -42,6 +43,7 @@
|
|||
#include "adb_io.h"
|
||||
#include "adb_trace.h"
|
||||
#include "adb_utils.h"
|
||||
#include "file_sync_protocol.h"
|
||||
#include "security_log_tags.h"
|
||||
#include "sysdeps/errno.h"
|
||||
|
||||
|
|
@ -525,7 +527,7 @@ static bool handle_sync_command(int fd, std::vector<char>& buffer) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void file_sync_service(android::base::unique_fd fd) {
|
||||
void file_sync_service(unique_fd fd) {
|
||||
std::vector<char> buffer(SYNC_DATA_MAX);
|
||||
|
||||
while (handle_sync_command(fd.get(), buffer)) {
|
||||
|
|
|
|||
21
adb/daemon/file_sync_service.h
Normal file
21
adb/daemon/file_sync_service.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Copyright (C) 2018 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "adb_unique_fd.h"
|
||||
|
||||
void file_sync_service(unique_fd fd);
|
||||
|
|
@ -57,7 +57,7 @@ struct fbinfo {
|
|||
unsigned int alpha_length;
|
||||
} __attribute__((packed));
|
||||
|
||||
void framebuffer_service(android::base::unique_fd fd) {
|
||||
void framebuffer_service(unique_fd fd) {
|
||||
struct fbinfo fbinfo;
|
||||
unsigned int i, bsize;
|
||||
char buf[640];
|
||||
|
|
|
|||
|
|
@ -14,11 +14,8 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _DAEMON_FRAMEBUFFER_SERVICE_H_
|
||||
#define _DAEMON_FRAMEBUFFER_SERVICE_H_
|
||||
#pragma once
|
||||
|
||||
#include <android-base/unique_fd.h>
|
||||
#include "adb_unique_fd.h"
|
||||
|
||||
void framebuffer_service(android::base::unique_fd fd);
|
||||
|
||||
#endif // _DAEMON_FRAMEBUFFER_SERVICE_H_
|
||||
void framebuffer_service(unique_fd fd);
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include "sysdeps.h"
|
||||
|
||||
#include <android/fdsan.h>
|
||||
#include <errno.h>
|
||||
#include <getopt.h>
|
||||
#include <malloc.h>
|
||||
|
|
@ -177,6 +178,11 @@ int adbd_main(int server_port) {
|
|||
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
auto fdsan_level = android_fdsan_get_error_level();
|
||||
if (fdsan_level == ANDROID_FDSAN_ERROR_LEVEL_DISABLED) {
|
||||
android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE);
|
||||
}
|
||||
|
||||
init_transport_registration();
|
||||
|
||||
// We need to call this even if auth isn't enabled because the file
|
||||
|
|
|
|||
|
|
@ -215,7 +215,7 @@ static void reboot_for_remount(int fd, bool need_fsck) {
|
|||
android::base::SetProperty(ANDROID_RB_PROPERTY, reboot_cmd.c_str());
|
||||
}
|
||||
|
||||
void remount_service(android::base::unique_fd fd, const std::string& cmd) {
|
||||
void remount_service(unique_fd fd, const std::string& cmd) {
|
||||
bool user_requested_reboot = cmd != "-R";
|
||||
|
||||
if (getuid() != 0) {
|
||||
|
|
@ -251,7 +251,7 @@ void remount_service(android::base::unique_fd fd, const std::string& cmd) {
|
|||
if (user_requested_reboot) {
|
||||
if (!dedup.empty() || verity_enabled) {
|
||||
if (verity_enabled) {
|
||||
set_verity_enabled_state_service(android::base::unique_fd(dup(fd.get())), false);
|
||||
set_verity_enabled_state_service(unique_fd(dup(fd.get())), false);
|
||||
}
|
||||
reboot_for_remount(fd.get(), !dedup.empty());
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -14,14 +14,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _REMOUNT_SERVICE_H_
|
||||
#define _REMOUNT_SERVICE_H_
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <android-base/unique_fd.h>
|
||||
#include "adb_unique_fd.h"
|
||||
|
||||
bool make_block_device_writable(const std::string&);
|
||||
void remount_service(android::base::unique_fd, const std::string&);
|
||||
|
||||
#endif
|
||||
void remount_service(unique_fd, const std::string&);
|
||||
|
|
@ -132,7 +132,7 @@ static bool set_avb_verity_enabled_state(int fd, AvbOps* ops, bool enable_verity
|
|||
return true;
|
||||
}
|
||||
|
||||
void set_verity_enabled_state_service(android::base::unique_fd fd, bool enable) {
|
||||
void set_verity_enabled_state_service(unique_fd fd, bool enable) {
|
||||
bool any_changed = false;
|
||||
|
||||
// Figure out if we're using VB1.0 or VB2.0 (aka AVB) - by
|
||||
|
|
|
|||
|
|
@ -14,11 +14,8 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _DAEMON_SET_VERITY_ENABLED_STATE_SERVICE_H_
|
||||
#define _DAEMON_SET_VERITY_ENABLED_STATE_SERVICE_H_
|
||||
#pragma once
|
||||
|
||||
#include <android-base/unique_fd.h>
|
||||
#include "adb_unique_fd.h"
|
||||
|
||||
void set_verity_enabled_state_service(android::base::unique_fd fd, bool enable);
|
||||
|
||||
#endif // _DAEMON_SET_VERITY_ENABLED_STATE_SERVICE_H_
|
||||
void set_verity_enabled_state_service(unique_fd fd, bool enable);
|
||||
|
|
|
|||
|
|
@ -106,6 +106,7 @@
|
|||
#include "adb_unique_fd.h"
|
||||
#include "adb_utils.h"
|
||||
#include "security_log_tags.h"
|
||||
#include "shell_protocol.h"
|
||||
|
||||
namespace {
|
||||
|
||||
|
|
|
|||
34
adb/daemon/shell_service.h
Normal file
34
adb/daemon/shell_service.h
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (C) 2018 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
enum class SubprocessType {
|
||||
kPty,
|
||||
kRaw,
|
||||
};
|
||||
|
||||
enum class SubprocessProtocol {
|
||||
kNone,
|
||||
kShell,
|
||||
};
|
||||
|
||||
// Forks and starts a new shell subprocess. If |name| is empty an interactive
|
||||
// shell is started, otherwise |name| is executed non-interactively.
|
||||
//
|
||||
// Returns an open FD connected to the subprocess or -1 on failure.
|
||||
int StartSubprocess(const char* name, const char* terminal_type, SubprocessType type,
|
||||
SubprocessProtocol protocol);
|
||||
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include "adb.h"
|
||||
#include "adb_io.h"
|
||||
#include "shell_protocol.h"
|
||||
#include "sysdeps.h"
|
||||
|
||||
class ShellServiceTest : public ::testing::Test {
|
||||
|
|
|
|||
|
|
@ -14,34 +14,28 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _FILE_SYNC_SERVICE_H_
|
||||
#define _FILE_SYNC_SERVICE_H_
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#define MKID(a, b, c, d) ((a) | ((b) << 8) | ((c) << 16) | ((d) << 24))
|
||||
|
||||
#include <android-base/unique_fd.h>
|
||||
|
||||
#define MKID(a,b,c,d) ((a) | ((b) << 8) | ((c) << 16) | ((d) << 24))
|
||||
|
||||
#define ID_LSTAT_V1 MKID('S','T','A','T')
|
||||
#define ID_STAT_V2 MKID('S','T','A','2')
|
||||
#define ID_LSTAT_V2 MKID('L','S','T','2')
|
||||
#define ID_LIST MKID('L','I','S','T')
|
||||
#define ID_SEND MKID('S','E','N','D')
|
||||
#define ID_RECV MKID('R','E','C','V')
|
||||
#define ID_DENT MKID('D','E','N','T')
|
||||
#define ID_DONE MKID('D','O','N','E')
|
||||
#define ID_DATA MKID('D','A','T','A')
|
||||
#define ID_OKAY MKID('O','K','A','Y')
|
||||
#define ID_FAIL MKID('F','A','I','L')
|
||||
#define ID_QUIT MKID('Q','U','I','T')
|
||||
#define ID_LSTAT_V1 MKID('S', 'T', 'A', 'T')
|
||||
#define ID_STAT_V2 MKID('S', 'T', 'A', '2')
|
||||
#define ID_LSTAT_V2 MKID('L', 'S', 'T', '2')
|
||||
#define ID_LIST MKID('L', 'I', 'S', 'T')
|
||||
#define ID_SEND MKID('S', 'E', 'N', 'D')
|
||||
#define ID_RECV MKID('R', 'E', 'C', 'V')
|
||||
#define ID_DENT MKID('D', 'E', 'N', 'T')
|
||||
#define ID_DONE MKID('D', 'O', 'N', 'E')
|
||||
#define ID_DATA MKID('D', 'A', 'T', 'A')
|
||||
#define ID_OKAY MKID('O', 'K', 'A', 'Y')
|
||||
#define ID_FAIL MKID('F', 'A', 'I', 'L')
|
||||
#define ID_QUIT MKID('Q', 'U', 'I', 'T')
|
||||
|
||||
struct SyncRequest {
|
||||
uint32_t id; // ID_STAT, et cetera.
|
||||
uint32_t id; // ID_STAT, et cetera.
|
||||
uint32_t path_length; // <= 1024
|
||||
// Followed by 'path_length' bytes of path (not NUL-terminated).
|
||||
} __attribute__((packed)) ;
|
||||
} __attribute__((packed));
|
||||
|
||||
union syncmsg {
|
||||
struct __attribute__((packed)) {
|
||||
|
|
@ -81,14 +75,4 @@ union syncmsg {
|
|||
} status;
|
||||
};
|
||||
|
||||
void file_sync_service(android::base::unique_fd fd);
|
||||
bool do_sync_ls(const char* path);
|
||||
bool do_sync_push(const std::vector<const char*>& srcs, const char* dst, bool sync);
|
||||
bool do_sync_pull(const std::vector<const char*>& srcs, const char* dst,
|
||||
bool copy_attrs, const char* name=nullptr);
|
||||
|
||||
bool do_sync_sync(const std::string& lpath, const std::string& rpath, bool list_only);
|
||||
|
||||
#define SYNC_DATA_MAX (64*1024)
|
||||
|
||||
#endif
|
||||
#define SYNC_DATA_MAX (64 * 1024)
|
||||
|
|
@ -37,7 +37,6 @@
|
|||
#include <android-base/parsenetaddress.h>
|
||||
#include <android-base/stringprintf.h>
|
||||
#include <android-base/strings.h>
|
||||
#include <android-base/unique_fd.h>
|
||||
#include <cutils/sockets.h>
|
||||
|
||||
#if !ADB_HOST
|
||||
|
|
@ -49,31 +48,31 @@
|
|||
|
||||
#include "adb.h"
|
||||
#include "adb_io.h"
|
||||
#include "adb_unique_fd.h"
|
||||
#include "adb_utils.h"
|
||||
#if !ADB_HOST
|
||||
#include "daemon/file_sync_service.h"
|
||||
#include "daemon/framebuffer_service.h"
|
||||
#include "daemon/remount_service.h"
|
||||
#include "daemon/set_verity_enable_state_service.h"
|
||||
#include "daemon/shell_service.h"
|
||||
#endif
|
||||
#include "file_sync_service.h"
|
||||
#include "remount_service.h"
|
||||
#include "services.h"
|
||||
#include "shell_service.h"
|
||||
#include "socket_spec.h"
|
||||
#include "sysdeps.h"
|
||||
#include "transport.h"
|
||||
|
||||
namespace {
|
||||
|
||||
void service_bootstrap_func(std::string service_name,
|
||||
std::function<void(android::base::unique_fd)> func,
|
||||
android::base::unique_fd fd) {
|
||||
void service_bootstrap_func(std::string service_name, std::function<void(unique_fd)> func,
|
||||
unique_fd fd) {
|
||||
adb_thread_setname(android::base::StringPrintf("%s svc %d", service_name.c_str(), fd.get()));
|
||||
func(std::move(fd));
|
||||
}
|
||||
|
||||
#if !ADB_HOST
|
||||
|
||||
void restart_root_service(android::base::unique_fd fd) {
|
||||
void restart_root_service(unique_fd fd) {
|
||||
if (getuid() == 0) {
|
||||
WriteFdExactly(fd.get(), "adbd is already running as root\n");
|
||||
return;
|
||||
|
|
@ -87,7 +86,7 @@ void restart_root_service(android::base::unique_fd fd) {
|
|||
WriteFdExactly(fd.get(), "restarting adbd as root\n");
|
||||
}
|
||||
|
||||
void restart_unroot_service(android::base::unique_fd fd) {
|
||||
void restart_unroot_service(unique_fd fd) {
|
||||
if (getuid() != 0) {
|
||||
WriteFdExactly(fd.get(), "adbd not running as root\n");
|
||||
return;
|
||||
|
|
@ -96,7 +95,7 @@ void restart_unroot_service(android::base::unique_fd fd) {
|
|||
WriteFdExactly(fd.get(), "restarting adbd as non root\n");
|
||||
}
|
||||
|
||||
void restart_tcp_service(android::base::unique_fd fd, int port) {
|
||||
void restart_tcp_service(unique_fd fd, int port) {
|
||||
if (port <= 0) {
|
||||
WriteFdFmt(fd.get(), "invalid port %d\n", port);
|
||||
return;
|
||||
|
|
@ -106,12 +105,12 @@ void restart_tcp_service(android::base::unique_fd fd, int port) {
|
|||
WriteFdFmt(fd.get(), "restarting in TCP mode port: %d\n", port);
|
||||
}
|
||||
|
||||
void restart_usb_service(android::base::unique_fd fd) {
|
||||
void restart_usb_service(unique_fd fd) {
|
||||
android::base::SetProperty("service.adb.tcp.port", "0");
|
||||
WriteFdExactly(fd.get(), "restarting in USB mode\n");
|
||||
}
|
||||
|
||||
bool reboot_service_impl(android::base::unique_fd fd, const std::string& arg) {
|
||||
bool reboot_service_impl(unique_fd fd, const std::string& arg) {
|
||||
std::string reboot_arg = arg;
|
||||
bool auto_reboot = false;
|
||||
|
||||
|
|
@ -152,7 +151,7 @@ bool reboot_service_impl(android::base::unique_fd fd, const std::string& arg) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void reboot_service(android::base::unique_fd fd, const std::string& arg) {
|
||||
void reboot_service(unique_fd fd, const std::string& arg) {
|
||||
if (!reboot_service_impl(std::move(fd), arg)) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -163,7 +162,7 @@ void reboot_service(android::base::unique_fd fd, const std::string& arg) {
|
|||
}
|
||||
}
|
||||
|
||||
void reconnect_service(android::base::unique_fd fd, atransport* t) {
|
||||
void reconnect_service(unique_fd fd, atransport* t) {
|
||||
WriteFdExactly(fd, "done");
|
||||
kick_transport(t);
|
||||
}
|
||||
|
|
@ -223,12 +222,11 @@ int ShellService(const std::string& args, const atransport* transport) {
|
|||
|
||||
#endif // !ADB_HOST
|
||||
|
||||
android::base::unique_fd create_service_thread(const char* service_name,
|
||||
std::function<void(android::base::unique_fd)> func) {
|
||||
unique_fd create_service_thread(const char* service_name, std::function<void(unique_fd)> func) {
|
||||
int s[2];
|
||||
if (adb_socketpair(s)) {
|
||||
printf("cannot create service socket pair\n");
|
||||
return android::base::unique_fd();
|
||||
return unique_fd();
|
||||
}
|
||||
D("socketpair: (%d,%d)", s[0], s[1]);
|
||||
|
||||
|
|
@ -241,10 +239,10 @@ android::base::unique_fd create_service_thread(const char* service_name,
|
|||
}
|
||||
#endif // !ADB_HOST
|
||||
|
||||
std::thread(service_bootstrap_func, service_name, func, android::base::unique_fd(s[1])).detach();
|
||||
std::thread(service_bootstrap_func, service_name, func, unique_fd(s[1])).detach();
|
||||
|
||||
D("service thread started, %d:%d",s[0], s[1]);
|
||||
return android::base::unique_fd(s[0]);
|
||||
return unique_fd(s[0]);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
@ -407,7 +405,7 @@ void connect_emulator(const std::string& port_spec, std::string* response) {
|
|||
}
|
||||
}
|
||||
|
||||
static void connect_service(android::base::unique_fd fd, std::string host) {
|
||||
static void connect_service(unique_fd fd, std::string host) {
|
||||
std::string response;
|
||||
if (!strncmp(host.c_str(), "emu:", 4)) {
|
||||
connect_emulator(host.c_str() + 4, &response);
|
||||
|
|
|
|||
|
|
@ -14,16 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// This file contains classes and functionality to launch shell subprocesses
|
||||
// in adbd and communicate between those subprocesses and the adb client.
|
||||
//
|
||||
// The main features exposed here are:
|
||||
// 1. A ShellPacket class to wrap data in a simple protocol. Both adbd and
|
||||
// the adb client use this class to transmit data between them.
|
||||
// 2. Functions to launch a subprocess on the adbd side.
|
||||
|
||||
#ifndef SHELL_SERVICE_H_
|
||||
#define SHELL_SERVICE_H_
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
|
@ -124,26 +115,3 @@ class ShellProtocol {
|
|||
|
||||
DISALLOW_COPY_AND_ASSIGN(ShellProtocol);
|
||||
};
|
||||
|
||||
#if !ADB_HOST
|
||||
|
||||
enum class SubprocessType {
|
||||
kPty,
|
||||
kRaw,
|
||||
};
|
||||
|
||||
enum class SubprocessProtocol {
|
||||
kNone,
|
||||
kShell,
|
||||
};
|
||||
|
||||
// Forks and starts a new shell subprocess. If |name| is empty an interactive
|
||||
// shell is started, otherwise |name| is executed non-interactively.
|
||||
//
|
||||
// Returns an open FD connected to the subprocess or -1 on failure.
|
||||
int StartSubprocess(const char* name, const char* terminal_type,
|
||||
SubprocessType type, SubprocessProtocol protocol);
|
||||
|
||||
#endif // !ADB_HOST
|
||||
|
||||
#endif // SHELL_SERVICE_H_
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "shell_service.h"
|
||||
#include "shell_protocol.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "shell_service.h"
|
||||
#include "shell_protocol.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -1157,7 +1157,7 @@ void close_usb_devices() {
|
|||
}
|
||||
#endif // ADB_HOST
|
||||
|
||||
int register_socket_transport(int s, const char* serial, int port, int local,
|
||||
int register_socket_transport(unique_fd s, const char* serial, int port, int local,
|
||||
atransport::ReconnectCallback reconnect) {
|
||||
atransport* t = new atransport(std::move(reconnect), kCsOffline);
|
||||
|
||||
|
|
@ -1167,8 +1167,8 @@ int register_socket_transport(int s, const char* serial, int port, int local,
|
|||
serial = buf;
|
||||
}
|
||||
|
||||
D("transport: %s init'ing for socket %d, on port %d", serial, s, port);
|
||||
if (init_socket_transport(t, s, port, local) < 0) {
|
||||
D("transport: %s init'ing for socket %d, on port %d", serial, s.get(), port);
|
||||
if (init_socket_transport(t, std::move(s), port, local) < 0) {
|
||||
delete t;
|
||||
return -1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -364,7 +364,7 @@ void register_usb_transport(usb_handle* h, const char* serial,
|
|||
void connect_device(const std::string& address, std::string* response);
|
||||
|
||||
/* cause new transports to be init'd and added to the list */
|
||||
int register_socket_transport(int s, const char* serial, int port, int local,
|
||||
int register_socket_transport(unique_fd s, const char* serial, int port, int local,
|
||||
atransport::ReconnectCallback reconnect);
|
||||
|
||||
// This should only be used for transports with connection_state == kCsNoPerm.
|
||||
|
|
|
|||
|
|
@ -122,12 +122,12 @@ void connect_device(const std::string& address, std::string* response) {
|
|||
// invoked if the atransport* has already been setup. This eventually
|
||||
// calls atransport->SetConnection() with a newly created Connection*
|
||||
// that will in turn send the CNXN packet.
|
||||
return init_socket_transport(t, fd.release(), port, 0) >= 0;
|
||||
return init_socket_transport(t, std::move(fd), port, 0) >= 0;
|
||||
};
|
||||
|
||||
int ret = register_socket_transport(fd.release(), serial.c_str(), port, 0, std::move(reconnect));
|
||||
int ret =
|
||||
register_socket_transport(std::move(fd), serial.c_str(), port, 0, std::move(reconnect));
|
||||
if (ret < 0) {
|
||||
adb_close(fd);
|
||||
if (ret == -EALREADY) {
|
||||
*response = android::base::StringPrintf("already connected to %s", serial.c_str());
|
||||
} else {
|
||||
|
|
@ -140,7 +140,7 @@ void connect_device(const std::string& address, std::string* response) {
|
|||
|
||||
|
||||
int local_connect_arbitrary_ports(int console_port, int adb_port, std::string* error) {
|
||||
int fd = -1;
|
||||
unique_fd fd;
|
||||
|
||||
#if ADB_HOST
|
||||
if (find_emulator_transport_by_adb_port(adb_port) != nullptr ||
|
||||
|
|
@ -150,23 +150,22 @@ int local_connect_arbitrary_ports(int console_port, int adb_port, std::string* e
|
|||
|
||||
const char *host = getenv("ADBHOST");
|
||||
if (host) {
|
||||
fd = network_connect(host, adb_port, SOCK_STREAM, 0, error);
|
||||
fd.reset(network_connect(host, adb_port, SOCK_STREAM, 0, error));
|
||||
}
|
||||
#endif
|
||||
if (fd < 0) {
|
||||
fd = network_loopback_client(adb_port, SOCK_STREAM, error);
|
||||
fd.reset(network_loopback_client(adb_port, SOCK_STREAM, error));
|
||||
}
|
||||
|
||||
if (fd >= 0) {
|
||||
D("client: connected on remote on fd %d", fd);
|
||||
close_on_exec(fd);
|
||||
disable_tcp_nagle(fd);
|
||||
D("client: connected on remote on fd %d", fd.get());
|
||||
close_on_exec(fd.get());
|
||||
disable_tcp_nagle(fd.get());
|
||||
std::string serial = getEmulatorSerialString(console_port);
|
||||
if (register_socket_transport(fd, serial.c_str(), adb_port, 1,
|
||||
if (register_socket_transport(std::move(fd), serial.c_str(), adb_port, 1,
|
||||
[](atransport*) { return false; }) == 0) {
|
||||
return 0;
|
||||
}
|
||||
adb_close(fd);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -243,34 +242,31 @@ static void client_socket_thread(int) {
|
|||
#else // ADB_HOST
|
||||
|
||||
static void server_socket_thread(int port) {
|
||||
int serverfd, fd;
|
||||
unique_fd serverfd;
|
||||
|
||||
adb_thread_setname("server socket");
|
||||
D("transport: server_socket_thread() starting");
|
||||
serverfd = -1;
|
||||
for(;;) {
|
||||
if(serverfd == -1) {
|
||||
std::string error;
|
||||
serverfd = network_inaddr_any_server(port, SOCK_STREAM, &error);
|
||||
if(serverfd < 0) {
|
||||
D("server: cannot bind socket yet: %s", error.c_str());
|
||||
std::this_thread::sleep_for(1s);
|
||||
continue;
|
||||
}
|
||||
close_on_exec(serverfd);
|
||||
while (serverfd == -1) {
|
||||
std::string error;
|
||||
serverfd.reset(network_inaddr_any_server(port, SOCK_STREAM, &error));
|
||||
if (serverfd < 0) {
|
||||
D("server: cannot bind socket yet: %s", error.c_str());
|
||||
std::this_thread::sleep_for(1s);
|
||||
continue;
|
||||
}
|
||||
close_on_exec(serverfd.get());
|
||||
}
|
||||
|
||||
while (true) {
|
||||
D("server: trying to get new connection from %d", port);
|
||||
fd = adb_socket_accept(serverfd, nullptr, nullptr);
|
||||
if(fd >= 0) {
|
||||
D("server: new connection on fd %d", fd);
|
||||
close_on_exec(fd);
|
||||
disable_tcp_nagle(fd);
|
||||
std::string serial = android::base::StringPrintf("host-%d", fd);
|
||||
if (register_socket_transport(fd, serial.c_str(), port, 1,
|
||||
[](atransport*) { return false; }) != 0) {
|
||||
adb_close(fd);
|
||||
}
|
||||
unique_fd fd(adb_socket_accept(serverfd, nullptr, nullptr));
|
||||
if (fd >= 0) {
|
||||
D("server: new connection on fd %d", fd.get());
|
||||
close_on_exec(fd.get());
|
||||
disable_tcp_nagle(fd.get());
|
||||
std::string serial = android::base::StringPrintf("host-%d", fd.get());
|
||||
register_socket_transport(std::move(fd), serial.c_str(), port, 1,
|
||||
[](atransport*) { return false; });
|
||||
}
|
||||
}
|
||||
D("transport: server_socket_thread() exiting");
|
||||
|
|
@ -331,7 +327,6 @@ static void qemu_socket_thread(int port) {
|
|||
/* 'ok' reply from the adb QEMUD service. */
|
||||
static const char _ok_resp[] = "ok";
|
||||
|
||||
int fd;
|
||||
char tmp[256];
|
||||
char con_name[32];
|
||||
|
||||
|
|
@ -342,7 +337,7 @@ static void qemu_socket_thread(int port) {
|
|||
snprintf(con_name, sizeof(con_name), "pipe:qemud:adb:%d", port);
|
||||
|
||||
/* Connect to the adb QEMUD service. */
|
||||
fd = qemu_pipe_open(con_name);
|
||||
unique_fd fd(qemu_pipe_open(con_name));
|
||||
if (fd < 0) {
|
||||
/* This could be an older version of the emulator, that doesn't
|
||||
* implement adb QEMUD service. Fall back to the old TCP way. */
|
||||
|
|
@ -351,31 +346,28 @@ static void qemu_socket_thread(int port) {
|
|||
return;
|
||||
}
|
||||
|
||||
for(;;) {
|
||||
while (true) {
|
||||
/*
|
||||
* Wait till the host creates a new connection.
|
||||
*/
|
||||
|
||||
/* Send the 'accept' request. */
|
||||
if (WriteFdExactly(fd, _accept_req, strlen(_accept_req))) {
|
||||
if (WriteFdExactly(fd.get(), _accept_req, strlen(_accept_req))) {
|
||||
/* Wait for the response. In the response we expect 'ok' on success,
|
||||
* or 'ko' on failure. */
|
||||
if (!ReadFdExactly(fd, tmp, 2) || memcmp(tmp, _ok_resp, 2)) {
|
||||
if (!ReadFdExactly(fd.get(), tmp, 2) || memcmp(tmp, _ok_resp, 2)) {
|
||||
D("Accepting ADB host connection has failed.");
|
||||
adb_close(fd);
|
||||
} else {
|
||||
/* Host is connected. Register the transport, and start the
|
||||
* exchange. */
|
||||
std::string serial = android::base::StringPrintf("host-%d", fd);
|
||||
if (register_socket_transport(fd, serial.c_str(), port, 1,
|
||||
[](atransport*) { return false; }) != 0 ||
|
||||
!WriteFdExactly(fd, _start_req, strlen(_start_req))) {
|
||||
adb_close(fd);
|
||||
}
|
||||
std::string serial = android::base::StringPrintf("host-%d", fd.get());
|
||||
WriteFdExactly(fd.get(), _start_req, strlen(_start_req));
|
||||
register_socket_transport(std::move(fd), serial.c_str(), port, 1,
|
||||
[](atransport*) { return false; });
|
||||
}
|
||||
|
||||
/* Prepare for accepting of the next ADB host connection. */
|
||||
fd = qemu_pipe_open(con_name);
|
||||
fd.reset(qemu_pipe_open(con_name));
|
||||
if (fd < 0) {
|
||||
D("adb service become unavailable.");
|
||||
return;
|
||||
|
|
@ -476,10 +468,9 @@ atransport* find_emulator_transport_by_console_port(int console_port) {
|
|||
}
|
||||
#endif
|
||||
|
||||
int init_socket_transport(atransport* t, int s, int adb_port, int local) {
|
||||
int init_socket_transport(atransport* t, unique_fd fd, int adb_port, int local) {
|
||||
int fail = 0;
|
||||
|
||||
unique_fd fd(s);
|
||||
t->type = kTransportLocal;
|
||||
|
||||
#if ADB_HOST
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue