diff options
author | Josh Gao <jmgao@google.com> | 2018-11-16 14:47:59 -0800 |
---|---|---|
committer | Josh Gao <jmgao@google.com> | 2018-12-12 12:54:28 -0800 |
commit | e89a55dd4115ccbd46d281b37c0d56f8a25964ec (patch) | |
tree | 0a19767b685f7ea15fb84e79c6e8112f15b16b76 /adb/client/commandline.cpp | |
parent | ce5ce87a66addb5f6a1170a0e0958e63dd30d78c (diff) | |
download | system_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.cpp | 38 |
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 */ |