48 #if defined HAVE_PREAD && defined PREAD_PROTOTYPE
51 #if defined HAVE_PWRITE && defined PWRITE_PROTOTYPE
61 if (errno != ENOENT) {
78 #ifdef F_DUPFD_CLOEXEC
82 if (fd < 0 && errno == EINVAL)
89 (void)fcntl(fd, F_SETFD, FD_CLOEXEC);
92 int save_errno = errno;
98 memset(toclose, 0,
sizeof(toclose));
104 int save_errno = errno;
112 (void)fcntl(fd, F_SETFD, FD_CLOEXEC);
137 #if !defined HAVE_PREAD || !defined HAVE_PWRITE
141 #elif defined __linux__
143 if (lseek(fd, std::numeric_limits<off_t>::max(), SEEK_SET) < 0) {
144 if constexpr (
sizeof(off_t) > 4) {
147 (void)lseek(fd, off_t(0xffffffff000), SEEK_SET);
152 if (lseek(fd, std::numeric_limits<off_t>::max(), SEEK_SET) < 0) {
153 if constexpr (
sizeof(off_t) > 4) {
155 (void)lseek(fd, off_t(0xffffffff000), SEEK_SET);
158 #elif defined __CYGWIN__ || \
159 defined __DragonFly__ || \
160 defined __FreeBSD__ || \
161 defined __APPLE__ || \
162 defined __NetBSD__ || \
163 defined __OpenBSD__ || \
173 (void)lseek(fd, std::numeric_limits<off_t>::max(), SEEK_SET);
174 #elif defined __EMSCRIPTEN__
175 if constexpr (
sizeof(off_t) > 4) {
178 (void)lseek(fd, off_t(0x20000000000000), SEEK_SET);
180 #elif defined __WIN32__
197 if (anew) flags |= O_CREAT | O_TRUNC;
198 int fd =
::open(filename, flags, 0666);
208 GENERIC_READ | GENERIC_WRITE,
211 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
213 anew ? CREATE_ALWAYS : OPEN_EXISTING,
214 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
216 if (handleWin == INVALID_HANDLE_VALUE) {
217 return posixy_set_errno_from_getlasterror();
221 int fd = _open_osfhandle((intptr_t)(handleWin), O_RDWR|
O_BINARY);
235 if (anew) flags |= O_CREAT | O_TRUNC;
236 int fd =
::open(filename, flags, 0666);
245 ssize_t c = read(fd,
p, n);
248 if (total >= min)
break;
251 if (errno == EINTR)
continue;
266 ssize_t c = write(fd,
p, n);
268 if (errno == EINTR)
continue;
277 io_pread(
int fd,
char *
p,
size_t n, off_t o,
size_t min)
282 ssize_t c = pread(fd,
p, n, o);
284 if (
usual(c == ssize_t(n)))
295 if (errno == EINTR)
continue;
305 #elif defined __WIN32__
306 HANDLE h = (HANDLE)_get_osfhandle(fd);
307 if (h == INVALID_HANDLE_VALUE) {
312 OVERLAPPED overlapped;
313 memset(&overlapped, 0,
sizeof(overlapped));
314 overlapped.Offset = (DWORD)o;
315 if constexpr (
sizeof(off_t) > 4) {
316 overlapped.OffsetHigh = o >> 32;
319 if (!ReadFile(h,
p, n, &c, &overlapped)) {
320 if (GetLastError() != ERROR_IO_PENDING ||
321 !GetOverlappedResult(h,
335 if (
rare(lseek(fd, o, SEEK_SET) < 0))
338 ssize_t c = read(fd,
p, n);
340 if (
usual(c == ssize_t(n)))
350 if (errno == EINTR)
continue;
367 ssize_t c = pwrite(fd,
p, n, o);
370 if (
usual(c == ssize_t(n)))
373 if (errno == EINTR)
continue;
380 #elif defined __WIN32__
381 HANDLE h = (HANDLE)_get_osfhandle(fd);
382 if (h == INVALID_HANDLE_VALUE) {
387 OVERLAPPED overlapped;
388 memset(&overlapped, 0,
sizeof(overlapped));
389 overlapped.Offset = (DWORD)o;
390 if constexpr (
sizeof(off_t) > 4) {
391 overlapped.OffsetHigh = o >> 32;
394 if (!WriteFile(h,
p, n, &c, &overlapped)) {
395 if (GetLastError() != ERROR_IO_PENDING ||
396 !GetOverlappedResult(h,
405 if (
rare(lseek(fd, o, SEEK_SET) < 0))
420 #ifdef HAVE_POSIX_FADVISE
427 return posix_fadvise(fd, o, n, POSIX_FADV_WILLNEED) == 0;
440 ssize_t c = pread(fd,
p, n, o);
442 if (
usual(c == ssize_t(n)))
450 if (errno == EINTR)
continue;
457 #elif defined __WIN32__
459 HANDLE h = (HANDLE)_get_osfhandle(fd);
460 if (h == INVALID_HANDLE_VALUE) {
465 OVERLAPPED overlapped;
466 memset(&overlapped, 0,
sizeof(overlapped));
467 overlapped.Offset = (DWORD)o;
468 if constexpr (
sizeof(off_t) > 4) {
469 overlapped.OffsetHigh = o >> 32;
472 if (!ReadFile(h,
p, n, &c, &overlapped)) {
473 if (GetLastError() != ERROR_IO_PENDING ||
474 !GetOverlappedResult(h,
485 if (
rare(lseek(fd, o, SEEK_SET) < 0))
488 ssize_t c = read(fd,
p, n);
490 if (
usual(c == ssize_t(n)))
497 if (errno == EINTR)
continue;
515 ssize_t c = pwrite(fd,
p, n, o);
517 if (
usual(c == ssize_t(n)))
522 if (errno == EINTR)
continue;
529 #elif defined __WIN32__
530 HANDLE h = (HANDLE)_get_osfhandle(fd);
531 if (h == INVALID_HANDLE_VALUE) {
536 OVERLAPPED overlapped;
537 memset(&overlapped, 0,
sizeof(overlapped));
538 overlapped.Offset = (DWORD)o;
539 if constexpr (
sizeof(off_t) > 4) {
540 overlapped.OffsetHigh = o >> 32;
543 if (!WriteFile(h,
p, n, &c, &overlapped)) {
544 if (GetLastError() != ERROR_IO_PENDING ||
545 !GetOverlappedResult(h,
553 if (
rare(lseek(fd, o, SEEK_SET) < 0))
556 ssize_t c = write(fd,
p, n);
558 if (
usual(c == ssize_t(n)))
563 if (errno == EINTR)
continue;
588 if (
posixy_rename(tmp_file.c_str(), real_file.c_str()) < 0) {
590 if (errno == EXDEV && --retries > 0)
goto retry;
597 int saved_errno = errno;
598 if (unlink(tmp_file.c_str()) == 0 || errno != ENOENT) {
DatabaseCorruptError indicates database corruption was detected.
DatabaseError indicates some sort of database related error.
Hierarchy of classes which Xapian can throw as exceptions.
void io_read_block(int fd, char *p, size_t n, off_t b, off_t o)
Read block b size n bytes into buffer p from file descriptor fd, offset o.
int io_open_block_wr(const char *filename, bool anew)
Open a block-based file for writing.
bool io_unlink(const std::string &filename)
Delete a file.
void io_write(int fd, const char *p, size_t n)
Write n bytes from block pointed to by p to file descriptor fd.
void io_pwrite(int fd, const char *p, size_t n, off_t o)
Write n bytes from block pointed to by p to file descriptor fd starting at position o.
size_t io_read(int fd, char *p, size_t n, size_t min)
Read n bytes (or until EOF) into block pointed to by p from file descriptor fd.
static int move_to_higher_fd_(int fd)
static void protect_from_write(int fd)
Protect against stray writes to fds we use pwrite() on.
int io_open_stream_wr(const char *filename, bool anew)
Open a stream-based file for writing.
size_t io_pread(int fd, char *p, size_t n, off_t o, size_t min)
Read n bytes (or until EOF) into block pointed to by p from file descriptor fd starting at position o...
bool io_tmp_rename(const std::string &tmp_file, const std::string &real_file)
Rename a temporary file to its final position.
void io_write_block(int fd, const char *p, size_t n, off_t b, off_t o)
Write block b size n bytes from buffer p to file descriptor fd, offset o.
static void throw_block_error(const char *s, off_t b, int e=0)
static int move_to_higher_fd(int fd)
Wrappers for low-level POSIX I/O routines.
bool io_readahead_block(int, size_t, off_t, off_t=0)
Readahead block b size n bytes from file descriptor fd.
string str(int value)
Convert int to std::string.
Database open(std::string_view host, unsigned int port, unsigned timeout=10000, unsigned connect_timeout=10000)
Construct a Database object for read-only access to a remote database accessed via a TCP connection.
Various assertion macros.
Provides wrappers with POSIXy semantics.
#define posixy_rename(F, T)
<unistd.h>, but with compat.
include <windows.h> without all the bloat and damage.
Convert types to std::string.