From 398909328cd0d3390f6e0943b54a26bfb382a68d Mon Sep 17 00:00:00 2001 From: blankie Date: Tue, 17 Jan 2023 21:44:17 +0700 Subject: [PATCH] Create stdout and stderr pipes --- logcat_thread.cpp | 69 +++++++++++++++++++++++++++++++++++++++++++++++ logcat_thread.h | 4 +++ 2 files changed, 73 insertions(+) diff --git a/logcat_thread.cpp b/logcat_thread.cpp index c11a33c..531c94c 100644 --- a/logcat_thread.cpp +++ b/logcat_thread.cpp @@ -1,5 +1,7 @@ +#include #include #include +#include #include "log.h" #include "misc.h" @@ -7,11 +9,66 @@ #define EPOLL_MAX_EVENTS 10 +static void mark_nonblock(int fd) { + int flags = fcntl(fd, F_GETFL); + if (flags < 0) { + throw make_system_error("fcntl(fd, F_GETFL)"); + } + if (!(flags & O_NONBLOCK) && fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) { + throw make_system_error("fcntl(fd, F_SETFL)"); + } +} + + LogcatThread::LogcatThread(bool* run_event_loop) { + int fds[2]; + struct epoll_event event = {.events = EPOLLIN | EPOLLET}; + + if (pipe(fds)) { + std::system_error e = make_system_error("pipe() for stdout"); + this->~LogcatThread(); + throw e; + } + this->_stdout_read_fd = fds[0]; + this->_stdout_write_fd = fds[1]; + try { + mark_nonblock(this->_stdout_read_fd); + } catch (const std::exception& e) { + this->~LogcatThread(); + throw; + } + + if (pipe(fds)) { + std::system_error e = make_system_error("pipe() for stderr"); + this->~LogcatThread(); + throw e; + } + this->_stderr_read_fd = fds[0]; + this->_stderr_write_fd = fds[1]; + try { + mark_nonblock(this->_stderr_read_fd); + } catch (const std::exception& e) { + this->~LogcatThread(); + throw; + } + this->_epoll_fd = epoll_create1(EPOLL_CLOEXEC); if (this->_epoll_fd == -1) { throw make_system_error("epoll_create1()"); } + event.data.fd = this->_stdout_read_fd; + if (epoll_ctl(this->_epoll_fd, EPOLL_CTL_ADD, this->_stdout_read_fd, &event)) { + std::system_error e = make_system_error("epoll_ctl() for stdout"); + this->~LogcatThread(); + throw e; + } + event.data.fd = this->_stderr_read_fd; + if (epoll_ctl(this->_epoll_fd, EPOLL_CTL_ADD, this->_stderr_read_fd, &event)) { + std::system_error e = make_system_error("epoll_ctl() for stderr"); + this->~LogcatThread(); + throw e; + } + this->_thread = std::thread(&LogcatThread::_run, this, run_event_loop); } @@ -19,6 +76,18 @@ LogcatThread::~LogcatThread() { if (this->_epoll_fd != -1 && close(this->_epoll_fd)) { log(std::string("Failed to close epoll file descriptor: ") + make_system_error("close()").what()); } + if (this->_stdout_read_fd != -1 && close(this->_stdout_read_fd)) { + log(std::string("Failed to close stdout read pipe: ") + make_system_error("close()").what()); + } + if (this->_stdout_write_fd != -1 && close(this->_stdout_write_fd)) { + log(std::string("Failed to close stdout write pipe: ") + make_system_error("close()").what()); + } + if (this->_stderr_read_fd != -1 && close(this->_stderr_read_fd)) { + log(std::string("Failed to close stderr read pipe: ") + make_system_error("close()").what()); + } + if (this->_stderr_write_fd != -1 && close(this->_stderr_write_fd)) { + log(std::string("Failed to close stderr write pipe: ") + make_system_error("close()").what()); + } } void LogcatThread::join() { diff --git a/logcat_thread.h b/logcat_thread.h index cdd6ae8..7765281 100644 --- a/logcat_thread.h +++ b/logcat_thread.h @@ -16,5 +16,9 @@ private: void _run(bool* run_event_loop); int _epoll_fd = -1; + int _stdout_read_fd = -1; + int _stdout_write_fd = -1; + int _stderr_read_fd = -1; + int _stderr_write_fd = -1; std::thread _thread; };