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