10#ifdef JOEDB_HAS_BROKEN_POSIX_LOCKING
11#define JOEDB_SETLK F_SETLK
12#define JOEDB_SETLKW F_SETLKW
16#define JOEDB_SETLK F_OFD_SETLK
17#define JOEDB_SETLKW F_OFD_SETLKW
22#ifndef _FILE_OFFSET_BITS
25 sizeof(off_t) ==
sizeof(int64_t),
26 "Define the _FILE_OFFSET_BITS macro to 32 or 64 to silence this error. 64 is recommended if possible. Joedb does not check for file-size overflow."
40 std::string(action) +
' ' + file_name +
": " + strerror(errno)
46 int Posix_FD::lock(
int command,
short type, int64_t start, int64_t size)
51 lock.l_whence = SEEK_SET;
52 lock.l_start = off_t(start);
53 lock.l_len = off_t(size);
56 return fcntl(fd, command, &lock);
63 return lock(
JOEDB_SETLK, F_WRLCK, start, size) == 0;
93 const ssize_t result = ::pread(fd, buffer, size, offset);
96 throw_last_error(
"Reading",
"file");
98 return size_t(result);
107 while (written < size)
120 written += size_t(result);
129 if (fcntl(fd, F_FULLFSYNC) == -1)
138#if _POSIX_SYNCHRONIZED_IO > 0
143 if (fdatasync(fd) == -1)
156 fd = open(file_name, O_RDONLY);
158 fd = open(file_name, O_RDWR);
160 fd = open(file_name, O_RDWR | O_CREAT | O_EXCL, 00644);
168 fd = open(file_name, O_RDWR | O_CREAT | O_EXCL, 00644);
170 fd = open(file_name, O_RDWR);
197 if (fstat(fd, &s) < 0)
200 return int64_t(s.st_size);
virtual void datasync()
Write data durably to permanent storage.
void exclusive_lock_tail()
static constexpr int64_t last_position
void destructor_flush() noexcept
size_t pread(char *buffer, size_t size, int64_t offset) const override
Read a range of bytes.
static void throw_last_error(const char *action, const char *file_name)
void pwrite(const char *buffer, size_t size, int64_t offset) override
Write a range of bytes. Extend file size if necessary.
bool try_exclusive_lock(int64_t start, int64_t size)
int64_t get_size() const override
Get the size of the file, or -1 if it is unknown.
void sync() override
Write data and meta-data (such as file size) durably to permanent storage.
void unlock(int64_t start, int64_t size) noexcept override
Remove a lock. The range should match the range of a corresponding lock.
void shared_lock(int64_t start, int64_t size) override
Lock a range of bytes for reading (prevents writes, not reads)
void exclusive_lock(int64_t start, int64_t size) override
Lock a range of bytes for writing (prevents both writes and reads)
Posix_FD(int fd, Open_Mode mode)
Posix_File(int fd, Open_Mode mode)
@ create_new
fails if already exists, locks the file for writing
@ write_existing
fails if does not exist or locked, locks the file for writing
@ shared_write
like write_existing_or_create_new, but does not lock the file, and does not fail if locked
@ write_existing_or_create_new
either write_existing or create_new depending on whether the file exists. Racy in Posix,...
@ write_lock
like write_existing_or_create_new, but waits instead of failing if already locked
@ read_existing
fails if does not exist