Program Listing for File fifo_writer.cpp
↰ Return to documentation for file (monitoring/fifo_writer.cpp)
#include "fifo_writer.hpp"
#include <sys/stat.h>
#include <ers/Severity.h>
FIFOWriter::FIFOWriter(const std::string& fifoname) {
try{
validate_fifo(fifoname);
} catch(const monitoring_log::fifo_issue &er) {
ers::error(er);
return;
}
signal(SIGPIPE, SIG_IGN);
// Opening a FIFO for write-only will fail if there is no reader, so we fake a reader
int tmpfd = open(fifoname.c_str(), O_RDONLY | O_NDELAY);
m_fifo_fd = open(fifoname.c_str(), O_WRONLY | O_NDELAY | O_NONBLOCK);
if (m_fifo_fd < 0) {
ers::error(monitoring_log::fifo_issue(std::format("Cannot open monitoring FIFO %s, error %d: %s", fifoname, errno, strerror(errno))));
}
ERS_INFO(std::format("Monitoring FIFO {} opened, fd={}", fifoname, m_fifo_fd));
fcntl(m_fifo_fd, F_SETPIPE_SZ, 1048576);
close(tmpfd);
}
FIFOWriter::~FIFOWriter() {
close(m_fifo_fd);
}
void FIFOWriter::write_message(const nlohmann::json& message) {
if (m_fifo_fd == -1) {
return;
}
const std::string msg = std::format("{}\n", message.dump());
const char* msg_ptr = msg.c_str();
size_t bytes_written = 0;
while (bytes_written < msg.size()) {
ssize_t result = write(m_fifo_fd, msg_ptr + bytes_written, msg.size() - bytes_written);
if (result == -1) {
if (errno == EINTR) {
continue;
} else if (errno == EPIPE) {
break;
}
ers::warning(monitoring_log::fifo_issue(std::format("Error writing to FIFO. Code {}: {}", errno, strerror(errno))));
break;
}
bytes_written += result;
}
}
void FIFOWriter::validate_fifo(const std::string& fifoname) {
if (fifoname.empty()) {
m_fifo_fd = -1;
throw monitoring_log::fifo_issue("FIFO path is empty");
}
// Check if file exists and is a FIFO
struct stat file_stat;
if (stat(fifoname.c_str(), &file_stat) == -1) {
m_fifo_fd = -1;
throw monitoring_log::fifo_issue(std::format("Cannot access FIFO %s, error %d: %s",
fifoname, errno, strerror(errno)));
}
if (not S_ISFIFO(file_stat.st_mode)) {
m_fifo_fd = -1;
throw monitoring_log::fifo_issue(std::format("%s exists but is not a UNIX FIFO", fifoname));
}
}