Thanks to visit codestin.com
Credit goes to chromium.googlesource.com

blob: a9fc732e7e86307f4ff609ca91fd6e9052f7ca55 [file] [log] [blame]
danielk1977a7a8e142008-02-13 18:25:271/*
drh054889e2005-11-30 03:20:312** 2005 November 29
3**
4** The author disclaims copyright to this source code. In place of
5** a legal notice, here is a blessing:
6**
7** May you do good and not evil.
8** May you find forgiveness for yourself and forgive others.
9** May you share freely, never taking more than you give.
10**
11******************************************************************************
12**
13** This file contains OS interface code that is common to all
14** architectures.
15*/
16#include "sqliteInt.h"
drh054889e2005-11-30 03:20:3117
18/*
mistachkinc04c54b2016-02-11 21:28:1619** If we compile with the SQLITE_TEST macro set, then the following block
20** of code will give us the ability to simulate a disk I/O error. This
21** is used for testing the I/O recovery logic.
22*/
23#if defined(SQLITE_TEST)
24int sqlite3_io_error_hit = 0; /* Total number of I/O Errors */
25int sqlite3_io_error_hardhit = 0; /* Number of non-benign errors */
26int sqlite3_io_error_pending = 0; /* Count down to first I/O error */
27int sqlite3_io_error_persist = 0; /* True if I/O errors persist */
28int sqlite3_io_error_benign = 0; /* True if errors are benign */
29int sqlite3_diskfull_pending = 0;
30int sqlite3_diskfull = 0;
31#endif /* defined(SQLITE_TEST) */
32
33/*
34** When testing, also keep a count of the number of open files.
35*/
36#if defined(SQLITE_TEST)
37int sqlite3_open_file_count = 0;
38#endif /* defined(SQLITE_TEST) */
39
40/*
danielk1977ae72d982007-10-03 08:46:4441** The default SQLite sqlite3_vfs implementations do not allocate
42** memory (actually, os_unix.c allocates a small amount of memory
43** from within OsOpen()), but some third-party implementations may.
44** So we test the effects of a malloc() failing and the sqlite3OsXXX()
45** function returning SQLITE_IOERR_NOMEM using the DO_OS_MALLOC_TEST macro.
46**
mistachkinc04c54b2016-02-11 21:28:1647** The following functions are instrumented for malloc() failure
danielk1977ae72d982007-10-03 08:46:4448** testing:
49**
danielk1977ae72d982007-10-03 08:46:4450** sqlite3OsRead()
51** sqlite3OsWrite()
52** sqlite3OsSync()
mistachkin6c3c1a02011-11-12 03:17:4053** sqlite3OsFileSize()
danielk1977ae72d982007-10-03 08:46:4454** sqlite3OsLock()
mistachkin6c3c1a02011-11-12 03:17:4055** sqlite3OsCheckReservedLock()
56** sqlite3OsFileControl()
57** sqlite3OsShmMap()
58** sqlite3OsOpen()
59** sqlite3OsDelete()
60** sqlite3OsAccess()
61** sqlite3OsFullPathname()
danielk1977ae72d982007-10-03 08:46:4462**
63*/
shanehfd286392010-07-02 19:49:3864#if defined(SQLITE_TEST)
danc396d4a2010-07-02 11:27:4365int sqlite3_memdebug_vfs_oom_test = 1;
66 #define DO_OS_MALLOC_TEST(x) \
dan2491de22016-02-27 20:14:5567 if (sqlite3_memdebug_vfs_oom_test && (!x || !sqlite3JournalIsInMemory(x))) { \
danielk1977b5a19202009-07-27 11:41:2068 void *pTstAlloc = sqlite3Malloc(10); \
mistachkinfad30392016-02-13 23:43:4669 if (!pTstAlloc) return SQLITE_IOERR_NOMEM_BKPT; \
danielk1977b5a19202009-07-27 11:41:2070 sqlite3_free(pTstAlloc); \
danielk1977ae72d982007-10-03 08:46:4471 }
72#else
danielk1977b5a19202009-07-27 11:41:2073 #define DO_OS_MALLOC_TEST(x)
danielk1977ae72d982007-10-03 08:46:4474#endif
75
76/*
drh054889e2005-11-30 03:20:3177** The following routines are convenience wrappers around methods
danielk197762079062007-08-15 17:08:4678** of the sqlite3_file object. This is mostly just syntactic sugar. All
drh054889e2005-11-30 03:20:3179** of this would be completely automatic if SQLite were coded using
80** C++ instead of plain old C.
81*/
drh8f2ce912016-04-14 13:16:5882void sqlite3OsClose(sqlite3_file *pId){
danielk1977c7b60172007-08-22 11:22:0383 if( pId->pMethods ){
drh8f2ce912016-04-14 13:16:5884 pId->pMethods->xClose(pId);
danielk1977c7b60172007-08-22 11:22:0385 pId->pMethods = 0;
86 }
drh054889e2005-11-30 03:20:3187}
danielk197762079062007-08-15 17:08:4688int sqlite3OsRead(sqlite3_file *id, void *pBuf, int amt, i64 offset){
danielk1977b5a19202009-07-27 11:41:2089 DO_OS_MALLOC_TEST(id);
danielk197762079062007-08-15 17:08:4690 return id->pMethods->xRead(id, pBuf, amt, offset);
drh054889e2005-11-30 03:20:3191}
danielk197762079062007-08-15 17:08:4692int sqlite3OsWrite(sqlite3_file *id, const void *pBuf, int amt, i64 offset){
danielk1977b5a19202009-07-27 11:41:2093 DO_OS_MALLOC_TEST(id);
danielk197762079062007-08-15 17:08:4694 return id->pMethods->xWrite(id, pBuf, amt, offset);
drh054889e2005-11-30 03:20:3195}
danielk197762079062007-08-15 17:08:4696int sqlite3OsTruncate(sqlite3_file *id, i64 size){
97 return id->pMethods->xTruncate(id, size);
drh054889e2005-11-30 03:20:3198}
danielk197790949c22007-08-17 16:50:3899int sqlite3OsSync(sqlite3_file *id, int flags){
danielk1977b5a19202009-07-27 11:41:20100 DO_OS_MALLOC_TEST(id);
drhdaaae7b2017-08-25 01:14:43101 return flags ? id->pMethods->xSync(id, flags) : SQLITE_OK;
drh054889e2005-11-30 03:20:31102}
danielk197762079062007-08-15 17:08:46103int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){
danielk1977b5a19202009-07-27 11:41:20104 DO_OS_MALLOC_TEST(id);
danielk197762079062007-08-15 17:08:46105 return id->pMethods->xFileSize(id, pSize);
drh054889e2005-11-30 03:20:31106}
danielk197762079062007-08-15 17:08:46107int sqlite3OsLock(sqlite3_file *id, int lockType){
danielk1977b5a19202009-07-27 11:41:20108 DO_OS_MALLOC_TEST(id);
drh2eca0612022-10-04 14:50:46109 assert( lockType>=SQLITE_LOCK_SHARED && lockType<=SQLITE_LOCK_EXCLUSIVE );
danielk197762079062007-08-15 17:08:46110 return id->pMethods->xLock(id, lockType);
drh054889e2005-11-30 03:20:31111}
danielk197762079062007-08-15 17:08:46112int sqlite3OsUnlock(sqlite3_file *id, int lockType){
drh2eca0612022-10-04 14:50:46113 assert( lockType==SQLITE_LOCK_NONE || lockType==SQLITE_LOCK_SHARED );
danielk197762079062007-08-15 17:08:46114 return id->pMethods->xUnlock(id, lockType);
drh054889e2005-11-30 03:20:31115}
danielk1977861f7452008-06-05 11:39:11116int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut){
danielk1977b5a19202009-07-27 11:41:20117 DO_OS_MALLOC_TEST(id);
danielk1977861f7452008-06-05 11:39:11118 return id->pMethods->xCheckReservedLock(id, pResOut);
drh054889e2005-11-30 03:20:31119}
drhc02372c2012-01-10 17:59:59120
121/*
122** Use sqlite3OsFileControl() when we are doing something that might fail
123** and we need to know about the failures. Use sqlite3OsFileControlHint()
124** when simply tossing information over the wall to the VFS and we do not
125** really care if the VFS receives and understands the information since it
126** is only a hint and can be safely ignored. The sqlite3OsFileControlHint()
127** routine has no return value since the return value would be meaningless.
128*/
drhcc6bb3e2007-08-31 16:11:35129int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){
dan6831dbe2018-04-10 14:29:51130 if( id->pMethods==0 ) return SQLITE_NOTFOUND;
dan1001ee82013-12-19 17:04:58131#ifdef SQLITE_TEST
drh000705b2018-03-26 21:05:47132 if( op!=SQLITE_FCNTL_COMMIT_PHASETWO
133 && op!=SQLITE_FCNTL_LOCK_TIMEOUT
drh1de03ab2020-12-03 19:25:06134 && op!=SQLITE_FCNTL_CKPT_DONE
135 && op!=SQLITE_FCNTL_CKPT_START
drh000705b2018-03-26 21:05:47136 ){
dan1001ee82013-12-19 17:04:58137 /* Faults are not injected into COMMIT_PHASETWO because, assuming SQLite
mistachkinc04c54b2016-02-11 21:28:16138 ** is using a regular VFS, it is called after the corresponding
139 ** transaction has been committed. Injecting a fault at this point
larrybrbc917382023-06-07 08:40:31140 ** confuses the test scripts - the COMMIT command returns SQLITE_NOMEM
dan1001ee82013-12-19 17:04:58141 ** but the transaction is committed anyway.
142 **
143 ** The core must call OsFileControl() though, not OsFileControlHint(),
144 ** as if a custom VFS (e.g. zipvfs) returns an error here, it probably
145 ** means the commit really has failed and an error should be returned
drh1de03ab2020-12-03 19:25:06146 ** to the user.
147 **
148 ** The CKPT_DONE and CKPT_START file-controls are write-only signals
149 ** to the cksumvfs. Their return code is meaningless and is ignored
150 ** by the SQLite core, so there is no point in simulating OOMs for them.
151 */
dan1001ee82013-12-19 17:04:58152 DO_OS_MALLOC_TEST(id);
153 }
154#endif
danielk1977861f7452008-06-05 11:39:11155 return id->pMethods->xFileControl(id, op, pArg);
drhcc6bb3e2007-08-31 16:11:35156}
drhc02372c2012-01-10 17:59:59157void sqlite3OsFileControlHint(sqlite3_file *id, int op, void *pArg){
drhafb39a42018-03-29 13:47:01158 if( id->pMethods ) (void)id->pMethods->xFileControl(id, op, pArg);
dan6f2f19a2012-01-10 16:56:39159}
drhc02372c2012-01-10 17:59:59160
danielk1977bf260972008-01-22 11:50:13161int sqlite3OsSectorSize(sqlite3_file *id){
162 int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize;
163 return (xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE);
164}
165int sqlite3OsDeviceCharacteristics(sqlite3_file *id){
drh76fc88f2021-10-02 16:39:16166 if( NEVER(id->pMethods==0) ) return 0;
danielk1977bf260972008-01-22 11:50:13167 return id->pMethods->xDeviceCharacteristics(id);
168}
drh2ed57372017-10-05 20:57:38169#ifndef SQLITE_OMIT_WAL
drh73b64e42010-05-30 19:55:15170int sqlite3OsShmLock(sqlite3_file *id, int offset, int n, int flags){
171 return id->pMethods->xShmLock(id, offset, n, flags);
drhd9e5c4f2010-05-12 18:01:39172}
drh286a2882010-05-20 23:51:06173void sqlite3OsShmBarrier(sqlite3_file *id){
174 id->pMethods->xShmBarrier(id);
175}
drhe11fedc2010-07-14 00:14:30176int sqlite3OsShmUnmap(sqlite3_file *id, int deleteFlag){
danda9fe0c2010-07-13 18:44:03177 return id->pMethods->xShmUnmap(id, deleteFlag);
drhd9e5c4f2010-05-12 18:01:39178}
dan18801912010-06-14 14:07:50179int sqlite3OsShmMap(
danda9fe0c2010-07-13 18:44:03180 sqlite3_file *id, /* Database file handle */
181 int iPage,
182 int pgsz,
183 int bExtend, /* True to extend file if necessary */
184 void volatile **pp /* OUT: Pointer to mapping */
dan13a3cb82010-06-11 19:04:21185){
mistachkin6c3c1a02011-11-12 03:17:40186 DO_OS_MALLOC_TEST(id);
danda9fe0c2010-07-13 18:44:03187 return id->pMethods->xShmMap(id, iPage, pgsz, bExtend, pp);
dan13a3cb82010-06-11 19:04:21188}
drh2ed57372017-10-05 20:57:38189#endif /* SQLITE_OMIT_WAL */
danf23da962013-03-23 21:00:41190
drh9b4c59f2013-04-15 17:03:42191#if SQLITE_MAX_MMAP_SIZE>0
drh188d4882013-04-08 20:47:49192/* The real implementation of xFetch and xUnfetch */
danf23da962013-03-23 21:00:41193int sqlite3OsFetch(sqlite3_file *id, i64 iOff, int iAmt, void **pp){
dana64d5a12013-03-25 18:25:49194 DO_OS_MALLOC_TEST(id);
danf23da962013-03-23 21:00:41195 return id->pMethods->xFetch(id, iOff, iAmt, pp);
196}
dandf737fe2013-03-25 17:00:24197int sqlite3OsUnfetch(sqlite3_file *id, i64 iOff, void *p){
198 return id->pMethods->xUnfetch(id, iOff, p);
dan5d8a1372013-03-19 19:28:06199}
drh188d4882013-04-08 20:47:49200#else
201/* No-op stubs to use when memory-mapped I/O is disabled */
202int sqlite3OsFetch(sqlite3_file *id, i64 iOff, int iAmt, void **pp){
203 *pp = 0;
204 return SQLITE_OK;
205}
206int sqlite3OsUnfetch(sqlite3_file *id, i64 iOff, void *p){
207 return SQLITE_OK;
208}
209#endif
drh3f459022006-01-07 16:06:07210
drhd677b3d2007-08-20 22:48:41211/*
212** The next group of routines are convenience wrappers around the
213** VFS methods.
214*/
danielk1977b4b47412007-08-17 15:53:36215int sqlite3OsOpen(
mistachkinc04c54b2016-02-11 21:28:16216 sqlite3_vfs *pVfs,
217 const char *zPath,
218 sqlite3_file *pFile,
219 int flags,
danielk1977b4b47412007-08-17 15:53:36220 int *pFlagsOut
221){
drh072db2f2009-03-25 14:24:41222 int rc;
danielk1977b5a19202009-07-27 11:41:20223 DO_OS_MALLOC_TEST(0);
dan44659c92011-12-30 05:08:41224 /* 0x87f7f is a mask of SQLITE_OPEN_ flags that are valid to be passed
drhf1f12682009-09-09 14:17:52225 ** down into the VFS layer. Some SQLITE_OPEN_ flags (for example,
226 ** SQLITE_OPEN_FULLMUTEX or SQLITE_OPEN_SHAREDCACHE) are blocked before
227 ** reaching the VFS. */
dan2756f802022-08-16 10:52:35228 assert( zPath || (flags & SQLITE_OPEN_EXCLUSIVE) );
drhc398c652019-11-22 00:42:01229 rc = pVfs->xOpen(pVfs, zPath, pFile, flags & 0x1087f7f, pFlagsOut);
drh072db2f2009-03-25 14:24:41230 assert( rc==SQLITE_OK || pFile->pMethods==0 );
231 return rc;
drh3f459022006-01-07 16:06:07232}
danielk1977fee2d252007-08-18 10:59:19233int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
mistachkin6c3c1a02011-11-12 03:17:40234 DO_OS_MALLOC_TEST(0);
drhe3495192012-01-05 16:07:30235 assert( dirSync==0 || dirSync==1 );
drh8119aab2021-04-06 13:03:06236 return pVfs->xDelete!=0 ? pVfs->xDelete(pVfs, zPath, dirSync) : SQLITE_OK;
danielk1977b4b47412007-08-17 15:53:36237}
danielk1977861f7452008-06-05 11:39:11238int sqlite3OsAccess(
mistachkinc04c54b2016-02-11 21:28:16239 sqlite3_vfs *pVfs,
240 const char *zPath,
241 int flags,
danielk1977861f7452008-06-05 11:39:11242 int *pResOut
243){
danielk1977b5a19202009-07-27 11:41:20244 DO_OS_MALLOC_TEST(0);
danielk1977861f7452008-06-05 11:39:11245 return pVfs->xAccess(pVfs, zPath, flags, pResOut);
danielk1977b4b47412007-08-17 15:53:36246}
danielk1977adfb9b02007-09-17 07:02:56247int sqlite3OsFullPathname(
mistachkinc04c54b2016-02-11 21:28:16248 sqlite3_vfs *pVfs,
249 const char *zPath,
250 int nPathOut,
danielk1977adfb9b02007-09-17 07:02:56251 char *zPathOut
252){
mistachkin6c3c1a02011-11-12 03:17:40253 DO_OS_MALLOC_TEST(0);
drh68ff78b2009-11-16 23:36:33254 zPathOut[0] = 0;
danielk1977adfb9b02007-09-17 07:02:56255 return pVfs->xFullPathname(pVfs, zPath, nPathOut, zPathOut);
danielk1977b4b47412007-08-17 15:53:36256}
shane75998ab2008-05-29 02:52:59257#ifndef SQLITE_OMIT_LOAD_EXTENSION
danielk1977b4b47412007-08-17 15:53:36258void *sqlite3OsDlOpen(sqlite3_vfs *pVfs, const char *zPath){
drhcf145042021-06-11 12:41:14259 assert( zPath!=0 );
260 assert( strlen(zPath)<=SQLITE_MAX_PATHLEN ); /* tag-20210611-1 */
drh153c62c2007-08-24 03:51:33261 return pVfs->xDlOpen(pVfs, zPath);
danielk1977b4b47412007-08-17 15:53:36262}
263void sqlite3OsDlError(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
drh153c62c2007-08-24 03:51:33264 pVfs->xDlError(pVfs, nByte, zBufOut);
danielk1977b4b47412007-08-17 15:53:36265}
drh1875f7a2008-12-08 18:19:17266void (*sqlite3OsDlSym(sqlite3_vfs *pVfs, void *pHdle, const char *zSym))(void){
267 return pVfs->xDlSym(pVfs, pHdle, zSym);
danielk1977b4b47412007-08-17 15:53:36268}
269void sqlite3OsDlClose(sqlite3_vfs *pVfs, void *pHandle){
drh153c62c2007-08-24 03:51:33270 pVfs->xDlClose(pVfs, pHandle);
danielk1977b4b47412007-08-17 15:53:36271}
shane75998ab2008-05-29 02:52:59272#endif /* SQLITE_OMIT_LOAD_EXTENSION */
danielk1977b4b47412007-08-17 15:53:36273int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
drhade54d62019-08-02 20:45:04274 if( sqlite3Config.iPrngSeed ){
275 memset(zBufOut, 0, nByte);
drh51755a72019-08-08 19:40:29276 if( ALWAYS(nByte>(signed)sizeof(unsigned)) ) nByte = sizeof(unsigned int);
drhade54d62019-08-02 20:45:04277 memcpy(zBufOut, &sqlite3Config.iPrngSeed, nByte);
278 return SQLITE_OK;
279 }else{
280 return pVfs->xRandomness(pVfs, nByte, zBufOut);
281 }
larrybrbc917382023-06-07 08:40:31282
danielk1977b4b47412007-08-17 15:53:36283}
284int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){
drh153c62c2007-08-24 03:51:33285 return pVfs->xSleep(pVfs, nMicro);
danielk1977b4b47412007-08-17 15:53:36286}
drh1b9f2142016-03-17 16:01:23287int sqlite3OsGetLastError(sqlite3_vfs *pVfs){
288 return pVfs->xGetLastError ? pVfs->xGetLastError(pVfs, 0, 0) : 0;
289}
drhb7e8ea22010-05-03 14:32:30290int sqlite3OsCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){
291 int rc;
drhbfccdaf2010-09-01 19:29:57292 /* IMPLEMENTATION-OF: R-49045-42493 SQLite will use the xCurrentTimeInt64()
293 ** method to get the current date and time if that method is available
294 ** (if iVersion is 2 or greater and the function pointer is not NULL) and
295 ** will fall back to xCurrentTime() if xCurrentTimeInt64() is
296 ** unavailable.
297 */
drhb7e8ea22010-05-03 14:32:30298 if( pVfs->iVersion>=2 && pVfs->xCurrentTimeInt64 ){
299 rc = pVfs->xCurrentTimeInt64(pVfs, pTimeOut);
300 }else{
301 double r;
302 rc = pVfs->xCurrentTime(pVfs, &r);
303 *pTimeOut = (sqlite3_int64)(r*86400000.0);
304 }
305 return rc;
danielk1977b4b47412007-08-17 15:53:36306}
307
308int sqlite3OsOpenMalloc(
mistachkinc04c54b2016-02-11 21:28:16309 sqlite3_vfs *pVfs,
310 const char *zFile,
311 sqlite3_file **ppFile,
danielk1977967a4a12007-08-20 14:23:44312 int flags,
313 int *pOutFlags
danielk1977b4b47412007-08-17 15:53:36314){
mistachkinfad30392016-02-13 23:43:46315 int rc;
danielk1977b4b47412007-08-17 15:53:36316 sqlite3_file *pFile;
mistachkinf1c40f42011-09-17 15:34:50317 pFile = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile);
danielk1977b4b47412007-08-17 15:53:36318 if( pFile ){
danielk1977967a4a12007-08-20 14:23:44319 rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags);
danielk1977b4b47412007-08-17 15:53:36320 if( rc!=SQLITE_OK ){
321 sqlite3_free(pFile);
drh33d28ab2021-10-28 12:07:43322 *ppFile = 0;
danielk1977b4b47412007-08-17 15:53:36323 }else{
324 *ppFile = pFile;
325 }
mistachkinfad30392016-02-13 23:43:46326 }else{
drh33d28ab2021-10-28 12:07:43327 *ppFile = 0;
mistachkinfad30392016-02-13 23:43:46328 rc = SQLITE_NOMEM_BKPT;
danielk1977b4b47412007-08-17 15:53:36329 }
drh33d28ab2021-10-28 12:07:43330 assert( *ppFile!=0 || rc!=SQLITE_OK );
danielk1977b4b47412007-08-17 15:53:36331 return rc;
332}
drh8f2ce912016-04-14 13:16:58333void sqlite3OsCloseFree(sqlite3_file *pFile){
mlcreech40032982008-04-08 03:09:22334 assert( pFile );
drh8f2ce912016-04-14 13:16:58335 sqlite3OsClose(pFile);
mlcreech40032982008-04-08 03:09:22336 sqlite3_free(pFile);
danielk1977b4b47412007-08-17 15:53:36337}
338
drhd677b3d2007-08-20 22:48:41339/*
dan3d6e0602009-08-17 15:52:25340** This function is a wrapper around the OS specific implementation of
341** sqlite3_os_init(). The purpose of the wrapper is to provide the
342** ability to simulate a malloc failure, so that the handling of an
343** error in sqlite3_os_init() by the upper layers can be tested.
344*/
345int sqlite3OsInit(void){
drhadad77a2009-08-17 16:01:11346 void *p = sqlite3_malloc(10);
mistachkinfad30392016-02-13 23:43:46347 if( p==0 ) return SQLITE_NOMEM_BKPT;
drhadad77a2009-08-17 16:01:11348 sqlite3_free(p);
dan3d6e0602009-08-17 15:52:25349 return sqlite3_os_init();
350}
351
352/*
danielk1977c0fa4c52008-06-25 17:19:00353** The list of all registered VFS implementations.
drhd677b3d2007-08-20 22:48:41354*/
danielk197795e80d62008-09-02 17:18:51355static sqlite3_vfs * SQLITE_WSD vfsList = 0;
danielk19775c8f8582008-09-02 10:22:00356#define vfsList GLOBAL(sqlite3_vfs *, vfsList)
drhd677b3d2007-08-20 22:48:41357
358/*
359** Locate a VFS by name. If no name is given, simply return the
360** first VFS on the list.
361*/
362sqlite3_vfs *sqlite3_vfs_find(const char *zVfs){
drha4189802008-06-19 16:07:07363 sqlite3_vfs *pVfs = 0;
drh18472fa2008-10-07 15:25:48364#if SQLITE_THREADSAFE
drh40257ff2008-06-13 18:24:27365 sqlite3_mutex *mutex;
366#endif
367#ifndef SQLITE_OMIT_AUTOINIT
368 int rc = sqlite3_initialize();
369 if( rc ) return 0;
370#endif
drh18472fa2008-10-07 15:25:48371#if SQLITE_THREADSAFE
drhccb21132020-06-19 11:34:57372 mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN);
drh7e8b8482008-01-23 03:03:05373#endif
drhd677b3d2007-08-20 22:48:41374 sqlite3_mutex_enter(mutex);
375 for(pVfs = vfsList; pVfs; pVfs=pVfs->pNext){
376 if( zVfs==0 ) break;
377 if( strcmp(zVfs, pVfs->zName)==0 ) break;
378 }
drhd677b3d2007-08-20 22:48:41379 sqlite3_mutex_leave(mutex);
380 return pVfs;
danielk1977b4b47412007-08-17 15:53:36381}
382
drhd677b3d2007-08-20 22:48:41383/*
drhd677b3d2007-08-20 22:48:41384** Unlink a VFS from the linked list
385*/
386static void vfsUnlink(sqlite3_vfs *pVfs){
drhccb21132020-06-19 11:34:57387 assert( sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN)) );
drh9bc54492007-10-23 14:49:59388 if( pVfs==0 ){
389 /* No-op */
390 }else if( vfsList==pVfs ){
drhd677b3d2007-08-20 22:48:41391 vfsList = pVfs->pNext;
drh9bc54492007-10-23 14:49:59392 }else if( vfsList ){
drhd677b3d2007-08-20 22:48:41393 sqlite3_vfs *p = vfsList;
394 while( p->pNext && p->pNext!=pVfs ){
395 p = p->pNext;
396 }
397 if( p->pNext==pVfs ){
398 p->pNext = pVfs->pNext;
399 }
400 }
401}
402
403/*
404** Register a VFS with the system. It is harmless to register the same
405** VFS multiple times. The new VFS becomes the default if makeDflt is
406** true.
407*/
408int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
drh30ddce62011-10-15 00:16:30409 MUTEX_LOGIC(sqlite3_mutex *mutex;)
drh40257ff2008-06-13 18:24:27410#ifndef SQLITE_OMIT_AUTOINIT
411 int rc = sqlite3_initialize();
412 if( rc ) return rc;
413#endif
drh9ca95732014-10-24 00:35:58414#ifdef SQLITE_ENABLE_API_ARMOR
415 if( pVfs==0 ) return SQLITE_MISUSE_BKPT;
416#endif
417
drhccb21132020-06-19 11:34:57418 MUTEX_LOGIC( mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN); )
drhd677b3d2007-08-20 22:48:41419 sqlite3_mutex_enter(mutex);
420 vfsUnlink(pVfs);
421 if( makeDflt || vfsList==0 ){
422 pVfs->pNext = vfsList;
423 vfsList = pVfs;
424 }else{
425 pVfs->pNext = vfsList->pNext;
danielk197795c8a542007-09-01 06:51:27426 vfsList->pNext = pVfs;
drhd677b3d2007-08-20 22:48:41427 }
danielk1977f1da17a2007-08-21 13:07:46428 assert(vfsList);
drhd677b3d2007-08-20 22:48:41429 sqlite3_mutex_leave(mutex);
430 return SQLITE_OK;
431}
432
433/*
434** Unregister a VFS so that it is no longer accessible.
435*/
436int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){
dan45f31822018-06-13 11:41:54437 MUTEX_LOGIC(sqlite3_mutex *mutex;)
438#ifndef SQLITE_OMIT_AUTOINIT
439 int rc = sqlite3_initialize();
440 if( rc ) return rc;
drh7e8b8482008-01-23 03:03:05441#endif
drhccb21132020-06-19 11:34:57442 MUTEX_LOGIC( mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN); )
drhd677b3d2007-08-20 22:48:41443 sqlite3_mutex_enter(mutex);
444 vfsUnlink(pVfs);
445 sqlite3_mutex_leave(mutex);
446 return SQLITE_OK;
447}