Files
kte/SyscallWrappers.cc
T
Claude aa53d75f96 Swap: keep the journal replayable across failures and crashes
- 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
2026-09-24 09:16:04 -07:00

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