Line data Source code
1 : #include <array>
2 : #include <cstdio>
3 : #include <cstring>
4 : #include <cstdlib>
5 : #include <unistd.h>
6 : #include <sys/types.h>
7 : #include <sys/stat.h>
8 : #include <fcntl.h>
9 : #include <errno.h>
10 :
11 : #include "disk_io.hpp"
12 : #include "log.hpp"
13 :
14 :
15 0 : std::string errno_msg(int errn)
16 : {
17 0 : constexpr static auto SIZE = std::size_t{256};
18 0 : std::array<char, SIZE> buffer{};
19 0 : if (strerror_r(errn, buffer.data(), sizeof(buffer)) != nullptr) {
20 0 : return "Unknown error";
21 : }
22 0 : return {buffer.data()};
23 : }
24 :
25 :
26 5 : DiskIO::DiskIO(const std::string& filename, size_t block_size, std::string_view op, bool is_fifo)
27 5 : : m_filename(filename), m_block_size(block_size), m_fd(-1), m_fstream(nullptr)
28 : {
29 5 : if (m_filename.empty()){
30 0 : LOG_WARN("Filename is empty. File/Fifo not opened.");
31 : return;
32 : }
33 :
34 5 : if (is_fifo){
35 0 : LOG_INFO("Opening fifo %s", m_filename.c_str());
36 0 : open_fifo(op);
37 : } else {
38 5 : LOG_INFO("Opening file %s", m_filename.c_str());
39 5 : open_file(op);
40 : }
41 0 : }
42 :
43 :
44 5 : DiskIO::~DiskIO()
45 : {
46 5 : if (m_fstream){
47 5 : fclose(m_fstream);
48 : }
49 5 : }
50 :
51 :
52 5 : void DiskIO::open_file(std::string_view op)
53 : {
54 5 : m_fstream = fopen(m_filename.c_str(), op.data());
55 5 : if (!m_fstream){
56 0 : LOG_ERR("cannot open file %s. %s", m_filename.c_str(), errno_msg(errno).c_str());
57 : }
58 5 : m_fd = fileno(m_fstream);
59 5 : if (m_fd == -1){
60 0 : LOG_ERR("cannot get file descriptor for %s. %s", m_filename.c_str(), errno_msg(errno).c_str());
61 : }
62 5 : }
63 :
64 :
65 0 : void DiskIO::open_fifo(std::string_view op)
66 : {
67 0 : int ret = mkfifo(m_filename.c_str(), 0666);
68 0 : if (ret != 0 and errno != EEXIST){
69 0 : LOG_ERR("cannot create fifo %s. %s", m_filename.c_str(), errno_msg(errno).c_str());
70 : }
71 0 : int trick_fd = open(m_filename.c_str(), O_RDONLY | O_NONBLOCK);
72 0 : m_fd = open(m_filename.c_str(), O_RDWR | O_NONBLOCK);
73 0 : if (m_fd == -1){
74 0 : LOG_ERR("cannot open file %s. %s", m_filename.c_str(), errno_msg(errno).c_str());
75 : }
76 0 : m_fstream = fdopen(m_fd, op.data());
77 0 : if (!m_fstream){
78 0 : LOG_ERR("cannot get stream from open fifo %s. %s", m_filename.c_str(), errno_msg(errno).c_str());
79 : }
80 0 : close(trick_fd);
81 0 : }
82 :
83 :
84 0 : bool DiskIO::is_eof()
85 : {
86 0 : return static_cast<bool>(feof(m_fstream));
87 : }
88 :
89 :
90 0 : int DiskIO::reset_position()
91 : {
92 0 : return fseek(m_fstream, 0, SEEK_SET);
93 : }
94 :
95 :
96 0 : size_t DiskIO::block_read(void *to_read, size_t max_blocks)
97 : {
98 0 : size_t read = 0;
99 0 : if ( m_fstream ){
100 0 : read = fread(to_read, m_block_size, max_blocks, m_fstream);
101 : }
102 0 : return read;
103 : }
104 :
105 :
106 6933 : size_t DiskIO::block_write(const void *to_write, size_t max_blocks)
107 : {
108 6933 : size_t written = 0;
109 6933 : if ( m_fstream ){
110 6933 : written = fwrite(to_write, m_block_size, max_blocks, m_fstream);
111 6933 : fflush(m_fstream);
112 : } else {
113 : written = max_blocks;
114 : }
115 6933 : return written;
116 : }
117 :
118 :
119 0 : size_t DiskIO::byte_read(void* to_read, size_t bytes)
120 : {
121 0 : if ( m_fd == -1 ){
122 : return 0;
123 : } else {
124 0 : return read(m_fd, to_read, bytes);
125 : }
126 : }
127 :
128 :
129 0 : size_t DiskIO::byte_write(void* to_write, size_t bytes)
130 : {
131 0 : if ( m_fd == -1 ){
132 : return bytes;
133 : } else {
134 0 : return write(m_fd, to_write, bytes);
135 : }
136 : }
137 :
138 :
|