diff options
author | David Pursell <dpursell@google.com> | 2015-09-22 10:43:08 -0700 |
---|---|---|
committer | David Pursell <dpursell@google.com> | 2015-09-22 12:50:11 -0700 |
commit | 4e2fd36bc8c16147cab323b0418a7666812d3bc7 (patch) | |
tree | e3d5ed4e8aef55f264df808c9835d85472739f92 /adb/services.cpp | |
parent | 00ea49fc98870470b33041e0b3c3f83c91ff1007 (diff) | |
download | core-4e2fd36bc8c16147cab323b0418a7666812d3bc7.tar.gz core-4e2fd36bc8c16147cab323b0418a7666812d3bc7.tar.bz2 core-4e2fd36bc8c16147cab323b0418a7666812d3bc7.zip |
adb: add -Tt options to `adb shell`.
Adds -T (no PTY) and -t (force PTY) options to `adb shell` to mimic
ssh options. Small cleanup to send an entire FeatureSet to the adb
client at once to avoid multiple round-trips when querying multiple
features.
Known issue: humans using `adb shell -T` to start a non-PTY interactive
session may experience problems since neither side will have PTY
features like echoing or newline translation. This is probably OK for
now as the -Tt options are primarily useful for scripting.
Bug: http://b/23825231
Change-Id: I4d0df300db0abd1f7410bab59dd4d5b991babda7
Diffstat (limited to 'adb/services.cpp')
-rw-r--r-- | adb/services.cpp | 44 |
1 files changed, 35 insertions, 9 deletions
diff --git a/adb/services.cpp b/adb/services.cpp index d128efc3d..d0494ec02 100644 --- a/adb/services.cpp +++ b/adb/services.cpp @@ -194,7 +194,39 @@ void reverse_service(int fd, void* arg) adb_close(fd); } -#endif +// Shell service string can look like: +// shell[args]:[command] +// Currently the only supported args are -T (force raw) and -t (force PTY). +static int ShellService(const std::string& args, const atransport* transport) { + size_t delimiter_index = args.find(':'); + if (delimiter_index == std::string::npos) { + LOG(ERROR) << "No ':' found in shell service arguments: " << args; + return -1; + } + const std::string service_args = args.substr(0, delimiter_index); + const std::string command = args.substr(delimiter_index + 1); + + SubprocessType type; + if (service_args.empty()) { + // Default: use PTY for interactive, raw for non-interactive. + type = (command.empty() ? SubprocessType::kPty : SubprocessType::kRaw); + } else if (service_args == "-T") { + type = SubprocessType::kRaw; + } else if (service_args == "-t") { + type = SubprocessType::kPty; + } else { + LOG(ERROR) << "Unsupported shell service arguments: " << args; + return -1; + } + + SubprocessProtocol protocol = + (transport->CanUseFeature(kFeatureShell2) ? SubprocessProtocol::kShell + : SubprocessProtocol::kNone); + + return StartSubprocess(command.c_str(), type, protocol); +} + +#endif // !ADB_HOST static int create_service_thread(void (*func)(int, void *), void *cookie) { @@ -265,14 +297,8 @@ int service_to_fd(const char* name, const atransport* transport) { ret = create_service_thread(framebuffer_service, 0); } else if (!strncmp(name, "jdwp:", 5)) { ret = create_jdwp_connection_fd(atoi(name+5)); - } else if(!strncmp(name, "shell:", 6)) { - const char* args = name + 6; - // Use raw for non-interactive, PTY for interactive. - SubprocessType type = (*args ? SubprocessType::kRaw : SubprocessType::kPty); - SubprocessProtocol protocol = - (transport->CanUseFeature(kFeatureShell2) ? SubprocessProtocol::kShell - : SubprocessProtocol::kNone); - ret = StartSubprocess(args, type, protocol); + } else if(!strncmp(name, "shell", 5)) { + ret = ShellService(name + 5, transport); } else if(!strncmp(name, "exec:", 5)) { ret = StartSubprocess(name + 5, SubprocessType::kRaw, SubprocessProtocol::kNone); |