diff --git a/CMakeLists.txt b/CMakeLists.txt index a7272ee7..37255ce9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -721,6 +721,7 @@ if(CORTEXT_EMBED_OBJSTORE) if(WIN32) list(APPEND CORTEXT_OBJSTORE_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/third_party/sqlite-objstore/src/win_dirent.c + ${CMAKE_CURRENT_SOURCE_DIR}/third_party/sqlite-objstore/src/win_posix.c ) endif() if(CORTEXT_TARGET_AARCH64) diff --git a/third_party/sqlite-objstore/src/CMakeLists.txt b/third_party/sqlite-objstore/src/CMakeLists.txt index fb72fb55..40dec625 100644 --- a/third_party/sqlite-objstore/src/CMakeLists.txt +++ b/third_party/sqlite-objstore/src/CMakeLists.txt @@ -80,7 +80,7 @@ if(OBJSTORE_BACKEND_VFS) endif() if(WIN32) - list(APPEND OBJSTORE_SOURCES win_dirent.c) + list(APPEND OBJSTORE_SOURCES win_dirent.c win_posix.c) endif() function(_objstore_configure_library target) diff --git a/third_party/sqlite-objstore/src/backend_file.c b/third_party/sqlite-objstore/src/backend_file.c index f1fefd05..09f269e8 100644 --- a/third_party/sqlite-objstore/src/backend_file.c +++ b/third_party/sqlite-objstore/src/backend_file.c @@ -28,8 +28,10 @@ #include #include #include +#if defined(_WIN32) +#include "win_posix.h" +#else #include -#if !defined(_WIN32) #include #endif #if defined(__linux__) diff --git a/third_party/sqlite-objstore/src/backend_portable.c b/third_party/sqlite-objstore/src/backend_portable.c index 754bb13f..8f3ccfc2 100644 --- a/third_party/sqlite-objstore/src/backend_portable.c +++ b/third_party/sqlite-objstore/src/backend_portable.c @@ -14,7 +14,11 @@ #include #include #include +#if defined(_WIN32) +#include "win_posix.h" +#else #include +#endif #if defined(__EMSCRIPTEN__) #include diff --git a/third_party/sqlite-objstore/src/win_posix.c b/third_party/sqlite-objstore/src/win_posix.c new file mode 100644 index 00000000..81eeb271 --- /dev/null +++ b/third_party/sqlite-objstore/src/win_posix.c @@ -0,0 +1,63 @@ +#include "win_posix.h" + +#define WIN32_LEAN_AND_MEAN 1 +#include + +int +flock (int fd, int how) +{ + HANDLE handle; + BOOL exclusive = (how & LOCK_EX) != 0; + + handle = (HANDLE) _get_osfhandle (fd); + if (handle == INVALID_HANDLE_VALUE) + { + errno = EBADF; + return -1; + } + + if (how & LOCK_UN) + { + if (UnlockFileEx (handle, 0, 1, 0, (LPOVERLAPPED) 0) != 0) + { + return 0; + } + errno = (GetLastError () == ERROR_NOT_LOCKED) ? EINVAL : EIO; + return -1; + } + + /* + * LockFileEx is always non-blocking; the POSIX callers of this shim use + * both modes (LOCK_NB for the primary probe, blocking waits while the + * primary finishes), so emulate the blocking form with a short retry + * loop on the dedicated lock file. + */ + for (;;) + { + if (LockFileEx (handle, exclusive ? LOCKFILE_EXCLUSIVE_LOCK : 0, + 0, 1, 0, (LPOVERLAPPED) 0) != 0) + { + return 0; + } + if (how & LOCK_NB) + { + errno = (GetLastError () == ERROR_LOCK_VIOLATION) ? EACCES : EIO; + return -1; + } + Sleep (10); + } +} + +int +ftruncate (int fd, off_t length) +{ + errno_t err; + + err = _chsize_s (fd, length); + if (err != 0) + { + errno = (int) err; + return -1; + } + return 0; +} diff --git a/third_party/sqlite-objstore/src/win_posix.h b/third_party/sqlite-objstore/src/win_posix.h new file mode 100644 index 00000000..85c0e89d --- /dev/null +++ b/third_party/sqlite-objstore/src/win_posix.h @@ -0,0 +1,66 @@ +#ifndef OBJSTORE_WIN_POSIX_H +#define OBJSTORE_WIN_POSIX_H + +/* + * Minimal POSIX unistd/fcntl/sys-file subset for Windows (MSVC and clang-cl). + * + * The objstore file backends use open/read/write/close, fsync, ftruncate, + * flock, the O_* open flags, and a few unistd functions. UCRT provides the + * underscore-prefixed primitives (_open, _read, _write, _close, _commit, + * _chsize_s, _get_osfhandle) and the prefixed _O_* flags, but not the bare + * POSIX names or the un-prefixed O_* aliases in plain C mode. On other + * platforms the real and are used instead. + * + * Every definition is guarded so this header also compiles under MinGW, + * where the bare names already exist. + */ + +#define WIN32_LEAN_AND_MEAN 1 +#include +#include +#include +#include +#include +#include +#include + +#ifndef O_RDONLY +#define O_RDONLY _O_RDONLY +#define O_WRONLY _O_WRONLY +#define O_RDWR _O_RDWR +#define O_CREAT _O_CREAT +#define O_TRUNC _O_TRUNC +#define O_EXCL _O_EXCL +#define O_APPEND _O_APPEND +#endif +#ifndef O_CLOEXEC +#define O_CLOEXEC _O_NOINHERIT +#endif +#ifndef open +#define open _open +#define read _read +#define write _write +#define close _close +#endif +#ifndef fsync +#define fsync(fd) _commit(fd) +#endif +#ifndef LOCK_SH +#define LOCK_SH 1 +#define LOCK_EX 2 +#define LOCK_NB 4 +#define LOCK_UN 8 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +int flock (int fd, int how); +int ftruncate (int fd, off_t length); + +#ifdef __cplusplus +} +#endif + +#endif /* OBJSTORE_WIN_POSIX_H */