.. _program_listing_file_disk_io.cpp: Program Listing for File disk_io.cpp ==================================== |exhale_lsh| :ref:`Return to documentation for file ` (``disk_io.cpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #include #include #include #include #include #include #include #include #include #include "disk_io.hpp" #include "log.hpp" std::string errno_msg(int errn) { constexpr static auto SIZE = std::size_t{256}; std::array buffer{}; if (strerror_r(errn, buffer.data(), sizeof(buffer)) != nullptr) { return "Unknown error"; } return {buffer.data()}; } DiskIO::DiskIO(const std::string& filename, size_t block_size, std::string_view op, bool is_fifo) : m_filename(filename), m_block_size(block_size), m_fd(-1), m_fstream(nullptr) { if (m_filename.empty()){ LOG_WARN("Filename is empty. File/Fifo not opened."); return; } if (is_fifo){ LOG_INFO("Opening fifo %s", m_filename.c_str()); open_fifo(op); } else { LOG_INFO("Opening file %s", m_filename.c_str()); open_file(op); } } DiskIO::~DiskIO() { if (m_fstream){ fclose(m_fstream); } } void DiskIO::open_file(std::string_view op) { m_fstream = fopen(m_filename.c_str(), op.data()); if (!m_fstream){ LOG_ERR("cannot open file %s. %s", m_filename.c_str(), errno_msg(errno).c_str()); } m_fd = fileno(m_fstream); if (m_fd == -1){ LOG_ERR("cannot get file descriptor for %s. %s", m_filename.c_str(), errno_msg(errno).c_str()); } } void DiskIO::open_fifo(std::string_view op) { int ret = mkfifo(m_filename.c_str(), 0666); if (ret != 0 and errno != EEXIST){ LOG_ERR("cannot create fifo %s. %s", m_filename.c_str(), errno_msg(errno).c_str()); } int trick_fd = open(m_filename.c_str(), O_RDONLY | O_NONBLOCK); m_fd = open(m_filename.c_str(), O_RDWR | O_NONBLOCK); if (m_fd == -1){ LOG_ERR("cannot open file %s. %s", m_filename.c_str(), errno_msg(errno).c_str()); } m_fstream = fdopen(m_fd, op.data()); if (!m_fstream){ LOG_ERR("cannot get stream from open fifo %s. %s", m_filename.c_str(), errno_msg(errno).c_str()); } close(trick_fd); } bool DiskIO::is_eof() { return static_cast(feof(m_fstream)); } int DiskIO::reset_position() { return fseek(m_fstream, 0, SEEK_SET); } size_t DiskIO::block_read(void *to_read, size_t max_blocks) { size_t read = 0; if ( m_fstream ){ read = fread(to_read, m_block_size, max_blocks, m_fstream); } return read; } size_t DiskIO::block_write(const void *to_write, size_t max_blocks) { size_t written = 0; if ( m_fstream ){ written = fwrite(to_write, m_block_size, max_blocks, m_fstream); fflush(m_fstream); } else { written = max_blocks; } return written; } size_t DiskIO::byte_read(void* to_read, size_t bytes) { if ( m_fd == -1 ){ return 0; } else { return read(m_fd, to_read, bytes); } } size_t DiskIO::byte_write(void* to_write, size_t bytes) { if ( m_fd == -1 ){ return bytes; } else { return write(m_fd, to_write, bytes); } }