Merge "Pass screen to the device." am: c40f213b67
am: 1fd0ea9e0e
* commit '1fd0ea9e0ef5ac01d23c8019c854763693dea6f1':
Pass $TERM to the device.
This commit is contained in:
commit
cc1ef0afae
5 changed files with 37 additions and 24 deletions
|
|
@ -595,6 +595,10 @@ static std::string ShellServiceString(bool use_shell_protocol,
|
||||||
if (!type_arg.empty()) {
|
if (!type_arg.empty()) {
|
||||||
args.push_back(type_arg);
|
args.push_back(type_arg);
|
||||||
}
|
}
|
||||||
|
const char* terminal_type = getenv("TERM");
|
||||||
|
if (terminal_type != nullptr) {
|
||||||
|
args.push_back(std::string("TERM=") + terminal_type);
|
||||||
|
}
|
||||||
|
|
||||||
// Shell service string can look like: shell[,arg1,arg2,...]:[command].
|
// Shell service string can look like: shell[,arg1,arg2,...]:[command].
|
||||||
return android::base::StringPrintf("shell%s%s:%s",
|
return android::base::StringPrintf("shell%s%s:%s",
|
||||||
|
|
@ -1029,8 +1033,7 @@ static int send_shell_command(TransportType transport_type, const char* serial,
|
||||||
use_shell_protocol = CanUseFeature(features, kFeatureShell2);
|
use_shell_protocol = CanUseFeature(features, kFeatureShell2);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string service_string = ShellServiceString(use_shell_protocol, "",
|
std::string service_string = ShellServiceString(use_shell_protocol, "", command);
|
||||||
command);
|
|
||||||
|
|
||||||
int fd;
|
int fd;
|
||||||
while (true) {
|
while (true) {
|
||||||
|
|
|
||||||
|
|
@ -213,9 +213,11 @@ static int ShellService(const std::string& args, const atransport* transport) {
|
||||||
// Defaults:
|
// Defaults:
|
||||||
// PTY for interactive, raw for non-interactive.
|
// PTY for interactive, raw for non-interactive.
|
||||||
// No protocol.
|
// No protocol.
|
||||||
|
// $TERM set to "dumb".
|
||||||
SubprocessType type(command.empty() ? SubprocessType::kPty
|
SubprocessType type(command.empty() ? SubprocessType::kPty
|
||||||
: SubprocessType::kRaw);
|
: SubprocessType::kRaw);
|
||||||
SubprocessProtocol protocol = SubprocessProtocol::kNone;
|
SubprocessProtocol protocol = SubprocessProtocol::kNone;
|
||||||
|
std::string terminal_type = "dumb";
|
||||||
|
|
||||||
for (const std::string& arg : android::base::Split(service_args, ",")) {
|
for (const std::string& arg : android::base::Split(service_args, ",")) {
|
||||||
if (arg == kShellServiceArgRaw) {
|
if (arg == kShellServiceArgRaw) {
|
||||||
|
|
@ -224,14 +226,15 @@ static int ShellService(const std::string& args, const atransport* transport) {
|
||||||
type = SubprocessType::kPty;
|
type = SubprocessType::kPty;
|
||||||
} else if (arg == kShellServiceArgShellProtocol) {
|
} else if (arg == kShellServiceArgShellProtocol) {
|
||||||
protocol = SubprocessProtocol::kShell;
|
protocol = SubprocessProtocol::kShell;
|
||||||
}
|
} else if (android::base::StartsWith(arg, "TERM=")) {
|
||||||
else if (!arg.empty()) {
|
terminal_type = arg.substr(5);
|
||||||
LOG(ERROR) << "Unsupported shell service arguments: " << args;
|
} else if (!arg.empty()) {
|
||||||
return -1;
|
// This is not an error to allow for future expansion.
|
||||||
|
LOG(WARNING) << "Ignoring unknown shell service argument: " << arg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return StartSubprocess(command.c_str(), type, protocol);
|
return StartSubprocess(command.c_str(), terminal_type.c_str(), type, protocol);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // !ADB_HOST
|
#endif // !ADB_HOST
|
||||||
|
|
@ -308,8 +311,7 @@ int service_to_fd(const char* name, const atransport* transport) {
|
||||||
} else if(!strncmp(name, "shell", 5)) {
|
} else if(!strncmp(name, "shell", 5)) {
|
||||||
ret = ShellService(name + 5, transport);
|
ret = ShellService(name + 5, transport);
|
||||||
} else if(!strncmp(name, "exec:", 5)) {
|
} else if(!strncmp(name, "exec:", 5)) {
|
||||||
ret = StartSubprocess(name + 5, SubprocessType::kRaw,
|
ret = StartSubprocess(name + 5, nullptr, SubprocessType::kRaw, SubprocessProtocol::kNone);
|
||||||
SubprocessProtocol::kNone);
|
|
||||||
} else if(!strncmp(name, "sync:", 5)) {
|
} else if(!strncmp(name, "sync:", 5)) {
|
||||||
ret = create_service_thread(file_sync_service, NULL);
|
ret = create_service_thread(file_sync_service, NULL);
|
||||||
} else if(!strncmp(name, "remount:", 8)) {
|
} else if(!strncmp(name, "remount:", 8)) {
|
||||||
|
|
@ -325,9 +327,9 @@ int service_to_fd(const char* name, const atransport* transport) {
|
||||||
} else if(!strncmp(name, "backup:", 7)) {
|
} else if(!strncmp(name, "backup:", 7)) {
|
||||||
ret = StartSubprocess(android::base::StringPrintf("/system/bin/bu backup %s",
|
ret = StartSubprocess(android::base::StringPrintf("/system/bin/bu backup %s",
|
||||||
(name + 7)).c_str(),
|
(name + 7)).c_str(),
|
||||||
SubprocessType::kRaw, SubprocessProtocol::kNone);
|
nullptr, SubprocessType::kRaw, SubprocessProtocol::kNone);
|
||||||
} else if(!strncmp(name, "restore:", 8)) {
|
} else if(!strncmp(name, "restore:", 8)) {
|
||||||
ret = StartSubprocess("/system/bin/bu restore", SubprocessType::kRaw,
|
ret = StartSubprocess("/system/bin/bu restore", nullptr, SubprocessType::kRaw,
|
||||||
SubprocessProtocol::kNone);
|
SubprocessProtocol::kNone);
|
||||||
} else if(!strncmp(name, "tcpip:", 6)) {
|
} else if(!strncmp(name, "tcpip:", 6)) {
|
||||||
int port;
|
int port;
|
||||||
|
|
|
||||||
|
|
@ -175,8 +175,8 @@ bool CreateSocketpair(ScopedFd* fd1, ScopedFd* fd2) {
|
||||||
|
|
||||||
class Subprocess {
|
class Subprocess {
|
||||||
public:
|
public:
|
||||||
Subprocess(const std::string& command, SubprocessType type,
|
Subprocess(const std::string& command, const char* terminal_type,
|
||||||
SubprocessProtocol protocol);
|
SubprocessType type, SubprocessProtocol protocol);
|
||||||
~Subprocess();
|
~Subprocess();
|
||||||
|
|
||||||
const std::string& command() const { return command_; }
|
const std::string& command() const { return command_; }
|
||||||
|
|
@ -207,6 +207,7 @@ class Subprocess {
|
||||||
ScopedFd* PassOutput(ScopedFd* sfd, ShellProtocol::Id id);
|
ScopedFd* PassOutput(ScopedFd* sfd, ShellProtocol::Id id);
|
||||||
|
|
||||||
const std::string command_;
|
const std::string command_;
|
||||||
|
const std::string terminal_type_;
|
||||||
SubprocessType type_;
|
SubprocessType type_;
|
||||||
SubprocessProtocol protocol_;
|
SubprocessProtocol protocol_;
|
||||||
pid_t pid_ = -1;
|
pid_t pid_ = -1;
|
||||||
|
|
@ -220,9 +221,12 @@ class Subprocess {
|
||||||
DISALLOW_COPY_AND_ASSIGN(Subprocess);
|
DISALLOW_COPY_AND_ASSIGN(Subprocess);
|
||||||
};
|
};
|
||||||
|
|
||||||
Subprocess::Subprocess(const std::string& command, SubprocessType type,
|
Subprocess::Subprocess(const std::string& command, const char* terminal_type,
|
||||||
SubprocessProtocol protocol)
|
SubprocessType type, SubprocessProtocol protocol)
|
||||||
: command_(command), type_(type), protocol_(protocol) {
|
: command_(command),
|
||||||
|
terminal_type_(terminal_type ? terminal_type : ""),
|
||||||
|
type_(type),
|
||||||
|
protocol_(protocol) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Subprocess::~Subprocess() {
|
Subprocess::~Subprocess() {
|
||||||
|
|
@ -290,6 +294,9 @@ bool Subprocess::ForkAndExec() {
|
||||||
setenv("SHELL", pw->pw_shell, 1);
|
setenv("SHELL", pw->pw_shell, 1);
|
||||||
setenv("USER", pw->pw_name, 1);
|
setenv("USER", pw->pw_name, 1);
|
||||||
}
|
}
|
||||||
|
if (!terminal_type_.empty()) {
|
||||||
|
setenv("TERM", terminal_type_.c_str(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
if (is_interactive()) {
|
if (is_interactive()) {
|
||||||
execl(_PATH_BSHELL, _PATH_BSHELL, "-", nullptr);
|
execl(_PATH_BSHELL, _PATH_BSHELL, "-", nullptr);
|
||||||
|
|
@ -644,13 +651,14 @@ void Subprocess::WaitForExit() {
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
int StartSubprocess(const char *name, SubprocessType type,
|
int StartSubprocess(const char* name, const char* terminal_type,
|
||||||
SubprocessProtocol protocol) {
|
SubprocessType type, SubprocessProtocol protocol) {
|
||||||
D("starting %s subprocess (protocol=%s): '%s'",
|
D("starting %s subprocess (protocol=%s, TERM=%s): '%s'",
|
||||||
type == SubprocessType::kRaw ? "raw" : "PTY",
|
type == SubprocessType::kRaw ? "raw" : "PTY",
|
||||||
protocol == SubprocessProtocol::kNone ? "none" : "shell", name);
|
protocol == SubprocessProtocol::kNone ? "none" : "shell",
|
||||||
|
terminal_type, name);
|
||||||
|
|
||||||
Subprocess* subprocess = new Subprocess(name, type, protocol);
|
Subprocess* subprocess = new Subprocess(name, terminal_type, type, protocol);
|
||||||
if (!subprocess) {
|
if (!subprocess) {
|
||||||
LOG(ERROR) << "failed to allocate new subprocess";
|
LOG(ERROR) << "failed to allocate new subprocess";
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
||||||
|
|
@ -141,8 +141,8 @@ enum class SubprocessProtocol {
|
||||||
// shell is started, otherwise |name| is executed non-interactively.
|
// shell is started, otherwise |name| is executed non-interactively.
|
||||||
//
|
//
|
||||||
// Returns an open FD connected to the subprocess or -1 on failure.
|
// Returns an open FD connected to the subprocess or -1 on failure.
|
||||||
int StartSubprocess(const char* name, SubprocessType type,
|
int StartSubprocess(const char* name, const char* terminal_type,
|
||||||
SubprocessProtocol protocol);
|
SubprocessType type, SubprocessProtocol protocol);
|
||||||
|
|
||||||
#endif // !ADB_HOST
|
#endif // !ADB_HOST
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ void ShellServiceTest::StartTestSubprocess(
|
||||||
SHELL_EXIT_NOTIFY_FD = fd[0];
|
SHELL_EXIT_NOTIFY_FD = fd[0];
|
||||||
shell_exit_receiver_fd_ = fd[1];
|
shell_exit_receiver_fd_ = fd[1];
|
||||||
|
|
||||||
subprocess_fd_ = StartSubprocess(command, type, protocol);
|
subprocess_fd_ = StartSubprocess(command, nullptr, type, protocol);
|
||||||
ASSERT_TRUE(subprocess_fd_ >= 0);
|
ASSERT_TRUE(subprocess_fd_ >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue