Merge "Adding EXEC version of calling ABB."
am: e257772bb2
Change-Id: I2ab1da67fe0b2030d55bf1129aa6e7dd22b85f9a
This commit is contained in:
commit
b590a59bc4
7 changed files with 66 additions and 72 deletions
|
@ -153,7 +153,7 @@ asocket* daemon_service_to_socket(std::string_view name);
|
|||
#endif
|
||||
|
||||
#if !ADB_HOST
|
||||
unique_fd execute_binder_command(std::string_view command);
|
||||
unique_fd execute_abb_command(std::string_view command);
|
||||
#endif
|
||||
|
||||
#if !ADB_HOST
|
||||
|
|
|
@ -85,7 +85,19 @@ int main(int argc, char* const argv[]) {
|
|||
break;
|
||||
}
|
||||
|
||||
unique_fd result = StartCommandInProcess(std::move(data), &execCmd);
|
||||
std::string_view name = data;
|
||||
auto protocol = SubprocessProtocol::kShell;
|
||||
if (name.starts_with("abb:")) {
|
||||
name.remove_prefix(strlen("abb:"));
|
||||
protocol = SubprocessProtocol::kShell;
|
||||
} else if (name.starts_with("abb_exec:")) {
|
||||
name.remove_prefix(strlen("abb_exec:"));
|
||||
protocol = SubprocessProtocol::kNone;
|
||||
} else {
|
||||
LOG(FATAL) << "Unknown command prefix for abb: " << data;
|
||||
}
|
||||
|
||||
unique_fd result = StartCommandInProcess(std::string(name), &execCmd, protocol);
|
||||
if (android::base::SendFileDescriptors(fd, "", 1, result.get()) != 1) {
|
||||
PLOG(ERROR) << "Failed to send an inprocess fd for command: " << data;
|
||||
break;
|
||||
|
|
|
@ -86,6 +86,6 @@ unique_fd AbbProcess::startAbbProcess(unique_fd* error_fd) {
|
|||
|
||||
} // namespace
|
||||
|
||||
unique_fd execute_binder_command(std::string_view command) {
|
||||
unique_fd execute_abb_command(std::string_view command) {
|
||||
return abbp->sendCommand(command);
|
||||
}
|
||||
|
|
|
@ -244,9 +244,8 @@ asocket* daemon_service_to_socket(std::string_view name) {
|
|||
|
||||
unique_fd daemon_service_to_fd(std::string_view name, atransport* transport) {
|
||||
#if defined(__ANDROID__) && !defined(__ANDROID_RECOVERY__)
|
||||
if (name.starts_with("abb:")) {
|
||||
name.remove_prefix(strlen("abb:"));
|
||||
return execute_binder_command(name);
|
||||
if (name.starts_with("abb:") || name.starts_with("abb_exec:")) {
|
||||
return execute_abb_command(name);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -170,6 +170,8 @@ class Subprocess {
|
|||
// Opens the file at |pts_name|.
|
||||
int OpenPtyChildFd(const char* pts_name, unique_fd* error_sfd);
|
||||
|
||||
bool ConnectProtocolEndpoints(std::string* _Nonnull error);
|
||||
|
||||
static void ThreadHandler(void* userdata);
|
||||
void PassDataStreams();
|
||||
void WaitForExit();
|
||||
|
@ -383,42 +385,9 @@ bool Subprocess::ForkAndExec(std::string* error) {
|
|||
}
|
||||
|
||||
D("subprocess parent: exec completed");
|
||||
if (protocol_ == SubprocessProtocol::kNone) {
|
||||
// No protocol: all streams pass through the stdinout FD and hook
|
||||
// directly into the local socket for raw data transfer.
|
||||
local_socket_sfd_.reset(stdinout_sfd_.release());
|
||||
} else {
|
||||
// Shell protocol: create another socketpair to intercept data.
|
||||
if (!CreateSocketpair(&protocol_sfd_, &local_socket_sfd_)) {
|
||||
*error = android::base::StringPrintf(
|
||||
"failed to create socketpair to intercept data: %s", strerror(errno));
|
||||
kill(pid_, SIGKILL);
|
||||
return false;
|
||||
}
|
||||
D("protocol FD = %d", protocol_sfd_.get());
|
||||
|
||||
input_ = std::make_unique<ShellProtocol>(protocol_sfd_);
|
||||
output_ = std::make_unique<ShellProtocol>(protocol_sfd_);
|
||||
if (!input_ || !output_) {
|
||||
*error = "failed to allocate shell protocol objects";
|
||||
kill(pid_, SIGKILL);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Don't let reads/writes to the subprocess block our thread. This isn't
|
||||
// likely but could happen under unusual circumstances, such as if we
|
||||
// write a ton of data to stdin but the subprocess never reads it and
|
||||
// the pipe fills up.
|
||||
for (int fd : {stdinout_sfd_.get(), stderr_sfd_.get()}) {
|
||||
if (fd >= 0) {
|
||||
if (!set_file_block_mode(fd, false)) {
|
||||
*error = android::base::StringPrintf(
|
||||
"failed to set non-blocking mode for fd %d", fd);
|
||||
kill(pid_, SIGKILL);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!ConnectProtocolEndpoints(error)) {
|
||||
kill(pid_, SIGKILL);
|
||||
return false;
|
||||
}
|
||||
|
||||
D("subprocess parent: completed");
|
||||
|
@ -429,7 +398,6 @@ bool Subprocess::ExecInProcess(Command command, std::string* _Nonnull error) {
|
|||
unique_fd child_stdinout_sfd, child_stderr_sfd;
|
||||
|
||||
CHECK(type_ == SubprocessType::kRaw);
|
||||
CHECK(protocol_ == SubprocessProtocol::kShell);
|
||||
|
||||
__android_log_security_bswrite(SEC_TAG_ADB_SHELL_CMD, command_.c_str());
|
||||
|
||||
|
@ -448,34 +416,9 @@ bool Subprocess::ExecInProcess(Command command, std::string* _Nonnull error) {
|
|||
D("execinprocess: stdin/stdout FD = %d, stderr FD = %d", stdinout_sfd_.get(),
|
||||
stderr_sfd_.get());
|
||||
|
||||
// Required for shell protocol: create another socketpair to intercept data.
|
||||
if (!CreateSocketpair(&protocol_sfd_, &local_socket_sfd_)) {
|
||||
*error = android::base::StringPrintf("failed to create socketpair to intercept data: %s",
|
||||
strerror(errno));
|
||||
if (!ConnectProtocolEndpoints(error)) {
|
||||
return false;
|
||||
}
|
||||
D("protocol FD = %d", protocol_sfd_.get());
|
||||
|
||||
input_ = std::make_unique<ShellProtocol>(protocol_sfd_);
|
||||
output_ = std::make_unique<ShellProtocol>(protocol_sfd_);
|
||||
if (!input_ || !output_) {
|
||||
*error = "failed to allocate shell protocol objects";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Don't let reads/writes to the subprocess block our thread. This isn't
|
||||
// likely but could happen under unusual circumstances, such as if we
|
||||
// write a ton of data to stdin but the subprocess never reads it and
|
||||
// the pipe fills up.
|
||||
for (int fd : {stdinout_sfd_.get(), stderr_sfd_.get()}) {
|
||||
if (fd >= 0) {
|
||||
if (!set_file_block_mode(fd, false)) {
|
||||
*error = android::base::StringPrintf("failed to set non-blocking mode for fd %d",
|
||||
fd);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::thread([inout_sfd = std::move(child_stdinout_sfd), err_sfd = std::move(child_stderr_sfd),
|
||||
command = std::move(command),
|
||||
|
@ -486,6 +429,45 @@ bool Subprocess::ExecInProcess(Command command, std::string* _Nonnull error) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Subprocess::ConnectProtocolEndpoints(std::string* _Nonnull error) {
|
||||
if (protocol_ == SubprocessProtocol::kNone) {
|
||||
// No protocol: all streams pass through the stdinout FD and hook
|
||||
// directly into the local socket for raw data transfer.
|
||||
local_socket_sfd_.reset(stdinout_sfd_.release());
|
||||
} else {
|
||||
// Required for shell protocol: create another socketpair to intercept data.
|
||||
if (!CreateSocketpair(&protocol_sfd_, &local_socket_sfd_)) {
|
||||
*error = android::base::StringPrintf(
|
||||
"failed to create socketpair to intercept data: %s", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
D("protocol FD = %d", protocol_sfd_.get());
|
||||
|
||||
input_ = std::make_unique<ShellProtocol>(protocol_sfd_);
|
||||
output_ = std::make_unique<ShellProtocol>(protocol_sfd_);
|
||||
if (!input_ || !output_) {
|
||||
*error = "failed to allocate shell protocol objects";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Don't let reads/writes to the subprocess block our thread. This isn't
|
||||
// likely but could happen under unusual circumstances, such as if we
|
||||
// write a ton of data to stdin but the subprocess never reads it and
|
||||
// the pipe fills up.
|
||||
for (int fd : {stdinout_sfd_.get(), stderr_sfd_.get()}) {
|
||||
if (fd >= 0) {
|
||||
if (!set_file_block_mode(fd, false)) {
|
||||
*error = android::base::StringPrintf(
|
||||
"failed to set non-blocking mode for fd %d", fd);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Subprocess::StartThread(std::unique_ptr<Subprocess> subprocess, std::string* error) {
|
||||
Subprocess* raw = subprocess.release();
|
||||
std::thread(ThreadHandler, raw).detach();
|
||||
|
@ -863,12 +845,11 @@ unique_fd StartSubprocess(std::string name, const char* terminal_type, Subproces
|
|||
return local_socket;
|
||||
}
|
||||
|
||||
unique_fd StartCommandInProcess(std::string name, Command command) {
|
||||
unique_fd StartCommandInProcess(std::string name, Command command, SubprocessProtocol protocol) {
|
||||
LOG(INFO) << "StartCommandInProcess(" << dump_hex(name.data(), name.size()) << ")";
|
||||
|
||||
constexpr auto terminal_type = "";
|
||||
constexpr auto type = SubprocessType::kRaw;
|
||||
constexpr auto protocol = SubprocessProtocol::kShell;
|
||||
constexpr auto make_pty_raw = false;
|
||||
|
||||
auto subprocess = std::make_unique<Subprocess>(std::move(name), terminal_type, type, protocol,
|
||||
|
|
|
@ -49,7 +49,7 @@ unique_fd StartSubprocess(std::string name, const char* terminal_type, Subproces
|
|||
//
|
||||
// Returns an open FD connected to the thread or -1 on failure.
|
||||
using Command = int(std::string_view args, int in, int out, int err);
|
||||
unique_fd StartCommandInProcess(std::string name, Command command);
|
||||
unique_fd StartCommandInProcess(std::string name, Command command, SubprocessProtocol protocol);
|
||||
|
||||
// Create a pipe containing the error.
|
||||
unique_fd ReportError(SubprocessProtocol protocol, const std::string& message);
|
||||
|
|
|
@ -72,6 +72,7 @@ const char* const kFeatureApex = "apex";
|
|||
const char* const kFeatureFixedPushMkdir = "fixed_push_mkdir";
|
||||
const char* const kFeatureAbb = "abb";
|
||||
const char* const kFeatureFixedPushSymlinkTimestamp = "fixed_push_symlink_timestamp";
|
||||
const char* const kFeatureAbbExec = "abb_exec";
|
||||
|
||||
namespace {
|
||||
|
||||
|
@ -1013,6 +1014,7 @@ const FeatureSet& supported_features() {
|
|||
kFeatureApex,
|
||||
kFeatureAbb,
|
||||
kFeatureFixedPushSymlinkTimestamp,
|
||||
kFeatureAbbExec,
|
||||
// Increment ADB_SERVER_VERSION when adding a feature that adbd needs
|
||||
// to know about. Otherwise, the client can be stuck running an old
|
||||
// version of the server even after upgrading their copy of adb.
|
||||
|
|
Loading…
Reference in a new issue