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/. */
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.
21 #define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData))
24 # define BASE_VFS "win32-none"
26 # define BASE_VFS "unix-none"
29 #define VFS_NAME "readonly-immutable-nolock"
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
) {
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
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 */
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
;
86 namespace mozilla::storage
{
88 UniquePtr
<sqlite3_vfs
> ConstructReadOnlyNoLockVFS() {
89 if (sqlite3_vfs_find(VFS_NAME
) != nullptr) {
92 sqlite3_vfs
* pOrigVfs
= sqlite3_vfs_find(BASE_VFS
);
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
100 MOZ_ASSERT(pOrigVfs
->iVersion
<= 3);
102 static const sqlite3_vfs vfs
= {
103 pOrigVfs
->iVersion
, /* iVersion */
104 pOrigVfs
->szOsFile
, /* szOsFile */
105 pOrigVfs
->mxPathname
, /* mxPathname */
107 VFS_NAME
, /* zName */
108 pOrigVfs
, /* pAppData */
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