- Replay recovers every complete record before a torn final record (the normal result of a crash mid-append) and reports it through err, instead of rejecting the whole journal. SwapReplay_TruncatedLog is updated to the new behaviour. - A record that cannot be written (open/write failure, breaker open) marks the journal as having a gap. Later position-based records are dropped until a checkpoint re-establishes the content; recorders request one on the next edit (at most once per second). - A failed append is truncated back off the file, and a failed header write closes the file so the next attempt starts fresh. - Inserts over the 24-bit record limit are split into consecutive records; buffers too large to checkpoint are no longer snapshotted and rejected on every checkpoint. - Declining to delete an unreadable swap moves it to .corrupt so new edits are not appended behind the bad data. - NotifyFilenameChanged no longer writes a full checkpoint into the journal it is about to delete. Audit findings D7, P5. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015rcVQiiWyTzoNrsvLSaAfB
87 lines
1.1 KiB
C++
87 lines
1.1 KiB
C++
#include "SyscallWrappers.h"
|
|
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
#include <sys/stat.h>
|
|
#include <cerrno>
|
|
#include <cstdlib>
|
|
|
|
namespace kte {
|
|
namespace syscall {
|
|
int
|
|
Open(const char *path, int flags, mode_t mode)
|
|
{
|
|
int fd;
|
|
do {
|
|
fd = ::open(path, flags, mode);
|
|
} while (fd == -1 && errno == EINTR);
|
|
return fd;
|
|
}
|
|
|
|
|
|
int
|
|
Close(int fd)
|
|
{
|
|
int ret;
|
|
do {
|
|
ret = ::close(fd);
|
|
} while (ret == -1 && errno == EINTR);
|
|
return ret;
|
|
}
|
|
|
|
|
|
int
|
|
Fsync(int fd)
|
|
{
|
|
int ret;
|
|
do {
|
|
ret = ::fsync(fd);
|
|
} while (ret == -1 && errno == EINTR);
|
|
return ret;
|
|
}
|
|
|
|
|
|
int
|
|
Fstat(int fd, struct stat *buf)
|
|
{
|
|
int ret;
|
|
do {
|
|
ret = ::fstat(fd, buf);
|
|
} while (ret == -1 && errno == EINTR);
|
|
return ret;
|
|
}
|
|
|
|
|
|
int
|
|
Ftruncate(int fd, off_t length)
|
|
{
|
|
int ret;
|
|
do {
|
|
ret = ::ftruncate(fd, length);
|
|
} while (ret == -1 && errno == EINTR);
|
|
return ret;
|
|
}
|
|
|
|
|
|
int
|
|
Fchmod(int fd, mode_t mode)
|
|
{
|
|
int ret;
|
|
do {
|
|
ret = ::fchmod(fd, mode);
|
|
} while (ret == -1 && errno == EINTR);
|
|
return ret;
|
|
}
|
|
|
|
|
|
int
|
|
Mkstemp(char *template_str)
|
|
{
|
|
int fd;
|
|
do {
|
|
fd = ::mkstemp(template_str);
|
|
} while (fd == -1 && errno == EINTR);
|
|
return fd;
|
|
}
|
|
} // namespace syscall
|
|
} // namespace kte
|