1 /* Copyright (C) 2019 MariaDB Corporation
2
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public License
5 as published by the Free Software Foundation; version 2 of
6 the License.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
16 MA 02110-1301, USA. */
17
18 #include <fcntl.h>
19
20 #include "SMDataFile.h"
21
22 using namespace std;
23
24 namespace idbdatafile
25 {
26
~SMDataFile()27 SMDataFile::~SMDataFile()
28 {
29 }
30
SMDataFile(const char * name,int _openmode,const struct stat & _stat)31 SMDataFile::SMDataFile(const char *name, int _openmode, const struct stat &_stat) :
32 IDBDataFile(name)
33 {
34 openmode = _openmode;
35 // the 'a' file open mode is the only one that starts at EOF
36 if ((openmode & O_APPEND) && !(openmode & O_RDWR))
37 position = _stat.st_size;
38 else
39 position = 0;
40 comm = SMComm::get();
41 }
42
pread(void * buf,off64_t offset,size_t count)43 ssize_t SMDataFile::pread(void *buf, off64_t offset, size_t count)
44 {
45 return comm->pread(name(), buf, count, offset);
46 }
47
read(void * buf,size_t count)48 ssize_t SMDataFile::read(void *buf, size_t count)
49 {
50 ssize_t ret = comm->pread(name(), buf, count, position);
51 if (ret < 0)
52 return ret;
53 position += ret;
54 return ret;
55 }
56
write(const void * buf,size_t count)57 ssize_t SMDataFile::write(const void *buf, size_t count)
58 {
59 if (openmode & O_APPEND)
60 return comm->append(name(), buf, count);
61 ssize_t ret = comm->pwrite(name(), buf, count, position);
62 if (ret < 0)
63 return ret;
64 position += ret;
65 return ret;
66 }
67
seek(off64_t offset,int whence)68 int SMDataFile::seek(off64_t offset, int whence)
69 {
70 switch (whence) {
71 case SEEK_SET:
72 position = offset;
73 break;
74 case SEEK_CUR:
75 position += offset;
76 break;
77 case SEEK_END:
78 {
79 struct stat _stat;
80 int err = comm->stat(name(), &_stat);
81 if (err)
82 return err;
83 position = _stat.st_size + offset;
84 break;
85 }
86 default:
87 errno = EINVAL;
88 return -1;
89 }
90 return 0;
91 }
92
truncate(off64_t length)93 int SMDataFile::truncate(off64_t length)
94 {
95 return comm->truncate(name(), length);
96 }
97
fallocate(int mode,off64_t offset,off64_t length)98 int SMDataFile::fallocate(int mode, off64_t offset, off64_t length)
99 {
100 idbassert_s(mode == 0, "SMDataFile::fallocate() does not support mode != 0 right now.");
101 return comm->truncate(name(), offset + length);
102 }
103
size()104 off64_t SMDataFile::size()
105 {
106 struct stat _stat;
107 int err = comm->stat(name(), &_stat);
108
109 if (err)
110 return err;
111 return _stat.st_size;
112 }
113
tell()114 off64_t SMDataFile::tell()
115 {
116 return position;
117 }
118
flush()119 int SMDataFile::flush()
120 {
121 return 0; // writes are synchronous b/c of replication. If we allow asynchronous replication,
122 // then we need to implement a flush() cmd in SMComm.
123 }
124
mtime()125 time_t SMDataFile::mtime()
126 {
127 struct stat _stat;
128 int err = comm->stat(name(), &_stat);
129
130 if (err)
131 return (time_t) err;
132 return _stat.st_mtime;
133 }
134
close()135 int SMDataFile::close()
136 {
137 return 0;
138 }
139
140 // constructor used for testing
SMDataFile(const char * fname,int _openmode,size_t fake_size)141 SMDataFile::SMDataFile(const char *fname, int _openmode, size_t fake_size)
142 : IDBDataFile(fname)
143 {
144 openmode = _openmode;
145 // the 'a' file open mode is the only one that starts at EOF
146 if ((openmode & O_APPEND) && !(openmode & O_RDWR))
147 position = fake_size;
148 else
149 position = 0;
150 comm = SMComm::get();
151 }
152
153 }
154