11#ifdef JOEDB_HAS_BROKEN_POSIX_LOCKING
12#define JOEDB_SETLK F_SETLK
13#define JOEDB_SETLKW F_SETLKW
17#define JOEDB_SETLK F_OFD_SETLK
18#define JOEDB_SETLKW F_OFD_SETLKW
23#ifndef _FILE_OFFSET_BITS
26 sizeof(off_t) ==
sizeof(int64_t),
27 "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."
41 std::string(action) +
' ' + file_name +
": " + strerror(errno)
47 int Posix_FD::lock(
int command,
short type, int64_t start, int64_t size)
52 lock.l_whence = SEEK_SET;
53 lock.l_start = off_t(start);
54 lock.l_len = off_t(size);
57 return fcntl(fd, command, &lock);
64 return lock(
JOEDB_SETLK, F_WRLCK, start, size) == 0;
94 const ssize_t result = ::pread(fd, buffer, size, offset);
97 throw_last_error(
"reading",
"file");
99 return size_t(result);
108 while (written < size)
121 written += size_t(result);
130 if (fcntl(fd, F_FULLFSYNC) == -1)
139#if _POSIX_SYNCHRONIZED_IO > 0
144 if (fdatasync(fd) == -1)
157 fd = open(file_name, O_RDONLY);
159 fd = open(file_name, O_RDWR);
161 fd = open(file_name, O_RDWR | O_CREAT | O_EXCL, 00644);
169 fd = open(file_name, O_RDWR | O_CREAT | O_EXCL, 00644);
171 fd = open(file_name, O_RDWR);
174 fd = open(file_name, O_RDWR | O_CREAT | O_TRUNC, 00644);
200 if (fstat(fd, &s) < 0)
203 return int64_t(s.st_size);
static constexpr int64_t last_position
virtual void datasync()
Write data durably (no file-size change)
void exclusive_lock_tail()
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 durably (including file-size change)
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)
@ truncate
create new file, or truncate existing file, and locks the file
@ 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