summaryrefslogtreecommitdiffstats
path: root/adb/client/commandline.cpp
diff options
context:
space:
mode:
authorJosh Gao <jmgao@google.com>2018-11-16 14:47:59 -0800
committerJosh Gao <jmgao@google.com>2018-12-12 12:54:28 -0800
commite89a55dd4115ccbd46d281b37c0d56f8a25964ec (patch)
tree0a19767b685f7ea15fb84e79c6e8112f15b16b76 /adb/client/commandline.cpp
parentce5ce87a66addb5f6a1170a0e0958e63dd30d78c (diff)
downloadsystem_core-e89a55dd4115ccbd46d281b37c0d56f8a25964ec.tar.gz
system_core-e89a55dd4115ccbd46d281b37c0d56f8a25964ec.tar.bz2
system_core-e89a55dd4115ccbd46d281b37c0d56f8a25964ec.zip
adb: make `adb raw` bidirectional.
Test: adb raw shell: Change-Id: I973f42c55c71ffd125e58f76d29100a2d5b0c308
Diffstat (limited to 'adb/client/commandline.cpp')
-rw-r--r--adb/client/commandline.cpp38
1 files changed, 37 insertions, 1 deletions
diff --git a/adb/client/commandline.cpp b/adb/client/commandline.cpp
index 95e66ae84..c8e834e67 100644
--- a/adb/client/commandline.cpp
+++ b/adb/client/commandline.cpp
@@ -1275,6 +1275,42 @@ static int adb_connect_command(const std::string& command) {
return 0;
}
+static int adb_connect_command_bidirectional(const std::string& command) {
+ std::string error;
+ int fd = adb_connect(command, &error);
+ if (fd < 0) {
+ fprintf(stderr, "error: %s\n", error.c_str());
+ return 1;
+ }
+
+ static constexpr auto forward = [](int src, int sink, bool exit_on_end) {
+ char buf[4096];
+ while (true) {
+ int rc = adb_read(src, buf, sizeof(buf));
+ if (rc == 0) {
+ if (exit_on_end) {
+ exit(0);
+ } else {
+ adb_shutdown(sink, SHUT_WR);
+ }
+ return;
+ } else if (rc < 0) {
+ perror_exit("read failed");
+ }
+ if (!WriteFdExactly(sink, buf, rc)) {
+ perror_exit("write failed");
+ }
+ }
+ };
+
+ std::thread read(forward, fd, STDOUT_FILENO, true);
+ std::thread write(forward, STDIN_FILENO, fd, false);
+ read.join();
+ write.join();
+ adb_close(fd);
+ return 0;
+}
+
static int adb_query_command(const std::string& command) {
std::string result;
std::string error;
@@ -1766,7 +1802,7 @@ int adb_commandline(int argc, const char** argv) {
if (argc != 2) {
error_exit("usage: adb raw SERVICE");
}
- return adb_connect_command(argv[1]);
+ return adb_connect_command_bidirectional(argv[1]);
}
/* "adb /?" is a common idiom under Windows */