Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e257772b authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Adding EXEC version of calling ABB."

parents ed7458e0 05626c18
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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
+13 −1
Original line number Diff line number Diff line
@@ -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;
+1 −1
Original line number Diff line number Diff line
@@ -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);
}
+2 −3
Original line number Diff line number Diff line
@@ -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

+46 −65
Original line number Diff line number Diff line
@@ -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,44 +385,11 @@ 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";
    if (!ConnectProtocolEndpoints(error)) {
        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;
                }
            }
        }
    }

    D("subprocess parent: completed");
    return true;
}
@@ -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,10 +416,29 @@ bool Subprocess::ExecInProcess(Command command, std::string* _Nonnull error) {
    D("execinprocess: stdin/stdout FD = %d, stderr FD = %d", stdinout_sfd_.get(),
      stderr_sfd_.get());

    if (!ConnectProtocolEndpoints(error)) {
        return false;
    }

    std::thread([inout_sfd = std::move(child_stdinout_sfd), err_sfd = std::move(child_stderr_sfd),
                 command = std::move(command),
                 args = command_]() { command(args, inout_sfd, inout_sfd, err_sfd); })
            .detach();

    D("execinprocess: completed");
    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));
            *error = android::base::StringPrintf(
                    "failed to create socketpair to intercept data: %s", strerror(errno));
            return false;
        }
        D("protocol FD = %d", protocol_sfd_.get());
@@ -470,19 +457,14 @@ bool Subprocess::ExecInProcess(Command command, std::string* _Nonnull error) {
        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);
                    *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),
                 args = command_]() { command(args, inout_sfd, inout_sfd, err_sfd); })
            .detach();

    D("execinprocess: completed");
    return true;
}

@@ -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,
Loading