Bug 1857193 - Make passing --port=0 select a free port, r=webdriver-reviewers,jdescottes
[gecko.git] / storage / ReadOnlyNoLockVFS.cpp
blob9a820085ede2914be1fe4f9009cf10850df306bf
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 /**
8 * This VFS is built on top of the (unix|win32)-none, but it additionally
9 * sets any opened file as immutable, that allows to also open in read-only
10 * mode databases using WAL, or other journals that need auxiliary files, when
11 * such files cannot be created.
12 * This is useful when trying to read from third-party databases, avoiding any
13 * risk of creating auxiliary files (e.g. journals).
14 * It can only be used on read-only connections, because being a no-lock VFS
15 * it would be trivial to corrupt the data.
18 #include "nsDebug.h"
19 #include "sqlite3.h"
21 #define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData))
23 #if defined(XP_WIN)
24 # define BASE_VFS "win32-none"
25 #else
26 # define BASE_VFS "unix-none"
27 #endif
29 #define VFS_NAME "readonly-immutable-nolock"
31 namespace {
33 static int vfsOpen(sqlite3_vfs* vfs, const char* zName, sqlite3_file* pFile,
34 int flags, int* pOutFlags) {
35 if ((flags & SQLITE_OPEN_READONLY) == 0) {
36 // This is not done to be used in readwrite connections.
37 return SQLITE_CANTOPEN;
40 sqlite3_vfs* pOrigVfs = ORIGVFS(vfs);
41 int rc = pOrigVfs->xOpen(pOrigVfs, zName, pFile, flags, pOutFlags);
42 if (rc != SQLITE_OK) {
43 return rc;
46 const sqlite3_io_methods* pOrigMethods = pFile->pMethods;
48 // If the IO version is higher than the last known one, you should update
49 // this IO adding appropriate methods for any methods added in the version
50 // change.
51 MOZ_ASSERT(pOrigMethods->iVersion <= 3);
53 static const sqlite3_io_methods vfs_io_methods = {
54 pOrigMethods->iVersion, /* iVersion */
55 pOrigMethods->xClose, /* xClose */
56 pOrigMethods->xRead, /* xRead */
57 pOrigMethods->xWrite, /* xWrite */
58 pOrigMethods->xTruncate, /* xTruncate */
59 pOrigMethods->xSync, /* xSync */
60 pOrigMethods->xFileSize, /* xFileSize */
61 pOrigMethods->xLock, /* xLock */
62 pOrigMethods->xUnlock, /* xUnlock */
63 pOrigMethods->xCheckReservedLock, /* xCheckReservedLock */
64 pOrigMethods->xFileControl, /* xFileControl */
65 pOrigMethods->xSectorSize, /* xSectorSize */
66 [](sqlite3_file*) {
67 return SQLITE_IOCAP_IMMUTABLE;
68 }, /* xDeviceCharacteristics */
69 pOrigMethods->xShmMap, /* xShmMap */
70 pOrigMethods->xShmLock, /* xShmLock */
71 pOrigMethods->xShmBarrier, /* xShmBarrier */
72 pOrigMethods->xShmUnmap, /* xShmUnmap */
73 pOrigMethods->xFetch, /* xFetch */
74 pOrigMethods->xUnfetch /* xUnfetch */
76 pFile->pMethods = &vfs_io_methods;
77 if (pOutFlags) {
78 *pOutFlags = flags;
81 return SQLITE_OK;
84 } // namespace
86 namespace mozilla::storage {
88 UniquePtr<sqlite3_vfs> ConstructReadOnlyNoLockVFS() {
89 if (sqlite3_vfs_find(VFS_NAME) != nullptr) {
90 return nullptr;
92 sqlite3_vfs* pOrigVfs = sqlite3_vfs_find(BASE_VFS);
93 if (!pOrigVfs) {
94 return nullptr;
97 // If the VFS version is higher than the last known one, you should update
98 // this VFS adding appropriate methods for any methods added in the version
99 // change.
100 MOZ_ASSERT(pOrigVfs->iVersion <= 3);
102 static const sqlite3_vfs vfs = {
103 pOrigVfs->iVersion, /* iVersion */
104 pOrigVfs->szOsFile, /* szOsFile */
105 pOrigVfs->mxPathname, /* mxPathname */
106 nullptr, /* pNext */
107 VFS_NAME, /* zName */
108 pOrigVfs, /* pAppData */
109 vfsOpen, /* xOpen */
110 pOrigVfs->xDelete, /* xDelete */
111 pOrigVfs->xAccess, /* xAccess */
112 pOrigVfs->xFullPathname, /* xFullPathname */
113 pOrigVfs->xDlOpen, /* xDlOpen */
114 pOrigVfs->xDlError, /* xDlError */
115 pOrigVfs->xDlSym, /* xDlSym */
116 pOrigVfs->xDlClose, /* xDlClose */
117 pOrigVfs->xRandomness, /* xRandomness */
118 pOrigVfs->xSleep, /* xSleep */
119 pOrigVfs->xCurrentTime, /* xCurrentTime */
120 pOrigVfs->xGetLastError, /* xGetLastError */
121 pOrigVfs->xCurrentTimeInt64, /* xCurrentTimeInt64 */
122 pOrigVfs->xSetSystemCall, /* xSetSystemCall */
123 pOrigVfs->xGetSystemCall, /* xGetSystemCall */
124 pOrigVfs->xNextSystemCall /* xNextSystemCall */
127 return MakeUnique<sqlite3_vfs>(vfs);
130 } // namespace mozilla::storage