| OLD | NEW |
| (Empty) |
| 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 #define _SQLITE_OS_C_ 1 | |
| 17 #include "sqliteInt.h" | |
| 18 #undef _SQLITE_OS_C_ | |
| 19 | |
| 20 /* | |
| 21 ** The default SQLite sqlite3_vfs implementations do not allocate | |
| 22 ** memory (actually, os_unix.c allocates a small amount of memory | |
| 23 ** from within OsOpen()), but some third-party implementations may. | |
| 24 ** So we test the effects of a malloc() failing and the sqlite3OsXXX() | |
| 25 ** function returning SQLITE_IOERR_NOMEM using the DO_OS_MALLOC_TEST macro. | |
| 26 ** | |
| 27 ** The following functions are instrumented for malloc() failure | |
| 28 ** testing: | |
| 29 ** | |
| 30 ** sqlite3OsRead() | |
| 31 ** sqlite3OsWrite() | |
| 32 ** sqlite3OsSync() | |
| 33 ** sqlite3OsFileSize() | |
| 34 ** sqlite3OsLock() | |
| 35 ** sqlite3OsCheckReservedLock() | |
| 36 ** sqlite3OsFileControl() | |
| 37 ** sqlite3OsShmMap() | |
| 38 ** sqlite3OsOpen() | |
| 39 ** sqlite3OsDelete() | |
| 40 ** sqlite3OsAccess() | |
| 41 ** sqlite3OsFullPathname() | |
| 42 ** | |
| 43 */ | |
| 44 #if defined(SQLITE_TEST) | |
| 45 int sqlite3_memdebug_vfs_oom_test = 1; | |
| 46 #define DO_OS_MALLOC_TEST(x) \ | |
| 47 if (sqlite3_memdebug_vfs_oom_test && (!x || !sqlite3IsMemJournal(x))) { \ | |
| 48 void *pTstAlloc = sqlite3Malloc(10); \ | |
| 49 if (!pTstAlloc) return SQLITE_IOERR_NOMEM; \ | |
| 50 sqlite3_free(pTstAlloc); \ | |
| 51 } | |
| 52 #else | |
| 53 #define DO_OS_MALLOC_TEST(x) | |
| 54 #endif | |
| 55 | |
| 56 /* | |
| 57 ** The following routines are convenience wrappers around methods | |
| 58 ** of the sqlite3_file object. This is mostly just syntactic sugar. All | |
| 59 ** of this would be completely automatic if SQLite were coded using | |
| 60 ** C++ instead of plain old C. | |
| 61 */ | |
| 62 int sqlite3OsClose(sqlite3_file *pId){ | |
| 63 int rc = SQLITE_OK; | |
| 64 if( pId->pMethods ){ | |
| 65 rc = pId->pMethods->xClose(pId); | |
| 66 pId->pMethods = 0; | |
| 67 } | |
| 68 return rc; | |
| 69 } | |
| 70 int sqlite3OsRead(sqlite3_file *id, void *pBuf, int amt, i64 offset){ | |
| 71 DO_OS_MALLOC_TEST(id); | |
| 72 return id->pMethods->xRead(id, pBuf, amt, offset); | |
| 73 } | |
| 74 int sqlite3OsWrite(sqlite3_file *id, const void *pBuf, int amt, i64 offset){ | |
| 75 DO_OS_MALLOC_TEST(id); | |
| 76 return id->pMethods->xWrite(id, pBuf, amt, offset); | |
| 77 } | |
| 78 int sqlite3OsTruncate(sqlite3_file *id, i64 size){ | |
| 79 return id->pMethods->xTruncate(id, size); | |
| 80 } | |
| 81 int sqlite3OsSync(sqlite3_file *id, int flags){ | |
| 82 DO_OS_MALLOC_TEST(id); | |
| 83 return id->pMethods->xSync(id, flags); | |
| 84 } | |
| 85 int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){ | |
| 86 DO_OS_MALLOC_TEST(id); | |
| 87 return id->pMethods->xFileSize(id, pSize); | |
| 88 } | |
| 89 int sqlite3OsLock(sqlite3_file *id, int lockType){ | |
| 90 DO_OS_MALLOC_TEST(id); | |
| 91 return id->pMethods->xLock(id, lockType); | |
| 92 } | |
| 93 int sqlite3OsUnlock(sqlite3_file *id, int lockType){ | |
| 94 return id->pMethods->xUnlock(id, lockType); | |
| 95 } | |
| 96 int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut){ | |
| 97 DO_OS_MALLOC_TEST(id); | |
| 98 return id->pMethods->xCheckReservedLock(id, pResOut); | |
| 99 } | |
| 100 | |
| 101 /* | |
| 102 ** Use sqlite3OsFileControl() when we are doing something that might fail | |
| 103 ** and we need to know about the failures. Use sqlite3OsFileControlHint() | |
| 104 ** when simply tossing information over the wall to the VFS and we do not | |
| 105 ** really care if the VFS receives and understands the information since it | |
| 106 ** is only a hint and can be safely ignored. The sqlite3OsFileControlHint() | |
| 107 ** routine has no return value since the return value would be meaningless. | |
| 108 */ | |
| 109 int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){ | |
| 110 #ifdef SQLITE_TEST | |
| 111 if( op!=SQLITE_FCNTL_COMMIT_PHASETWO ){ | |
| 112 /* Faults are not injected into COMMIT_PHASETWO because, assuming SQLite | |
| 113 ** is using a regular VFS, it is called after the corresponding | |
| 114 ** transaction has been committed. Injecting a fault at this point | |
| 115 ** confuses the test scripts - the COMMIT comand returns SQLITE_NOMEM | |
| 116 ** but the transaction is committed anyway. | |
| 117 ** | |
| 118 ** The core must call OsFileControl() though, not OsFileControlHint(), | |
| 119 ** as if a custom VFS (e.g. zipvfs) returns an error here, it probably | |
| 120 ** means the commit really has failed and an error should be returned | |
| 121 ** to the user. */ | |
| 122 DO_OS_MALLOC_TEST(id); | |
| 123 } | |
| 124 #endif | |
| 125 return id->pMethods->xFileControl(id, op, pArg); | |
| 126 } | |
| 127 void sqlite3OsFileControlHint(sqlite3_file *id, int op, void *pArg){ | |
| 128 (void)id->pMethods->xFileControl(id, op, pArg); | |
| 129 } | |
| 130 | |
| 131 int sqlite3OsSectorSize(sqlite3_file *id){ | |
| 132 int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize; | |
| 133 return (xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE); | |
| 134 } | |
| 135 int sqlite3OsDeviceCharacteristics(sqlite3_file *id){ | |
| 136 return id->pMethods->xDeviceCharacteristics(id); | |
| 137 } | |
| 138 int sqlite3OsShmLock(sqlite3_file *id, int offset, int n, int flags){ | |
| 139 return id->pMethods->xShmLock(id, offset, n, flags); | |
| 140 } | |
| 141 void sqlite3OsShmBarrier(sqlite3_file *id){ | |
| 142 id->pMethods->xShmBarrier(id); | |
| 143 } | |
| 144 int sqlite3OsShmUnmap(sqlite3_file *id, int deleteFlag){ | |
| 145 return id->pMethods->xShmUnmap(id, deleteFlag); | |
| 146 } | |
| 147 int sqlite3OsShmMap( | |
| 148 sqlite3_file *id, /* Database file handle */ | |
| 149 int iPage, | |
| 150 int pgsz, | |
| 151 int bExtend, /* True to extend file if necessary */ | |
| 152 void volatile **pp /* OUT: Pointer to mapping */ | |
| 153 ){ | |
| 154 DO_OS_MALLOC_TEST(id); | |
| 155 return id->pMethods->xShmMap(id, iPage, pgsz, bExtend, pp); | |
| 156 } | |
| 157 | |
| 158 #if SQLITE_MAX_MMAP_SIZE>0 | |
| 159 /* The real implementation of xFetch and xUnfetch */ | |
| 160 int sqlite3OsFetch(sqlite3_file *id, i64 iOff, int iAmt, void **pp){ | |
| 161 DO_OS_MALLOC_TEST(id); | |
| 162 return id->pMethods->xFetch(id, iOff, iAmt, pp); | |
| 163 } | |
| 164 int sqlite3OsUnfetch(sqlite3_file *id, i64 iOff, void *p){ | |
| 165 return id->pMethods->xUnfetch(id, iOff, p); | |
| 166 } | |
| 167 #else | |
| 168 /* No-op stubs to use when memory-mapped I/O is disabled */ | |
| 169 int sqlite3OsFetch(sqlite3_file *id, i64 iOff, int iAmt, void **pp){ | |
| 170 *pp = 0; | |
| 171 return SQLITE_OK; | |
| 172 } | |
| 173 int sqlite3OsUnfetch(sqlite3_file *id, i64 iOff, void *p){ | |
| 174 return SQLITE_OK; | |
| 175 } | |
| 176 #endif | |
| 177 | |
| 178 /* | |
| 179 ** The next group of routines are convenience wrappers around the | |
| 180 ** VFS methods. | |
| 181 */ | |
| 182 int sqlite3OsOpen( | |
| 183 sqlite3_vfs *pVfs, | |
| 184 const char *zPath, | |
| 185 sqlite3_file *pFile, | |
| 186 int flags, | |
| 187 int *pFlagsOut | |
| 188 ){ | |
| 189 int rc; | |
| 190 DO_OS_MALLOC_TEST(0); | |
| 191 /* 0x87f7f is a mask of SQLITE_OPEN_ flags that are valid to be passed | |
| 192 ** down into the VFS layer. Some SQLITE_OPEN_ flags (for example, | |
| 193 ** SQLITE_OPEN_FULLMUTEX or SQLITE_OPEN_SHAREDCACHE) are blocked before | |
| 194 ** reaching the VFS. */ | |
| 195 rc = pVfs->xOpen(pVfs, zPath, pFile, flags & 0x87f7f, pFlagsOut); | |
| 196 assert( rc==SQLITE_OK || pFile->pMethods==0 ); | |
| 197 return rc; | |
| 198 } | |
| 199 int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ | |
| 200 DO_OS_MALLOC_TEST(0); | |
| 201 assert( dirSync==0 || dirSync==1 ); | |
| 202 return pVfs->xDelete(pVfs, zPath, dirSync); | |
| 203 } | |
| 204 int sqlite3OsAccess( | |
| 205 sqlite3_vfs *pVfs, | |
| 206 const char *zPath, | |
| 207 int flags, | |
| 208 int *pResOut | |
| 209 ){ | |
| 210 DO_OS_MALLOC_TEST(0); | |
| 211 return pVfs->xAccess(pVfs, zPath, flags, pResOut); | |
| 212 } | |
| 213 int sqlite3OsFullPathname( | |
| 214 sqlite3_vfs *pVfs, | |
| 215 const char *zPath, | |
| 216 int nPathOut, | |
| 217 char *zPathOut | |
| 218 ){ | |
| 219 DO_OS_MALLOC_TEST(0); | |
| 220 zPathOut[0] = 0; | |
| 221 return pVfs->xFullPathname(pVfs, zPath, nPathOut, zPathOut); | |
| 222 } | |
| 223 #ifndef SQLITE_OMIT_LOAD_EXTENSION | |
| 224 void *sqlite3OsDlOpen(sqlite3_vfs *pVfs, const char *zPath){ | |
| 225 return pVfs->xDlOpen(pVfs, zPath); | |
| 226 } | |
| 227 void sqlite3OsDlError(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ | |
| 228 pVfs->xDlError(pVfs, nByte, zBufOut); | |
| 229 } | |
| 230 void (*sqlite3OsDlSym(sqlite3_vfs *pVfs, void *pHdle, const char *zSym))(void){ | |
| 231 return pVfs->xDlSym(pVfs, pHdle, zSym); | |
| 232 } | |
| 233 void sqlite3OsDlClose(sqlite3_vfs *pVfs, void *pHandle){ | |
| 234 pVfs->xDlClose(pVfs, pHandle); | |
| 235 } | |
| 236 #endif /* SQLITE_OMIT_LOAD_EXTENSION */ | |
| 237 int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ | |
| 238 return pVfs->xRandomness(pVfs, nByte, zBufOut); | |
| 239 } | |
| 240 int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){ | |
| 241 return pVfs->xSleep(pVfs, nMicro); | |
| 242 } | |
| 243 int sqlite3OsCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){ | |
| 244 int rc; | |
| 245 /* IMPLEMENTATION-OF: R-49045-42493 SQLite will use the xCurrentTimeInt64() | |
| 246 ** method to get the current date and time if that method is available | |
| 247 ** (if iVersion is 2 or greater and the function pointer is not NULL) and | |
| 248 ** will fall back to xCurrentTime() if xCurrentTimeInt64() is | |
| 249 ** unavailable. | |
| 250 */ | |
| 251 if( pVfs->iVersion>=2 && pVfs->xCurrentTimeInt64 ){ | |
| 252 rc = pVfs->xCurrentTimeInt64(pVfs, pTimeOut); | |
| 253 }else{ | |
| 254 double r; | |
| 255 rc = pVfs->xCurrentTime(pVfs, &r); | |
| 256 *pTimeOut = (sqlite3_int64)(r*86400000.0); | |
| 257 } | |
| 258 return rc; | |
| 259 } | |
| 260 | |
| 261 int sqlite3OsOpenMalloc( | |
| 262 sqlite3_vfs *pVfs, | |
| 263 const char *zFile, | |
| 264 sqlite3_file **ppFile, | |
| 265 int flags, | |
| 266 int *pOutFlags | |
| 267 ){ | |
| 268 int rc = SQLITE_NOMEM; | |
| 269 sqlite3_file *pFile; | |
| 270 pFile = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile); | |
| 271 if( pFile ){ | |
| 272 rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags); | |
| 273 if( rc!=SQLITE_OK ){ | |
| 274 sqlite3_free(pFile); | |
| 275 }else{ | |
| 276 *ppFile = pFile; | |
| 277 } | |
| 278 } | |
| 279 return rc; | |
| 280 } | |
| 281 int sqlite3OsCloseFree(sqlite3_file *pFile){ | |
| 282 int rc = SQLITE_OK; | |
| 283 assert( pFile ); | |
| 284 rc = sqlite3OsClose(pFile); | |
| 285 sqlite3_free(pFile); | |
| 286 return rc; | |
| 287 } | |
| 288 | |
| 289 /* | |
| 290 ** This function is a wrapper around the OS specific implementation of | |
| 291 ** sqlite3_os_init(). The purpose of the wrapper is to provide the | |
| 292 ** ability to simulate a malloc failure, so that the handling of an | |
| 293 ** error in sqlite3_os_init() by the upper layers can be tested. | |
| 294 */ | |
| 295 int sqlite3OsInit(void){ | |
| 296 void *p = sqlite3_malloc(10); | |
| 297 if( p==0 ) return SQLITE_NOMEM; | |
| 298 sqlite3_free(p); | |
| 299 return sqlite3_os_init(); | |
| 300 } | |
| 301 | |
| 302 /* | |
| 303 ** The list of all registered VFS implementations. | |
| 304 */ | |
| 305 static sqlite3_vfs * SQLITE_WSD vfsList = 0; | |
| 306 #define vfsList GLOBAL(sqlite3_vfs *, vfsList) | |
| 307 | |
| 308 /* | |
| 309 ** Locate a VFS by name. If no name is given, simply return the | |
| 310 ** first VFS on the list. | |
| 311 */ | |
| 312 sqlite3_vfs *sqlite3_vfs_find(const char *zVfs){ | |
| 313 sqlite3_vfs *pVfs = 0; | |
| 314 #if SQLITE_THREADSAFE | |
| 315 sqlite3_mutex *mutex; | |
| 316 #endif | |
| 317 #ifndef SQLITE_OMIT_AUTOINIT | |
| 318 int rc = sqlite3_initialize(); | |
| 319 if( rc ) return 0; | |
| 320 #endif | |
| 321 #if SQLITE_THREADSAFE | |
| 322 mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); | |
| 323 #endif | |
| 324 sqlite3_mutex_enter(mutex); | |
| 325 for(pVfs = vfsList; pVfs; pVfs=pVfs->pNext){ | |
| 326 if( zVfs==0 ) break; | |
| 327 if( strcmp(zVfs, pVfs->zName)==0 ) break; | |
| 328 } | |
| 329 sqlite3_mutex_leave(mutex); | |
| 330 return pVfs; | |
| 331 } | |
| 332 | |
| 333 /* | |
| 334 ** Unlink a VFS from the linked list | |
| 335 */ | |
| 336 static void vfsUnlink(sqlite3_vfs *pVfs){ | |
| 337 assert( sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)) ); | |
| 338 if( pVfs==0 ){ | |
| 339 /* No-op */ | |
| 340 }else if( vfsList==pVfs ){ | |
| 341 vfsList = pVfs->pNext; | |
| 342 }else if( vfsList ){ | |
| 343 sqlite3_vfs *p = vfsList; | |
| 344 while( p->pNext && p->pNext!=pVfs ){ | |
| 345 p = p->pNext; | |
| 346 } | |
| 347 if( p->pNext==pVfs ){ | |
| 348 p->pNext = pVfs->pNext; | |
| 349 } | |
| 350 } | |
| 351 } | |
| 352 | |
| 353 /* | |
| 354 ** Register a VFS with the system. It is harmless to register the same | |
| 355 ** VFS multiple times. The new VFS becomes the default if makeDflt is | |
| 356 ** true. | |
| 357 */ | |
| 358 int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){ | |
| 359 MUTEX_LOGIC(sqlite3_mutex *mutex;) | |
| 360 #ifndef SQLITE_OMIT_AUTOINIT | |
| 361 int rc = sqlite3_initialize(); | |
| 362 if( rc ) return rc; | |
| 363 #endif | |
| 364 #ifdef SQLITE_ENABLE_API_ARMOR | |
| 365 if( pVfs==0 ) return SQLITE_MISUSE_BKPT; | |
| 366 #endif | |
| 367 | |
| 368 MUTEX_LOGIC( mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); ) | |
| 369 sqlite3_mutex_enter(mutex); | |
| 370 vfsUnlink(pVfs); | |
| 371 if( makeDflt || vfsList==0 ){ | |
| 372 pVfs->pNext = vfsList; | |
| 373 vfsList = pVfs; | |
| 374 }else{ | |
| 375 pVfs->pNext = vfsList->pNext; | |
| 376 vfsList->pNext = pVfs; | |
| 377 } | |
| 378 assert(vfsList); | |
| 379 sqlite3_mutex_leave(mutex); | |
| 380 return SQLITE_OK; | |
| 381 } | |
| 382 | |
| 383 /* | |
| 384 ** Unregister a VFS so that it is no longer accessible. | |
| 385 */ | |
| 386 int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){ | |
| 387 #if SQLITE_THREADSAFE | |
| 388 sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); | |
| 389 #endif | |
| 390 sqlite3_mutex_enter(mutex); | |
| 391 vfsUnlink(pVfs); | |
| 392 sqlite3_mutex_leave(mutex); | |
| 393 return SQLITE_OK; | |
| 394 } | |
| OLD | NEW |