Create stdout and stderr pipes
This commit is contained in:
parent
708fc3b16a
commit
398909328c
|
@ -1,5 +1,7 @@
|
||||||
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/epoll.h>
|
#include <sys/epoll.h>
|
||||||
|
#include <system_error>
|
||||||
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
@ -7,11 +9,66 @@
|
||||||
|
|
||||||
#define EPOLL_MAX_EVENTS 10
|
#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) {
|
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);
|
this->_epoll_fd = epoll_create1(EPOLL_CLOEXEC);
|
||||||
if (this->_epoll_fd == -1) {
|
if (this->_epoll_fd == -1) {
|
||||||
throw make_system_error("epoll_create1()");
|
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);
|
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)) {
|
if (this->_epoll_fd != -1 && close(this->_epoll_fd)) {
|
||||||
log(std::string("Failed to close epoll file descriptor: ") + make_system_error("close()").what());
|
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() {
|
void LogcatThread::join() {
|
||||||
|
|
|
@ -16,5 +16,9 @@ private:
|
||||||
void _run(bool* run_event_loop);
|
void _run(bool* run_event_loop);
|
||||||
|
|
||||||
int _epoll_fd = -1;
|
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;
|
std::thread _thread;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue