Bug 1845715 - Check for failure when getting RegExp match result template r=iain
[gecko.git] / storage / BaseVFS.cpp
blob2bf435f3d6e0b878021e594f13581050199c8304
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 #include <string.h>
8 #include "sqlite3.h"
9 #include "mozilla/net/IOActivityMonitor.h"
11 namespace {
13 // The last VFS version for which this file has been updated.
14 constexpr int kLastKnowVfsVersion = 3;
16 // The last io_methods version for which this file has been updated.
17 constexpr int kLastKnownIOMethodsVersion = 3;
19 using namespace mozilla;
20 using namespace mozilla::net;
22 struct BaseFile {
23 // Base class. Must be first
24 sqlite3_file base;
25 // The filename
26 char* location;
27 // This points to the underlying sqlite3_file
28 sqlite3_file pReal[1];
31 int BaseClose(sqlite3_file* pFile) {
32 BaseFile* p = (BaseFile*)pFile;
33 delete[] p->location;
34 return p->pReal->pMethods->xClose(p->pReal);
37 int BaseRead(sqlite3_file* pFile, void* zBuf, int iAmt, sqlite_int64 iOfst) {
38 BaseFile* p = (BaseFile*)pFile;
39 int rc = p->pReal->pMethods->xRead(p->pReal, zBuf, iAmt, iOfst);
40 if (rc == SQLITE_OK && IOActivityMonitor::IsActive()) {
41 IOActivityMonitor::Read(nsDependentCString(p->location), iAmt);
43 return rc;
46 int BaseWrite(sqlite3_file* pFile, const void* zBuf, int iAmt,
47 sqlite_int64 iOfst) {
48 BaseFile* p = (BaseFile*)pFile;
49 int rc = p->pReal->pMethods->xWrite(p->pReal, zBuf, iAmt, iOfst);
50 if (rc == SQLITE_OK && IOActivityMonitor::IsActive()) {
51 IOActivityMonitor::Write(nsDependentCString(p->location), iAmt);
53 return rc;
56 int BaseTruncate(sqlite3_file* pFile, sqlite_int64 size) {
57 BaseFile* p = (BaseFile*)pFile;
58 return p->pReal->pMethods->xTruncate(p->pReal, size);
61 int BaseSync(sqlite3_file* pFile, int flags) {
62 BaseFile* p = (BaseFile*)pFile;
63 return p->pReal->pMethods->xSync(p->pReal, flags);
66 int BaseFileSize(sqlite3_file* pFile, sqlite_int64* pSize) {
67 BaseFile* p = (BaseFile*)pFile;
68 return p->pReal->pMethods->xFileSize(p->pReal, pSize);
71 int BaseLock(sqlite3_file* pFile, int eLock) {
72 BaseFile* p = (BaseFile*)pFile;
73 return p->pReal->pMethods->xLock(p->pReal, eLock);
76 int BaseUnlock(sqlite3_file* pFile, int eLock) {
77 BaseFile* p = (BaseFile*)pFile;
78 return p->pReal->pMethods->xUnlock(p->pReal, eLock);
81 int BaseCheckReservedLock(sqlite3_file* pFile, int* pResOut) {
82 BaseFile* p = (BaseFile*)pFile;
83 return p->pReal->pMethods->xCheckReservedLock(p->pReal, pResOut);
86 int BaseFileControl(sqlite3_file* pFile, int op, void* pArg) {
87 #if defined(MOZ_SQLITE_PERSIST_AUXILIARY_FILES)
88 // Persist auxiliary files (-shm and -wal) on disk, because creating and
89 // deleting them may be expensive on slow storage.
90 // Only do this when there is a journal size limit, so the journal is
91 // truncated instead of deleted on shutdown, that feels safer if the user
92 // moves a database file around without its auxiliary files.
93 MOZ_ASSERT(
94 ::sqlite3_compileoption_used("DEFAULT_JOURNAL_SIZE_LIMIT"),
95 "A journal size limit ensures the journal is truncated on shutdown");
96 if (op == SQLITE_FCNTL_PERSIST_WAL) {
97 *static_cast<int*>(pArg) = 1;
98 return SQLITE_OK;
100 #endif
101 BaseFile* p = (BaseFile*)pFile;
102 return p->pReal->pMethods->xFileControl(p->pReal, op, pArg);
105 int BaseSectorSize(sqlite3_file* pFile) {
106 BaseFile* p = (BaseFile*)pFile;
107 return p->pReal->pMethods->xSectorSize(p->pReal);
110 int BaseDeviceCharacteristics(sqlite3_file* pFile) {
111 BaseFile* p = (BaseFile*)pFile;
112 return p->pReal->pMethods->xDeviceCharacteristics(p->pReal);
115 int BaseShmMap(sqlite3_file* pFile, int iPg, int pgsz, int bExtend,
116 void volatile** pp) {
117 BaseFile* p = (BaseFile*)pFile;
118 return p->pReal->pMethods->xShmMap(p->pReal, iPg, pgsz, bExtend, pp);
121 int BaseShmLock(sqlite3_file* pFile, int offset, int n, int flags) {
122 BaseFile* p = (BaseFile*)pFile;
123 return p->pReal->pMethods->xShmLock(p->pReal, offset, n, flags);
126 void BaseShmBarrier(sqlite3_file* pFile) {
127 BaseFile* p = (BaseFile*)pFile;
128 return p->pReal->pMethods->xShmBarrier(p->pReal);
131 int BaseShmUnmap(sqlite3_file* pFile, int deleteFlag) {
132 BaseFile* p = (BaseFile*)pFile;
133 return p->pReal->pMethods->xShmUnmap(p->pReal, deleteFlag);
136 int BaseFetch(sqlite3_file* pFile, sqlite3_int64 iOfst, int iAmt, void** pp) {
137 BaseFile* p = (BaseFile*)pFile;
138 return p->pReal->pMethods->xFetch(p->pReal, iOfst, iAmt, pp);
141 int BaseUnfetch(sqlite3_file* pFile, sqlite3_int64 iOfst, void* pPage) {
142 BaseFile* p = (BaseFile*)pFile;
143 return p->pReal->pMethods->xUnfetch(p->pReal, iOfst, pPage);
146 int BaseOpen(sqlite3_vfs* vfs, const char* zName, sqlite3_file* pFile,
147 int flags, int* pOutFlags) {
148 BaseFile* p = (BaseFile*)pFile;
149 if (zName) {
150 p->location = new char[7 + strlen(zName) + 1];
151 strcpy(p->location, "file://");
152 strcpy(p->location + 7, zName);
153 } else {
154 p->location = new char[8];
155 strcpy(p->location, "file://");
158 sqlite3_vfs* origVfs = (sqlite3_vfs*)(vfs->pAppData);
159 int rc = origVfs->xOpen(origVfs, zName, p->pReal, flags, pOutFlags);
160 if (rc) {
161 return rc;
163 if (p->pReal->pMethods) {
164 // If the io_methods version is higher than the last known one, you should
165 // update this VFS adding appropriate IO methods for any methods added in
166 // the version change.
167 MOZ_ASSERT(p->pReal->pMethods->iVersion == kLastKnownIOMethodsVersion);
168 static const sqlite3_io_methods IOmethods = {
169 kLastKnownIOMethodsVersion, /* iVersion */
170 BaseClose, /* xClose */
171 BaseRead, /* xRead */
172 BaseWrite, /* xWrite */
173 BaseTruncate, /* xTruncate */
174 BaseSync, /* xSync */
175 BaseFileSize, /* xFileSize */
176 BaseLock, /* xLock */
177 BaseUnlock, /* xUnlock */
178 BaseCheckReservedLock, /* xCheckReservedLock */
179 BaseFileControl, /* xFileControl */
180 BaseSectorSize, /* xSectorSize */
181 BaseDeviceCharacteristics, /* xDeviceCharacteristics */
182 BaseShmMap, /* xShmMap */
183 BaseShmLock, /* xShmLock */
184 BaseShmBarrier, /* xShmBarrier */
185 BaseShmUnmap, /* xShmUnmap */
186 BaseFetch, /* xFetch */
187 BaseUnfetch /* xUnfetch */
189 pFile->pMethods = &IOmethods;
192 return SQLITE_OK;
195 } // namespace
197 namespace mozilla::storage {
199 const char* GetBaseVFSName(bool exclusive) {
200 return exclusive ? "base-vfs-excl" : "base-vfs";
203 UniquePtr<sqlite3_vfs> ConstructBaseVFS(bool exclusive) {
204 #if defined(XP_WIN)
205 # define EXPECTED_VFS "win32"
206 # define EXPECTED_VFS_EXCL "win32"
207 #else
208 # define EXPECTED_VFS "unix"
209 # define EXPECTED_VFS_EXCL "unix-excl"
210 #endif
212 if (sqlite3_vfs_find(GetBaseVFSName(exclusive))) {
213 return nullptr;
216 bool found;
217 sqlite3_vfs* origVfs;
218 if (!exclusive) {
219 // Use the non-exclusive VFS.
220 origVfs = sqlite3_vfs_find(nullptr);
221 found = origVfs && origVfs->zName && !strcmp(origVfs->zName, EXPECTED_VFS);
222 } else {
223 origVfs = sqlite3_vfs_find(EXPECTED_VFS_EXCL);
224 found = (origVfs != nullptr);
226 if (!found) {
227 return nullptr;
230 // If the VFS version is higher than the last known one, you should update
231 // this VFS adding appropriate methods for any methods added in the version
232 // change.
233 MOZ_ASSERT(origVfs->iVersion == kLastKnowVfsVersion);
235 sqlite3_vfs vfs = {
236 kLastKnowVfsVersion, /* iVersion */
237 origVfs->szOsFile + static_cast<int>(sizeof(BaseFile)), /* szOsFile */
238 origVfs->mxPathname, /* mxPathname */
239 nullptr, /* pNext */
240 GetBaseVFSName(exclusive), /* zName */
241 origVfs, /* pAppData */
242 BaseOpen, /* xOpen */
243 origVfs->xDelete, /* xDelete */
244 origVfs->xAccess, /* xAccess */
245 origVfs->xFullPathname, /* xFullPathname */
246 origVfs->xDlOpen, /* xDlOpen */
247 origVfs->xDlError, /* xDlError */
248 origVfs->xDlSym, /* xDlSym */
249 origVfs->xDlClose, /* xDlClose */
250 origVfs->xRandomness, /* xRandomness */
251 origVfs->xSleep, /* xSleep */
252 origVfs->xCurrentTime, /* xCurrentTime */
253 origVfs->xGetLastError, /* xGetLastError */
254 origVfs->xCurrentTimeInt64, /* xCurrentTimeInt64 */
255 origVfs->xSetSystemCall, /* xSetSystemCall */
256 origVfs->xGetSystemCall, /* xGetSystemCall */
257 origVfs->xNextSystemCall /* xNextSystemCall */
260 return MakeUnique<sqlite3_vfs>(vfs);
263 } // namespace mozilla::storage