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;
    }
}