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** sqlite3OsOpen() 31** sqlite3OsRead() 32** sqlite3OsWrite() 33** sqlite3OsSync() 34** sqlite3OsLock() 35** 36*/ 37#if defined(SQLITE_TEST) 38int sqlite3_memdebug_vfs_oom_test = 1; 39 #define DO_OS_MALLOC_TEST(x) \ 40 if (sqlite3_memdebug_vfs_oom_test && (!x || !sqlite3IsMemJournal(x))) { \ 41 void *pTstAlloc = sqlite3Malloc(10); \ 42 if (!pTstAlloc) return SQLITE_IOERR_NOMEM; \ 43 sqlite3_free(pTstAlloc); \ 44 } 45#else 46 #define DO_OS_MALLOC_TEST(x) 47#endif 48 49/* 50** The following routines are convenience wrappers around methods 51** of the sqlite3_file object. This is mostly just syntactic sugar. All 52** of this would be completely automatic if SQLite were coded using 53** C++ instead of plain old C. 54*/ 55int sqlite3OsClose(sqlite3_file *pId){ 56 int rc = SQLITE_OK; 57 if( pId->pMethods ){ 58 rc = pId->pMethods->xClose(pId); 59 pId->pMethods = 0; 60 } 61 return rc; 62} 63int sqlite3OsRead(sqlite3_file *id, void *pBuf, int amt, i64 offset){ 64 DO_OS_MALLOC_TEST(id); 65 return id->pMethods->xRead(id, pBuf, amt, offset); 66} 67int sqlite3OsWrite(sqlite3_file *id, const void *pBuf, int amt, i64 offset){ 68 DO_OS_MALLOC_TEST(id); 69 return id->pMethods->xWrite(id, pBuf, amt, offset); 70} 71int sqlite3OsTruncate(sqlite3_file *id, i64 size){ 72 return id->pMethods->xTruncate(id, size); 73} 74int sqlite3OsSync(sqlite3_file *id, int flags){ 75 DO_OS_MALLOC_TEST(id); 76 return id->pMethods->xSync(id, flags); 77} 78int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){ 79 DO_OS_MALLOC_TEST(id); 80 return id->pMethods->xFileSize(id, pSize); 81} 82int sqlite3OsLock(sqlite3_file *id, int lockType){ 83 DO_OS_MALLOC_TEST(id); 84 return id->pMethods->xLock(id, lockType); 85} 86int sqlite3OsUnlock(sqlite3_file *id, int lockType){ 87 return id->pMethods->xUnlock(id, lockType); 88} 89int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut){ 90 DO_OS_MALLOC_TEST(id); 91 return id->pMethods->xCheckReservedLock(id, pResOut); 92} 93int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){ 94 return id->pMethods->xFileControl(id, op, pArg); 95} 96int sqlite3OsSectorSize(sqlite3_file *id){ 97 int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize; 98 return (xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE); 99} 100int sqlite3OsDeviceCharacteristics(sqlite3_file *id){ 101 return id->pMethods->xDeviceCharacteristics(id); 102} 103int sqlite3OsShmLock(sqlite3_file *id, int offset, int n, int flags){ 104 return id->pMethods->xShmLock(id, offset, n, flags); 105} 106void sqlite3OsShmBarrier(sqlite3_file *id){ 107 id->pMethods->xShmBarrier(id); 108} 109int sqlite3OsShmUnmap(sqlite3_file *id, int deleteFlag){ 110 return id->pMethods->xShmUnmap(id, deleteFlag); 111} 112int sqlite3OsShmMap( 113 sqlite3_file *id, /* Database file handle */ 114 int iPage, 115 int pgsz, 116 int bExtend, /* True to extend file if necessary */ 117 void volatile **pp /* OUT: Pointer to mapping */ 118){ 119 return id->pMethods->xShmMap(id, iPage, pgsz, bExtend, pp); 120} 121 122/* 123** The next group of routines are convenience wrappers around the 124** VFS methods. 125*/ 126int sqlite3OsOpen( 127 sqlite3_vfs *pVfs, 128 const char *zPath, 129 sqlite3_file *pFile, 130 int flags, 131 int *pFlagsOut 132){ 133 int rc; 134 DO_OS_MALLOC_TEST(0); 135 /* 0x87f3f is a mask of SQLITE_OPEN_ flags that are valid to be passed 136 ** down into the VFS layer. Some SQLITE_OPEN_ flags (for example, 137 ** SQLITE_OPEN_FULLMUTEX or SQLITE_OPEN_SHAREDCACHE) are blocked before 138 ** reaching the VFS. */ 139 rc = pVfs->xOpen(pVfs, zPath, pFile, flags & 0x87f3f, pFlagsOut); 140 assert( rc==SQLITE_OK || pFile->pMethods==0 ); 141 return rc; 142} 143int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ 144 return pVfs->xDelete(pVfs, zPath, dirSync); 145} 146int sqlite3OsAccess( 147 sqlite3_vfs *pVfs, 148 const char *zPath, 149 int flags, 150 int *pResOut 151){ 152 DO_OS_MALLOC_TEST(0); 153 return pVfs->xAccess(pVfs, zPath, flags, pResOut); 154} 155int sqlite3OsFullPathname( 156 sqlite3_vfs *pVfs, 157 const char *zPath, 158 int nPathOut, 159 char *zPathOut 160){ 161 zPathOut[0] = 0; 162 return pVfs->xFullPathname(pVfs, zPath, nPathOut, zPathOut); 163} 164#ifndef SQLITE_OMIT_LOAD_EXTENSION 165void *sqlite3OsDlOpen(sqlite3_vfs *pVfs, const char *zPath){ 166 return pVfs->xDlOpen(pVfs, zPath); 167} 168void sqlite3OsDlError(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ 169 pVfs->xDlError(pVfs, nByte, zBufOut); 170} 171void (*sqlite3OsDlSym(sqlite3_vfs *pVfs, void *pHdle, const char *zSym))(void){ 172 return pVfs->xDlSym(pVfs, pHdle, zSym); 173} 174void sqlite3OsDlClose(sqlite3_vfs *pVfs, void *pHandle){ 175 pVfs->xDlClose(pVfs, pHandle); 176} 177#endif /* SQLITE_OMIT_LOAD_EXTENSION */ 178int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ 179 return pVfs->xRandomness(pVfs, nByte, zBufOut); 180} 181int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){ 182 return pVfs->xSleep(pVfs, nMicro); 183} 184int sqlite3OsCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){ 185 int rc; 186 /* IMPLEMENTATION-OF: R-49045-42493 SQLite will use the xCurrentTimeInt64() 187 ** method to get the current date and time if that method is available 188 ** (if iVersion is 2 or greater and the function pointer is not NULL) and 189 ** will fall back to xCurrentTime() if xCurrentTimeInt64() is 190 ** unavailable. 191 */ 192 if( pVfs->iVersion>=2 && pVfs->xCurrentTimeInt64 ){ 193 rc = pVfs->xCurrentTimeInt64(pVfs, pTimeOut); 194 }else{ 195 double r; 196 rc = pVfs->xCurrentTime(pVfs, &r); 197 *pTimeOut = (sqlite3_int64)(r*86400000.0); 198 } 199 return rc; 200} 201 202int sqlite3OsOpenMalloc( 203 sqlite3_vfs *pVfs, 204 const char *zFile, 205 sqlite3_file **ppFile, 206 int flags, 207 int *pOutFlags 208){ 209 int rc = SQLITE_NOMEM; 210 sqlite3_file *pFile; 211 pFile = (sqlite3_file *)sqlite3Malloc(pVfs->szOsFile); 212 if( pFile ){ 213 rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags); 214 if( rc!=SQLITE_OK ){ 215 sqlite3_free(pFile); 216 }else{ 217 *ppFile = pFile; 218 } 219 } 220 return rc; 221} 222int sqlite3OsCloseFree(sqlite3_file *pFile){ 223 int rc = SQLITE_OK; 224 assert( pFile ); 225 rc = sqlite3OsClose(pFile); 226 sqlite3_free(pFile); 227 return rc; 228} 229 230/* 231** This function is a wrapper around the OS specific implementation of 232** sqlite3_os_init(). The purpose of the wrapper is to provide the 233** ability to simulate a malloc failure, so that the handling of an 234** error in sqlite3_os_init() by the upper layers can be tested. 235*/ 236int sqlite3OsInit(void){ 237 void *p = sqlite3_malloc(10); 238 if( p==0 ) return SQLITE_NOMEM; 239 sqlite3_free(p); 240 return sqlite3_os_init(); 241} 242 243/* 244** The list of all registered VFS implementations. 245*/ 246static sqlite3_vfs * SQLITE_WSD vfsList = 0; 247#define vfsList GLOBAL(sqlite3_vfs *, vfsList) 248 249/* 250** Locate a VFS by name. If no name is given, simply return the 251** first VFS on the list. 252*/ 253sqlite3_vfs *sqlite3_vfs_find(const char *zVfs){ 254 sqlite3_vfs *pVfs = 0; 255#if SQLITE_THREADSAFE 256 sqlite3_mutex *mutex; 257#endif 258#ifndef SQLITE_OMIT_AUTOINIT 259 int rc = sqlite3_initialize(); 260 if( rc ) return 0; 261#endif 262#if SQLITE_THREADSAFE 263 mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); 264#endif 265 sqlite3_mutex_enter(mutex); 266 for(pVfs = vfsList; pVfs; pVfs=pVfs->pNext){ 267 if( zVfs==0 ) break; 268 if( strcmp(zVfs, pVfs->zName)==0 ) break; 269 } 270 sqlite3_mutex_leave(mutex); 271 return pVfs; 272} 273 274/* 275** Unlink a VFS from the linked list 276*/ 277static void vfsUnlink(sqlite3_vfs *pVfs){ 278 assert( sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)) ); 279 if( pVfs==0 ){ 280 /* No-op */ 281 }else if( vfsList==pVfs ){ 282 vfsList = pVfs->pNext; 283 }else if( vfsList ){ 284 sqlite3_vfs *p = vfsList; 285 while( p->pNext && p->pNext!=pVfs ){ 286 p = p->pNext; 287 } 288 if( p->pNext==pVfs ){ 289 p->pNext = pVfs->pNext; 290 } 291 } 292} 293 294/* 295** Register a VFS with the system. It is harmless to register the same 296** VFS multiple times. The new VFS becomes the default if makeDflt is 297** true. 298*/ 299int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){ 300 sqlite3_mutex *mutex = 0; 301#ifndef SQLITE_OMIT_AUTOINIT 302 int rc = sqlite3_initialize(); 303 if( rc ) return rc; 304#endif 305 mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); 306 sqlite3_mutex_enter(mutex); 307 vfsUnlink(pVfs); 308 if( makeDflt || vfsList==0 ){ 309 pVfs->pNext = vfsList; 310 vfsList = pVfs; 311 }else{ 312 pVfs->pNext = vfsList->pNext; 313 vfsList->pNext = pVfs; 314 } 315 assert(vfsList); 316 sqlite3_mutex_leave(mutex); 317 return SQLITE_OK; 318} 319 320/* 321** Unregister a VFS so that it is no longer accessible. 322*/ 323int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){ 324#if SQLITE_THREADSAFE 325 sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); 326#endif 327 sqlite3_mutex_enter(mutex); 328 vfsUnlink(pVfs); 329 sqlite3_mutex_leave(mutex); 330 return SQLITE_OK; 331} 332