From 6d10f56a986945d86cbfc3a6f5a6607cb8457561 Mon Sep 17 00:00:00 2001 From: Horror Proton <107091537+horror-proton@users.noreply.github.com> Date: Wed, 16 Nov 2022 22:17:55 +0800 Subject: [PATCH 1/3] feat: add minitouch control for posix --- src/MeoAssistant/Controller.cpp | 104 +++++++++++++++++++++++++++++--- src/MeoAssistant/Controller.h | 4 +- 2 files changed, 99 insertions(+), 9 deletions(-) diff --git a/src/MeoAssistant/Controller.cpp b/src/MeoAssistant/Controller.cpp index e356f7c724..c08cbbe239 100644 --- a/src/MeoAssistant/Controller.cpp +++ b/src/MeoAssistant/Controller.cpp @@ -7,7 +7,11 @@ #include #else #include +#include #include +#ifndef __APPLE__ +#include +#endif #include #include #endif @@ -453,6 +457,12 @@ bool asst::Controller::call_and_hup_minitouch(const std::string& cmd) constexpr int PipeReadBuffSize = 4096ULL; constexpr int PipeWriteBuffSize = 64 * 1024ULL; std::string pipe_str; + + auto check_timeout = [&](const auto& start_time) -> bool { + using namespace std::chrono_literals; + return std::chrono::steady_clock::now() - start_time < 3s; + }; + #ifdef _WIN32 SECURITY_ATTRIBUTES sa_attr_inherit { .nLength = sizeof(SECURITY_ATTRIBUTES), @@ -493,16 +503,12 @@ bool asst::Controller::call_and_hup_minitouch(const std::string& cmd) } auto start_time = std::chrono::steady_clock::now(); - auto check_timeout = [&]() -> bool { - using namespace std::chrono_literals; - return std::chrono::steady_clock::now() - start_time < 3s; - }; auto pipe_buffer = std::make_unique(PipeReadBuffSize); OVERLAPPED pipeov { .hEvent = CreateEventW(nullptr, TRUE, FALSE, nullptr) }; std::ignore = ReadFile(pipe_parent_read, pipe_buffer.get(), PipeReadBuffSize, nullptr, &pipeov); - while (!need_exit() && check_timeout()) { + while (!need_exit() && check_timeout(start_time)) { if (pipe_str.find('$') != std::string::npos) { break; } @@ -518,12 +524,81 @@ bool asst::Controller::call_and_hup_minitouch(const std::string& cmd) pipe_parent_read = INVALID_HANDLE_VALUE; m_minitouch_parent_write = pipe_parent_write; -#else // !_WIN32 +#else // !_WIN32 // TODO + + pid_t pid = 0; + int pipe_to_child[2]; + int pipe_from_child[2]; + + if (::pipe(pipe_to_child)) return false; + if (::pipe(pipe_from_child)) return false; + + pid = fork(); + if (pid < 0) return false; + if (pid == 0) { // child process + if (::dup2(pipe_to_child[0], STDIN_FILENO) < 0 || ::close(pipe_to_child[1]) < 0 || + ::close(pipe_from_child[0]) < 0 || ::dup2(pipe_from_child[1], STDOUT_FILENO) < 0 || + ::dup2(pipe_from_child[1], STDERR_FILENO) < 0) { + ::exit(-1); + } + + // set stdin of child to blocking + if (int val = ::fcntl(STDIN_FILENO, F_GETFL); val != -1 && (val & O_NONBLOCK)) { + val &= ~O_NONBLOCK; + ::fcntl(STDIN_FILENO, F_SETFL, val); + } + +#ifndef __APPLE__ + ::prctl(PR_SET_PDEATHSIG, SIGTERM); +#endif + + ::execlp("/bin/sh", "sh", "-c", cmd.c_str(), nullptr); + exit(-1); + } + + if (::close(pipe_from_child[1]) < 0 || ::close(pipe_to_child[0]) < 0) { + return false; + } + + // set stdout to non blocking + if (int val = ::fcntl(pipe_from_child[0], F_GETFL); val != -1) { + val |= O_NONBLOCK; + ::fcntl(pipe_from_child[0], F_SETFL, val); + } + else + return false; + + const auto start_time = std::chrono::steady_clock::now(); + + // TODO: kill child on fail + + while (true) { + if (need_exit()) return false; + if (!check_timeout(start_time)) { + Log.info("cannot find $ from pipe_str:", Logger::separator::newline, pipe_str); + return false; + } + + if (pipe_str.find('$') != std::string::npos) { + break; + } + + char buf_from_child[PipeReadBuffSize]; + ssize_t ret = ::read(pipe_from_child[0], buf_from_child, PipeReadBuffSize); + if (ret <= 0) continue; + pipe_str.insert(pipe_str.end(), buf_from_child, buf_from_child + ret); + } + + ::dup2(::open("/dev/null", O_WRONLY), pipe_from_child[0]); + + m_minitouch_process = pid; + m_write_to_minitouch_fd = pipe_to_child[1]; + std::ignore = pipe_str; std::ignore = PipeReadBuffSize; std::ignore = PipeWriteBuffSize; - return false; + // return false; #endif // _WIN32 Log.info("pipe str", Logger::separator::newline, pipe_str); @@ -567,6 +642,10 @@ bool asst::Controller::input_to_minitouch(const std::string& cmd) return cmd.size() == written; #else + // TODO + if (m_minitouch_process < 0 || m_write_to_minitouch_fd < 0) return false; + if (::write(m_write_to_minitouch_fd, cmd.c_str(), cmd.length()) >= 0) return true; + Log.error("Failed to write to minitouch, err", errno); return false; #endif } @@ -594,7 +673,16 @@ void asst::Controller::release_minitouch(bool force) CloseHandle(m_minitouch_parent_write); m_minitouch_parent_write = nullptr; } - +#else + if (m_write_to_minitouch_fd != -1) { + ::close(m_write_to_minitouch_fd); + m_write_to_minitouch_fd = -1; + } + if (m_minitouch_process > 0) { + ::kill(m_minitouch_process, SIGTERM); + if (force) ::kill(m_minitouch_process, SIGKILL); + m_minitouch_process = -1; + } #endif // _WIN32 } diff --git a/src/MeoAssistant/Controller.h b/src/MeoAssistant/Controller.h index bf1285b216..209dd4490d 100644 --- a/src/MeoAssistant/Controller.h +++ b/src/MeoAssistant/Controller.h @@ -4,6 +4,7 @@ #include "Utils/Platform/SafeWindows.h" #include #else +#include #include #include #endif @@ -13,7 +14,6 @@ #include #include #include -#include #include #include #include @@ -173,6 +173,8 @@ namespace asst PROCESS_INFORMATION m_minitouch_process_info = { nullptr }; ASST_AUTO_DEDUCED_ZERO_INIT_END #else + ::pid_t m_minitouch_process = -1; + int m_write_to_minitouch_fd = -1; // TODO #endif From 5c7edb2d6ab290e4624e5b3cdd7c06ba00698178 Mon Sep 17 00:00:00 2001 From: Horror Proton <107091537+horror-proton@users.noreply.github.com> Date: Thu, 17 Nov 2022 21:52:50 +0800 Subject: [PATCH 2/3] feat: update controller for posix --- src/MeoAssistant/Controller.cpp | 43 +++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/src/MeoAssistant/Controller.cpp b/src/MeoAssistant/Controller.cpp index c08cbbe239..4a17b46c92 100644 --- a/src/MeoAssistant/Controller.cpp +++ b/src/MeoAssistant/Controller.cpp @@ -499,6 +499,7 @@ bool asst::Controller::call_and_hup_minitouch(const std::string& cmd) if (!create_ret) { DWORD err = GetLastError(); Log.error("Failed to create process for minitouch, err", err); + release_minitouch(true); return false; } @@ -525,17 +526,22 @@ bool asst::Controller::call_and_hup_minitouch(const std::string& cmd) m_minitouch_parent_write = pipe_parent_write; #else // !_WIN32 - // TODO - pid_t pid = 0; int pipe_to_child[2]; int pipe_from_child[2]; if (::pipe(pipe_to_child)) return false; - if (::pipe(pipe_from_child)) return false; + if (::pipe(pipe_from_child)) { + ::close(pipe_to_child[0]); + ::close(pipe_to_child[1]); + return false; + } - pid = fork(); - if (pid < 0) return false; + ::pid_t pid = fork(); + if (pid < 0) { + Log.error("failed to create process"); + return false; + } if (pid == 0) { // child process if (::dup2(pipe_to_child[0], STDIN_FILENO) < 0 || ::close(pipe_to_child[1]) < 0 || ::close(pipe_from_child[0]) < 0 || ::dup2(pipe_from_child[1], STDOUT_FILENO) < 0 || @@ -557,7 +563,11 @@ bool asst::Controller::call_and_hup_minitouch(const std::string& cmd) exit(-1); } + m_minitouch_process = pid; + m_write_to_minitouch_fd = pipe_to_child[1]; + if (::close(pipe_from_child[1]) < 0 || ::close(pipe_to_child[0]) < 0) { + release_minitouch(true); return false; } @@ -566,17 +576,20 @@ bool asst::Controller::call_and_hup_minitouch(const std::string& cmd) val |= O_NONBLOCK; ::fcntl(pipe_from_child[0], F_SETFL, val); } - else + else { + release_minitouch(true); return false; - + } const auto start_time = std::chrono::steady_clock::now(); - // TODO: kill child on fail - while (true) { - if (need_exit()) return false; + if (need_exit()) { + release_minitouch(true); + return false; + } if (!check_timeout(start_time)) { - Log.info("cannot find $ from pipe_str:", Logger::separator::newline, pipe_str); + Log.info("unable to find $ from pipe_str:", Logger::separator::newline, pipe_str); + release_minitouch(true); return false; } @@ -592,13 +605,8 @@ bool asst::Controller::call_and_hup_minitouch(const std::string& cmd) ::dup2(::open("/dev/null", O_WRONLY), pipe_from_child[0]); - m_minitouch_process = pid; - m_write_to_minitouch_fd = pipe_to_child[1]; - - std::ignore = pipe_str; - std::ignore = PipeReadBuffSize; std::ignore = PipeWriteBuffSize; - // return false; + #endif // _WIN32 Log.info("pipe str", Logger::separator::newline, pipe_str); @@ -642,7 +650,6 @@ bool asst::Controller::input_to_minitouch(const std::string& cmd) return cmd.size() == written; #else - // TODO if (m_minitouch_process < 0 || m_write_to_minitouch_fd < 0) return false; if (::write(m_write_to_minitouch_fd, cmd.c_str(), cmd.length()) >= 0) return true; Log.error("Failed to write to minitouch, err", errno); From 98e3f22bd6b3da3b9d73637b4f2cd9b878c91ece Mon Sep 17 00:00:00 2001 From: MistEO Date: Fri, 18 Nov 2022 21:44:02 +0800 Subject: [PATCH 3/3] =?UTF-8?q?chore:=20=E5=88=A0=E9=99=A4=E4=B8=80?= =?UTF-8?q?=E4=BA=9B=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/MeoAssistant/Controller.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/MeoAssistant/Controller.cpp b/src/MeoAssistant/Controller.cpp index 4a17b46c92..8d9802f1c8 100644 --- a/src/MeoAssistant/Controller.cpp +++ b/src/MeoAssistant/Controller.cpp @@ -605,8 +605,6 @@ bool asst::Controller::call_and_hup_minitouch(const std::string& cmd) ::dup2(::open("/dev/null", O_WRONLY), pipe_from_child[0]); - std::ignore = PipeWriteBuffSize; - #endif // _WIN32 Log.info("pipe str", Logger::separator::newline, pipe_str); @@ -1276,7 +1274,6 @@ bool asst::Controller::connect(const std::string& adb_path, const std::string& a { m_adb.connect = cmd_replace(adb_cfg.connect); auto connect_ret = call_command(m_adb.connect, 60LL * 1000, false /* adb 连接时不允许重试 */); - // 端口即使错误,命令仍然会返回0,TODO 对connect_result进行判断 bool is_connect_success = false; if (connect_ret) { auto& connect_str = connect_ret.value();