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 #ifdef SQLITE_TEST 38 #define DO_OS_MALLOC_TEST if (1) { \ 39 void *pTstAlloc = sqlite3_malloc(10); \ 40 if (!pTstAlloc) return SQLITE_IOERR_NOMEM; \ 41 sqlite3_free(pTstAlloc); \ 42 } 43 #else 44 #define DO_OS_MALLOC_TEST 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; 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; 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; 74 return id->pMethods->xSync(id, flags); 75 } 76 int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){ 77 return id->pMethods->xFileSize(id, pSize); 78 } 79 int sqlite3OsLock(sqlite3_file *id, int lockType){ 80 DO_OS_MALLOC_TEST; 81 return id->pMethods->xLock(id, lockType); 82 } 83 int sqlite3OsUnlock(sqlite3_file *id, int lockType){ 84 return id->pMethods->xUnlock(id, lockType); 85 } 86 int sqlite3OsCheckReservedLock(sqlite3_file *id){ 87 return id->pMethods->xCheckReservedLock(id); 88 } 89 int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){ 90 return id->pMethods->xFileControl(id,op,pArg); 91 } 92 93 #ifdef SQLITE_TEST 94 /* The following two variables are used to override the values returned 95 ** by the xSectorSize() and xDeviceCharacteristics() vfs methods for 96 ** testing purposes. They are usually set by a test command implemented 97 ** in test6.c. 98 */ 99 int sqlite3_test_sector_size = 0; 100 int sqlite3_test_device_characteristics = 0; 101 int sqlite3OsDeviceCharacteristics(sqlite3_file *id){ 102 int dc = id->pMethods->xDeviceCharacteristics(id); 103 return dc | sqlite3_test_device_characteristics; 104 } 105 int sqlite3OsSectorSize(sqlite3_file *id){ 106 if( sqlite3_test_sector_size==0 ){ 107 int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize; 108 return (xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE); 109 } 110 return sqlite3_test_sector_size; 111 } 112 #else 113 int sqlite3OsSectorSize(sqlite3_file *id){ 114 int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize; 115 return (xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE); 116 } 117 int sqlite3OsDeviceCharacteristics(sqlite3_file *id){ 118 return id->pMethods->xDeviceCharacteristics(id); 119 } 120 #endif 121 122 /* 123 ** The next group of routines are convenience wrappers around the 124 ** VFS methods. 125 */ 126 int sqlite3OsOpen( 127 sqlite3_vfs *pVfs, 128 const char *zPath, 129 sqlite3_file *pFile, 130 int flags, 131 int *pFlagsOut 132 ){ 133 DO_OS_MALLOC_TEST; 134 return pVfs->xOpen(pVfs, zPath, pFile, flags, pFlagsOut); 135 } 136 int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ 137 return pVfs->xDelete(pVfs, zPath, dirSync); 138 } 139 int sqlite3OsAccess(sqlite3_vfs *pVfs, const char *zPath, int flags){ 140 return pVfs->xAccess(pVfs, zPath, flags); 141 } 142 int sqlite3OsGetTempname(sqlite3_vfs *pVfs, int nBufOut, char *zBufOut){ 143 return pVfs->xGetTempname(pVfs, nBufOut, zBufOut); 144 } 145 int sqlite3OsFullPathname( 146 sqlite3_vfs *pVfs, 147 const char *zPath, 148 int nPathOut, 149 char *zPathOut 150 ){ 151 return pVfs->xFullPathname(pVfs, zPath, nPathOut, zPathOut); 152 } 153 void *sqlite3OsDlOpen(sqlite3_vfs *pVfs, const char *zPath){ 154 return pVfs->xDlOpen(pVfs, zPath); 155 } 156 void sqlite3OsDlError(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ 157 pVfs->xDlError(pVfs, nByte, zBufOut); 158 } 159 void *sqlite3OsDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){ 160 return pVfs->xDlSym(pVfs, pHandle, zSymbol); 161 } 162 void sqlite3OsDlClose(sqlite3_vfs *pVfs, void *pHandle){ 163 pVfs->xDlClose(pVfs, pHandle); 164 } 165 int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ 166 return pVfs->xRandomness(pVfs, nByte, zBufOut); 167 } 168 int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){ 169 return pVfs->xSleep(pVfs, nMicro); 170 } 171 int sqlite3OsCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){ 172 return pVfs->xCurrentTime(pVfs, pTimeOut); 173 } 174 175 int sqlite3OsOpenMalloc( 176 sqlite3_vfs *pVfs, 177 const char *zFile, 178 sqlite3_file **ppFile, 179 int flags, 180 int *pOutFlags 181 ){ 182 int rc = SQLITE_NOMEM; 183 sqlite3_file *pFile; 184 pFile = (sqlite3_file *)sqlite3_malloc(pVfs->szOsFile); 185 if( pFile ){ 186 rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags); 187 if( rc!=SQLITE_OK ){ 188 sqlite3_free(pFile); 189 }else{ 190 *ppFile = pFile; 191 } 192 } 193 return rc; 194 } 195 int sqlite3OsCloseFree(sqlite3_file *pFile){ 196 int rc = SQLITE_OK; 197 if( pFile ){ 198 rc = sqlite3OsClose(pFile); 199 sqlite3_free(pFile); 200 } 201 return rc; 202 } 203 204 /* 205 ** The list of all registered VFS implementations. This list is 206 ** initialized to the single VFS returned by sqlite3OsDefaultVfs() 207 ** upon the first call to sqlite3_vfs_find(). 208 */ 209 static sqlite3_vfs *vfsList = 0; 210 211 /* 212 ** Locate a VFS by name. If no name is given, simply return the 213 ** first VFS on the list. 214 */ 215 sqlite3_vfs *sqlite3_vfs_find(const char *zVfs){ 216 sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER); 217 sqlite3_vfs *pVfs = 0; 218 static int isInit = 0; 219 sqlite3_mutex_enter(mutex); 220 if( !isInit ){ 221 vfsList = sqlite3OsDefaultVfs(); 222 isInit = 1; 223 } 224 for(pVfs = vfsList; pVfs; pVfs=pVfs->pNext){ 225 if( zVfs==0 ) break; 226 if( strcmp(zVfs, pVfs->zName)==0 ) break; 227 } 228 sqlite3_mutex_leave(mutex); 229 return pVfs; 230 } 231 232 /* 233 ** Unlink a VFS from the linked list 234 */ 235 static void vfsUnlink(sqlite3_vfs *pVfs){ 236 assert( sqlite3_mutex_held(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)) ); 237 if( pVfs==0 ){ 238 /* No-op */ 239 }else if( vfsList==pVfs ){ 240 vfsList = pVfs->pNext; 241 }else if( vfsList ){ 242 sqlite3_vfs *p = vfsList; 243 while( p->pNext && p->pNext!=pVfs ){ 244 p = p->pNext; 245 } 246 if( p->pNext==pVfs ){ 247 p->pNext = pVfs->pNext; 248 } 249 } 250 } 251 252 /* 253 ** Register a VFS with the system. It is harmless to register the same 254 ** VFS multiple times. The new VFS becomes the default if makeDflt is 255 ** true. 256 */ 257 int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){ 258 sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER); 259 sqlite3_vfs_find(0); /* Make sure we are initialized */ 260 sqlite3_mutex_enter(mutex); 261 vfsUnlink(pVfs); 262 if( makeDflt || vfsList==0 ){ 263 pVfs->pNext = vfsList; 264 vfsList = pVfs; 265 }else{ 266 pVfs->pNext = vfsList->pNext; 267 vfsList->pNext = pVfs; 268 } 269 assert(vfsList); 270 sqlite3_mutex_leave(mutex); 271 return SQLITE_OK; 272 } 273 274 /* 275 ** Unregister a VFS so that it is no longer accessible. 276 */ 277 int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){ 278 sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER); 279 sqlite3_mutex_enter(mutex); 280 vfsUnlink(pVfs); 281 sqlite3_mutex_leave(mutex); 282 return SQLITE_OK; 283 } 284