1 | /* |
2 | ** 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" |
17 | |
18 | /* |
19 | ** 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) |
24 | int sqlite3_io_error_hit = 0; /* Total number of I/O Errors */ |
25 | int sqlite3_io_error_hardhit = 0; /* Number of non-benign errors */ |
26 | int sqlite3_io_error_pending = 0; /* Count down to first I/O error */ |
27 | int sqlite3_io_error_persist = 0; /* True if I/O errors persist */ |
28 | int sqlite3_io_error_benign = 0; /* True if errors are benign */ |
29 | int sqlite3_diskfull_pending = 0; |
30 | int 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) |
37 | int sqlite3_open_file_count = 0; |
38 | #endif /* defined(SQLITE_TEST) */ |
39 | |
40 | /* |
41 | ** 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 | ** |
47 | ** The following functions are instrumented for malloc() failure |
48 | ** testing: |
49 | ** |
50 | ** sqlite3OsRead() |
51 | ** sqlite3OsWrite() |
52 | ** sqlite3OsSync() |
53 | ** sqlite3OsFileSize() |
54 | ** sqlite3OsLock() |
55 | ** sqlite3OsCheckReservedLock() |
56 | ** sqlite3OsFileControl() |
57 | ** sqlite3OsShmMap() |
58 | ** sqlite3OsOpen() |
59 | ** sqlite3OsDelete() |
60 | ** sqlite3OsAccess() |
61 | ** sqlite3OsFullPathname() |
62 | ** |
63 | */ |
64 | #if defined(SQLITE_TEST) |
65 | int sqlite3_memdebug_vfs_oom_test = 1; |
66 | #define DO_OS_MALLOC_TEST(x) \ |
67 | if (sqlite3_memdebug_vfs_oom_test && (!x || !sqlite3JournalIsInMemory(x))) { \ |
68 | void *pTstAlloc = sqlite3Malloc(10); \ |
69 | if (!pTstAlloc) return SQLITE_IOERR_NOMEM_BKPT; \ |
70 | sqlite3_free(pTstAlloc); \ |
71 | } |
72 | #else |
73 | #define DO_OS_MALLOC_TEST(x) |
74 | #endif |
75 | |
76 | /* |
77 | ** The following routines are convenience wrappers around methods |
78 | ** of the sqlite3_file object. This is mostly just syntactic sugar. All |
79 | ** of this would be completely automatic if SQLite were coded using |
80 | ** C++ instead of plain old C. |
81 | */ |
82 | void sqlite3OsClose(sqlite3_file *pId){ |
83 | if( pId->pMethods ){ |
84 | pId->pMethods->xClose(pId); |
85 | pId->pMethods = 0; |
86 | } |
87 | } |
88 | int sqlite3OsRead(sqlite3_file *id, void *pBuf, int amt, i64 offset){ |
89 | DO_OS_MALLOC_TEST(id); |
90 | return id->pMethods->xRead(id, pBuf, amt, offset); |
91 | } |
92 | int sqlite3OsWrite(sqlite3_file *id, const void *pBuf, int amt, i64 offset){ |
93 | DO_OS_MALLOC_TEST(id); |
94 | return id->pMethods->xWrite(id, pBuf, amt, offset); |
95 | } |
96 | int sqlite3OsTruncate(sqlite3_file *id, i64 size){ |
97 | return id->pMethods->xTruncate(id, size); |
98 | } |
99 | int sqlite3OsSync(sqlite3_file *id, int flags){ |
100 | DO_OS_MALLOC_TEST(id); |
101 | return flags ? id->pMethods->xSync(id, flags) : SQLITE_OK; |
102 | } |
103 | int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){ |
104 | DO_OS_MALLOC_TEST(id); |
105 | return id->pMethods->xFileSize(id, pSize); |
106 | } |
107 | int sqlite3OsLock(sqlite3_file *id, int lockType){ |
108 | DO_OS_MALLOC_TEST(id); |
109 | assert( lockType>=SQLITE_LOCK_SHARED && lockType<=SQLITE_LOCK_EXCLUSIVE ); |
110 | return id->pMethods->xLock(id, lockType); |
111 | } |
112 | int sqlite3OsUnlock(sqlite3_file *id, int lockType){ |
113 | assert( lockType==SQLITE_LOCK_NONE || lockType==SQLITE_LOCK_SHARED ); |
114 | return id->pMethods->xUnlock(id, lockType); |
115 | } |
116 | int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut){ |
117 | DO_OS_MALLOC_TEST(id); |
118 | return id->pMethods->xCheckReservedLock(id, pResOut); |
119 | } |
120 | |
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 | */ |
129 | int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){ |
130 | if( id->pMethods==0 ) return SQLITE_NOTFOUND; |
131 | #ifdef SQLITE_TEST |
132 | if( op!=SQLITE_FCNTL_COMMIT_PHASETWO |
133 | && op!=SQLITE_FCNTL_LOCK_TIMEOUT |
134 | && op!=SQLITE_FCNTL_CKPT_DONE |
135 | && op!=SQLITE_FCNTL_CKPT_START |
136 | ){ |
137 | /* Faults are not injected into COMMIT_PHASETWO because, assuming SQLite |
138 | ** is using a regular VFS, it is called after the corresponding |
139 | ** transaction has been committed. Injecting a fault at this point |
140 | ** confuses the test scripts - the COMMIT comand returns SQLITE_NOMEM |
141 | ** 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 |
146 | ** 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 | */ |
152 | DO_OS_MALLOC_TEST(id); |
153 | } |
154 | #endif |
155 | return id->pMethods->xFileControl(id, op, pArg); |
156 | } |
157 | void sqlite3OsFileControlHint(sqlite3_file *id, int op, void *pArg){ |
158 | if( id->pMethods ) (void)id->pMethods->xFileControl(id, op, pArg); |
159 | } |
160 | |
161 | int sqlite3OsSectorSize(sqlite3_file *id){ |
162 | int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize; |
163 | return (xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE); |
164 | } |
165 | int sqlite3OsDeviceCharacteristics(sqlite3_file *id){ |
166 | if( NEVER(id->pMethods==0) ) return 0; |
167 | return id->pMethods->xDeviceCharacteristics(id); |
168 | } |
169 | #ifndef SQLITE_OMIT_WAL |
170 | int sqlite3OsShmLock(sqlite3_file *id, int offset, int n, int flags){ |
171 | return id->pMethods->xShmLock(id, offset, n, flags); |
172 | } |
173 | void sqlite3OsShmBarrier(sqlite3_file *id){ |
174 | id->pMethods->xShmBarrier(id); |
175 | } |
176 | int sqlite3OsShmUnmap(sqlite3_file *id, int deleteFlag){ |
177 | return id->pMethods->xShmUnmap(id, deleteFlag); |
178 | } |
179 | int sqlite3OsShmMap( |
180 | 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 */ |
185 | ){ |
186 | DO_OS_MALLOC_TEST(id); |
187 | return id->pMethods->xShmMap(id, iPage, pgsz, bExtend, pp); |
188 | } |
189 | #endif /* SQLITE_OMIT_WAL */ |
190 | |
191 | #if SQLITE_MAX_MMAP_SIZE>0 |
192 | /* The real implementation of xFetch and xUnfetch */ |
193 | int sqlite3OsFetch(sqlite3_file *id, i64 iOff, int iAmt, void **pp){ |
194 | DO_OS_MALLOC_TEST(id); |
195 | return id->pMethods->xFetch(id, iOff, iAmt, pp); |
196 | } |
197 | int sqlite3OsUnfetch(sqlite3_file *id, i64 iOff, void *p){ |
198 | return id->pMethods->xUnfetch(id, iOff, p); |
199 | } |
200 | #else |
201 | /* No-op stubs to use when memory-mapped I/O is disabled */ |
202 | int sqlite3OsFetch(sqlite3_file *id, i64 iOff, int iAmt, void **pp){ |
203 | *pp = 0; |
204 | return SQLITE_OK; |
205 | } |
206 | int sqlite3OsUnfetch(sqlite3_file *id, i64 iOff, void *p){ |
207 | return SQLITE_OK; |
208 | } |
209 | #endif |
210 | |
211 | /* |
212 | ** The next group of routines are convenience wrappers around the |
213 | ** VFS methods. |
214 | */ |
215 | int sqlite3OsOpen( |
216 | sqlite3_vfs *pVfs, |
217 | const char *zPath, |
218 | sqlite3_file *pFile, |
219 | int flags, |
220 | int *pFlagsOut |
221 | ){ |
222 | int rc; |
223 | DO_OS_MALLOC_TEST(0); |
224 | /* 0x87f7f is a mask of SQLITE_OPEN_ flags that are valid to be passed |
225 | ** 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. */ |
228 | assert( zPath || (flags & SQLITE_OPEN_EXCLUSIVE) ); |
229 | rc = pVfs->xOpen(pVfs, zPath, pFile, flags & 0x1087f7f, pFlagsOut); |
230 | assert( rc==SQLITE_OK || pFile->pMethods==0 ); |
231 | return rc; |
232 | } |
233 | int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ |
234 | DO_OS_MALLOC_TEST(0); |
235 | assert( dirSync==0 || dirSync==1 ); |
236 | return pVfs->xDelete!=0 ? pVfs->xDelete(pVfs, zPath, dirSync) : SQLITE_OK; |
237 | } |
238 | int sqlite3OsAccess( |
239 | sqlite3_vfs *pVfs, |
240 | const char *zPath, |
241 | int flags, |
242 | int *pResOut |
243 | ){ |
244 | DO_OS_MALLOC_TEST(0); |
245 | return pVfs->xAccess(pVfs, zPath, flags, pResOut); |
246 | } |
247 | int sqlite3OsFullPathname( |
248 | sqlite3_vfs *pVfs, |
249 | const char *zPath, |
250 | int nPathOut, |
251 | char *zPathOut |
252 | ){ |
253 | DO_OS_MALLOC_TEST(0); |
254 | zPathOut[0] = 0; |
255 | return pVfs->xFullPathname(pVfs, zPath, nPathOut, zPathOut); |
256 | } |
257 | #ifndef SQLITE_OMIT_LOAD_EXTENSION |
258 | void *sqlite3OsDlOpen(sqlite3_vfs *pVfs, const char *zPath){ |
259 | assert( zPath!=0 ); |
260 | assert( strlen(zPath)<=SQLITE_MAX_PATHLEN ); /* tag-20210611-1 */ |
261 | return pVfs->xDlOpen(pVfs, zPath); |
262 | } |
263 | void sqlite3OsDlError(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ |
264 | pVfs->xDlError(pVfs, nByte, zBufOut); |
265 | } |
266 | void (*sqlite3OsDlSym(sqlite3_vfs *pVfs, void *pHdle, const char *zSym))(void){ |
267 | return pVfs->xDlSym(pVfs, pHdle, zSym); |
268 | } |
269 | void sqlite3OsDlClose(sqlite3_vfs *pVfs, void *pHandle){ |
270 | pVfs->xDlClose(pVfs, pHandle); |
271 | } |
272 | #endif /* SQLITE_OMIT_LOAD_EXTENSION */ |
273 | int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ |
274 | if( sqlite3Config.iPrngSeed ){ |
275 | memset(zBufOut, 0, nByte); |
276 | if( ALWAYS(nByte>(signed)sizeof(unsigned)) ) nByte = sizeof(unsigned int); |
277 | memcpy(zBufOut, &sqlite3Config.iPrngSeed, nByte); |
278 | return SQLITE_OK; |
279 | }else{ |
280 | return pVfs->xRandomness(pVfs, nByte, zBufOut); |
281 | } |
282 | |
283 | } |
284 | int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){ |
285 | return pVfs->xSleep(pVfs, nMicro); |
286 | } |
287 | int sqlite3OsGetLastError(sqlite3_vfs *pVfs){ |
288 | return pVfs->xGetLastError ? pVfs->xGetLastError(pVfs, 0, 0) : 0; |
289 | } |
290 | int sqlite3OsCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){ |
291 | int rc; |
292 | /* 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 | */ |
298 | 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; |
306 | } |
307 | |
308 | int sqlite3OsOpenMalloc( |
309 | sqlite3_vfs *pVfs, |
310 | const char *zFile, |
311 | sqlite3_file **ppFile, |
312 | int flags, |
313 | int *pOutFlags |
314 | ){ |
315 | int rc; |
316 | sqlite3_file *pFile; |
317 | pFile = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile); |
318 | if( pFile ){ |
319 | rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags); |
320 | if( rc!=SQLITE_OK ){ |
321 | sqlite3_free(pFile); |
322 | *ppFile = 0; |
323 | }else{ |
324 | *ppFile = pFile; |
325 | } |
326 | }else{ |
327 | *ppFile = 0; |
328 | rc = SQLITE_NOMEM_BKPT; |
329 | } |
330 | assert( *ppFile!=0 || rc!=SQLITE_OK ); |
331 | return rc; |
332 | } |
333 | void sqlite3OsCloseFree(sqlite3_file *pFile){ |
334 | assert( pFile ); |
335 | sqlite3OsClose(pFile); |
336 | sqlite3_free(pFile); |
337 | } |
338 | |
339 | /* |
340 | ** 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 | */ |
345 | int sqlite3OsInit(void){ |
346 | void *p = sqlite3_malloc(10); |
347 | if( p==0 ) return SQLITE_NOMEM_BKPT; |
348 | sqlite3_free(p); |
349 | return sqlite3_os_init(); |
350 | } |
351 | |
352 | /* |
353 | ** The list of all registered VFS implementations. |
354 | */ |
355 | static sqlite3_vfs * SQLITE_WSD vfsList = 0; |
356 | #define vfsList GLOBAL(sqlite3_vfs *, vfsList) |
357 | |
358 | /* |
359 | ** Locate a VFS by name. If no name is given, simply return the |
360 | ** first VFS on the list. |
361 | */ |
362 | sqlite3_vfs *sqlite3_vfs_find(const char *zVfs){ |
363 | sqlite3_vfs *pVfs = 0; |
364 | #if SQLITE_THREADSAFE |
365 | sqlite3_mutex *mutex; |
366 | #endif |
367 | #ifndef SQLITE_OMIT_AUTOINIT |
368 | int rc = sqlite3_initialize(); |
369 | if( rc ) return 0; |
370 | #endif |
371 | #if SQLITE_THREADSAFE |
372 | mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN); |
373 | #endif |
374 | 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 | } |
379 | sqlite3_mutex_leave(mutex); |
380 | return pVfs; |
381 | } |
382 | |
383 | /* |
384 | ** Unlink a VFS from the linked list |
385 | */ |
386 | static void vfsUnlink(sqlite3_vfs *pVfs){ |
387 | assert( sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN)) ); |
388 | if( pVfs==0 ){ |
389 | /* No-op */ |
390 | }else if( vfsList==pVfs ){ |
391 | vfsList = pVfs->pNext; |
392 | }else if( vfsList ){ |
393 | 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 | */ |
408 | int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){ |
409 | MUTEX_LOGIC(sqlite3_mutex *mutex;) |
410 | #ifndef SQLITE_OMIT_AUTOINIT |
411 | int rc = sqlite3_initialize(); |
412 | if( rc ) return rc; |
413 | #endif |
414 | #ifdef SQLITE_ENABLE_API_ARMOR |
415 | if( pVfs==0 ) return SQLITE_MISUSE_BKPT; |
416 | #endif |
417 | |
418 | MUTEX_LOGIC( mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN); ) |
419 | 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; |
426 | vfsList->pNext = pVfs; |
427 | } |
428 | assert(vfsList); |
429 | sqlite3_mutex_leave(mutex); |
430 | return SQLITE_OK; |
431 | } |
432 | |
433 | /* |
434 | ** Unregister a VFS so that it is no longer accessible. |
435 | */ |
436 | int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){ |
437 | MUTEX_LOGIC(sqlite3_mutex *mutex;) |
438 | #ifndef SQLITE_OMIT_AUTOINIT |
439 | int rc = sqlite3_initialize(); |
440 | if( rc ) return rc; |
441 | #endif |
442 | MUTEX_LOGIC( mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MAIN); ) |
443 | sqlite3_mutex_enter(mutex); |
444 | vfsUnlink(pVfs); |
445 | sqlite3_mutex_leave(mutex); |
446 | return SQLITE_OK; |
447 | } |
448 | |