Program Listing for File monitor.cpp
↰ Return to documentation for file (monitor.cpp
)
#include <fcntl.h>
#include <signal.h>
#include <errno.h>
#include "monitor.hpp"
#include "util.hpp"
#include "log.hpp"
Monitor::Monitor(std::string& fifoname)
{
if (fifoname == ""){
m_fifo_fd = -1;
return;
}
else if (!is_fifo(fifoname.c_str()))
{
LOG_ERR("%s does not exist or is not a FIFO. Monitor disabled.", fifoname.c_str());
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)
{
LOG_ERR("Cannot open monitoring FIFO %s, error %d: %s", fifoname.c_str(), errno, strerror(errno));
}
LOG_INFO("Monitoring FIFO %s opened, fd=%d", fifoname.c_str(), m_fifo_fd);
fcntl(m_fifo_fd, F_SETPIPE_SZ, 1048576);
close(tmpfd);
}
Monitor::~Monitor()
{
close(m_fifo_fd);
}
bool Monitor::is_fifo(const char *filename)
{
struct stat stat_p;
if (0 != stat(filename, &stat_p))
{
// does not exist
return false;
}
if (!S_ISFIFO(stat_p.st_mode))
{
// not a fifo
return false;
}
return true;
}
std::string Monitor::get_serialized_message()
{
return m_message.dump();
}
void Monitor::write_message()
{
if(m_fifo_fd == -1){
return;
}
std::string msg = get_serialized_message()+"\n";
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;
}
LOG_WARN("Error writing to FIFO. Code %d: %s ", errno, strerror(errno));
break;
}
bytes_written += result;
}
}