Program Listing for File disk_io.cpp
↰ Return to documentation for file (disk_io.cpp
)
#include <array>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include "disk_io.hpp"
#include "log.hpp"
std::string errno_msg(int errn)
{
constexpr static auto SIZE = std::size_t{256};
std::array<char, SIZE> 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<bool>(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);
}
}