1 /* 2 ** 2008 Jan 22 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 code that modified the OS layer in order to simulate 14 ** different device types (by overriding the return values of the 15 ** xDeviceCharacteristics() and xSectorSize() methods). 16 */ 17 #if SQLITE_TEST /* This file is used for testing only */ 18 19 #include "sqlite3.h" 20 #include "sqliteInt.h" 21 22 /* 23 ** Maximum pathname length supported by the devsym backend. 24 */ 25 #define DEVSYM_MAX_PATHNAME 512 26 27 /* 28 ** Name used to identify this VFS. 29 */ 30 #define DEVSYM_VFS_NAME "devsym" 31 32 typedef struct devsym_file devsym_file; 33 struct devsym_file { 34 sqlite3_file base; 35 sqlite3_file *pReal; 36 }; 37 38 /* 39 ** Method declarations for devsym_file. 40 */ 41 static int devsymClose(sqlite3_file*); 42 static int devsymRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); 43 static int devsymWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst); 44 static int devsymTruncate(sqlite3_file*, sqlite3_int64 size); 45 static int devsymSync(sqlite3_file*, int flags); 46 static int devsymFileSize(sqlite3_file*, sqlite3_int64 *pSize); 47 static int devsymLock(sqlite3_file*, int); 48 static int devsymUnlock(sqlite3_file*, int); 49 static int devsymCheckReservedLock(sqlite3_file*, int *); 50 static int devsymFileControl(sqlite3_file*, int op, void *pArg); 51 static int devsymSectorSize(sqlite3_file*); 52 static int devsymDeviceCharacteristics(sqlite3_file*); 53 static int devsymShmOpen(sqlite3_file*); 54 static int devsymShmLock(sqlite3_file*,int,int,int); 55 static int devsymShmMap(sqlite3_file*,int,int,int, void volatile **); 56 static void devsymShmBarrier(sqlite3_file*); 57 static int devsymShmClose(sqlite3_file*,int); 58 59 /* 60 ** Method declarations for devsym_vfs. 61 */ 62 static int devsymOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *); 63 static int devsymDelete(sqlite3_vfs*, const char *zName, int syncDir); 64 static int devsymAccess(sqlite3_vfs*, const char *zName, int flags, int *); 65 static int devsymFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut); 66 #ifndef SQLITE_OMIT_LOAD_EXTENSION 67 static void *devsymDlOpen(sqlite3_vfs*, const char *zFilename); 68 static void devsymDlError(sqlite3_vfs*, int nByte, char *zErrMsg); 69 static void (*devsymDlSym(sqlite3_vfs*,void*, const char *zSymbol))(void); 70 static void devsymDlClose(sqlite3_vfs*, void*); 71 #endif /* SQLITE_OMIT_LOAD_EXTENSION */ 72 static int devsymRandomness(sqlite3_vfs*, int nByte, char *zOut); 73 static int devsymSleep(sqlite3_vfs*, int microseconds); 74 static int devsymCurrentTime(sqlite3_vfs*, double*); 75 76 static sqlite3_vfs devsym_vfs = { 77 2, /* iVersion */ 78 sizeof(devsym_file), /* szOsFile */ 79 DEVSYM_MAX_PATHNAME, /* mxPathname */ 80 0, /* pNext */ 81 DEVSYM_VFS_NAME, /* zName */ 82 0, /* pAppData */ 83 devsymOpen, /* xOpen */ 84 devsymDelete, /* xDelete */ 85 devsymAccess, /* xAccess */ 86 devsymFullPathname, /* xFullPathname */ 87 #ifndef SQLITE_OMIT_LOAD_EXTENSION 88 devsymDlOpen, /* xDlOpen */ 89 devsymDlError, /* xDlError */ 90 devsymDlSym, /* xDlSym */ 91 devsymDlClose, /* xDlClose */ 92 #else 93 0, /* xDlOpen */ 94 0, /* xDlError */ 95 0, /* xDlSym */ 96 0, /* xDlClose */ 97 #endif /* SQLITE_OMIT_LOAD_EXTENSION */ 98 devsymRandomness, /* xRandomness */ 99 devsymSleep, /* xSleep */ 100 devsymCurrentTime, /* xCurrentTime */ 101 0, /* xGetLastError */ 102 0 /* xCurrentTimeInt64 */ 103 }; 104 105 static sqlite3_io_methods devsym_io_methods = { 106 2, /* iVersion */ 107 devsymClose, /* xClose */ 108 devsymRead, /* xRead */ 109 devsymWrite, /* xWrite */ 110 devsymTruncate, /* xTruncate */ 111 devsymSync, /* xSync */ 112 devsymFileSize, /* xFileSize */ 113 devsymLock, /* xLock */ 114 devsymUnlock, /* xUnlock */ 115 devsymCheckReservedLock, /* xCheckReservedLock */ 116 devsymFileControl, /* xFileControl */ 117 devsymSectorSize, /* xSectorSize */ 118 devsymDeviceCharacteristics, /* xDeviceCharacteristics */ 119 devsymShmOpen, /* xShmOpen */ 120 devsymShmLock, /* xShmLock */ 121 devsymShmMap, /* xShmMap */ 122 devsymShmBarrier, /* xShmBarrier */ 123 devsymShmClose /* xShmClose */ 124 }; 125 126 struct DevsymGlobal { 127 sqlite3_vfs *pVfs; 128 int iDeviceChar; 129 int iSectorSize; 130 }; 131 struct DevsymGlobal g = {0, 0, 512}; 132 133 /* 134 ** Close an devsym-file. 135 */ 136 static int devsymClose(sqlite3_file *pFile){ 137 devsym_file *p = (devsym_file *)pFile; 138 return sqlite3OsClose(p->pReal); 139 } 140 141 /* 142 ** Read data from an devsym-file. 143 */ 144 static int devsymRead( 145 sqlite3_file *pFile, 146 void *zBuf, 147 int iAmt, 148 sqlite_int64 iOfst 149 ){ 150 devsym_file *p = (devsym_file *)pFile; 151 return sqlite3OsRead(p->pReal, zBuf, iAmt, iOfst); 152 } 153 154 /* 155 ** Write data to an devsym-file. 156 */ 157 static int devsymWrite( 158 sqlite3_file *pFile, 159 const void *zBuf, 160 int iAmt, 161 sqlite_int64 iOfst 162 ){ 163 devsym_file *p = (devsym_file *)pFile; 164 return sqlite3OsWrite(p->pReal, zBuf, iAmt, iOfst); 165 } 166 167 /* 168 ** Truncate an devsym-file. 169 */ 170 static int devsymTruncate(sqlite3_file *pFile, sqlite_int64 size){ 171 devsym_file *p = (devsym_file *)pFile; 172 return sqlite3OsTruncate(p->pReal, size); 173 } 174 175 /* 176 ** Sync an devsym-file. 177 */ 178 static int devsymSync(sqlite3_file *pFile, int flags){ 179 devsym_file *p = (devsym_file *)pFile; 180 return sqlite3OsSync(p->pReal, flags); 181 } 182 183 /* 184 ** Return the current file-size of an devsym-file. 185 */ 186 static int devsymFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ 187 devsym_file *p = (devsym_file *)pFile; 188 return sqlite3OsFileSize(p->pReal, pSize); 189 } 190 191 /* 192 ** Lock an devsym-file. 193 */ 194 static int devsymLock(sqlite3_file *pFile, int eLock){ 195 devsym_file *p = (devsym_file *)pFile; 196 return sqlite3OsLock(p->pReal, eLock); 197 } 198 199 /* 200 ** Unlock an devsym-file. 201 */ 202 static int devsymUnlock(sqlite3_file *pFile, int eLock){ 203 devsym_file *p = (devsym_file *)pFile; 204 return sqlite3OsUnlock(p->pReal, eLock); 205 } 206 207 /* 208 ** Check if another file-handle holds a RESERVED lock on an devsym-file. 209 */ 210 static int devsymCheckReservedLock(sqlite3_file *pFile, int *pResOut){ 211 devsym_file *p = (devsym_file *)pFile; 212 return sqlite3OsCheckReservedLock(p->pReal, pResOut); 213 } 214 215 /* 216 ** File control method. For custom operations on an devsym-file. 217 */ 218 static int devsymFileControl(sqlite3_file *pFile, int op, void *pArg){ 219 devsym_file *p = (devsym_file *)pFile; 220 return sqlite3OsFileControl(p->pReal, op, pArg); 221 } 222 223 /* 224 ** Return the sector-size in bytes for an devsym-file. 225 */ 226 static int devsymSectorSize(sqlite3_file *pFile){ 227 return g.iSectorSize; 228 } 229 230 /* 231 ** Return the device characteristic flags supported by an devsym-file. 232 */ 233 static int devsymDeviceCharacteristics(sqlite3_file *pFile){ 234 return g.iDeviceChar; 235 } 236 237 /* 238 ** Shared-memory methods are all pass-thrus. 239 */ 240 static int devsymShmOpen(sqlite3_file *pFile){ 241 devsym_file *p = (devsym_file *)pFile; 242 return sqlite3OsShmOpen(p->pReal); 243 } 244 static int devsymShmLock(sqlite3_file *pFile, int ofst, int n, int flags){ 245 devsym_file *p = (devsym_file *)pFile; 246 return sqlite3OsShmLock(p->pReal, ofst, n, flags); 247 } 248 static int devsymShmMap( 249 sqlite3_file *pFile, 250 int iRegion, 251 int szRegion, 252 int isWrite, 253 void volatile **pp 254 ){ 255 devsym_file *p = (devsym_file *)pFile; 256 return sqlite3OsShmMap(p->pReal, iRegion, szRegion, isWrite, pp); 257 } 258 static void devsymShmBarrier(sqlite3_file *pFile){ 259 devsym_file *p = (devsym_file *)pFile; 260 sqlite3OsShmBarrier(p->pReal); 261 } 262 static int devsymShmClose(sqlite3_file *pFile, int delFlag){ 263 devsym_file *p = (devsym_file *)pFile; 264 return sqlite3OsShmClose(p->pReal, delFlag); 265 } 266 267 268 269 /* 270 ** Open an devsym file handle. 271 */ 272 static int devsymOpen( 273 sqlite3_vfs *pVfs, 274 const char *zName, 275 sqlite3_file *pFile, 276 int flags, 277 int *pOutFlags 278 ){ 279 int rc; 280 devsym_file *p = (devsym_file *)pFile; 281 p->pReal = (sqlite3_file *)&p[1]; 282 rc = sqlite3OsOpen(g.pVfs, zName, p->pReal, flags, pOutFlags); 283 if( p->pReal->pMethods ){ 284 pFile->pMethods = &devsym_io_methods; 285 } 286 return rc; 287 } 288 289 /* 290 ** Delete the file located at zPath. If the dirSync argument is true, 291 ** ensure the file-system modifications are synced to disk before 292 ** returning. 293 */ 294 static int devsymDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ 295 return sqlite3OsDelete(g.pVfs, zPath, dirSync); 296 } 297 298 /* 299 ** Test for access permissions. Return true if the requested permission 300 ** is available, or false otherwise. 301 */ 302 static int devsymAccess( 303 sqlite3_vfs *pVfs, 304 const char *zPath, 305 int flags, 306 int *pResOut 307 ){ 308 return sqlite3OsAccess(g.pVfs, zPath, flags, pResOut); 309 } 310 311 /* 312 ** Populate buffer zOut with the full canonical pathname corresponding 313 ** to the pathname in zPath. zOut is guaranteed to point to a buffer 314 ** of at least (DEVSYM_MAX_PATHNAME+1) bytes. 315 */ 316 static int devsymFullPathname( 317 sqlite3_vfs *pVfs, 318 const char *zPath, 319 int nOut, 320 char *zOut 321 ){ 322 return sqlite3OsFullPathname(g.pVfs, zPath, nOut, zOut); 323 } 324 325 #ifndef SQLITE_OMIT_LOAD_EXTENSION 326 /* 327 ** Open the dynamic library located at zPath and return a handle. 328 */ 329 static void *devsymDlOpen(sqlite3_vfs *pVfs, const char *zPath){ 330 return sqlite3OsDlOpen(g.pVfs, zPath); 331 } 332 333 /* 334 ** Populate the buffer zErrMsg (size nByte bytes) with a human readable 335 ** utf-8 string describing the most recent error encountered associated 336 ** with dynamic libraries. 337 */ 338 static void devsymDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){ 339 sqlite3OsDlError(g.pVfs, nByte, zErrMsg); 340 } 341 342 /* 343 ** Return a pointer to the symbol zSymbol in the dynamic library pHandle. 344 */ 345 static void (*devsymDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){ 346 return sqlite3OsDlSym(g.pVfs, p, zSym); 347 } 348 349 /* 350 ** Close the dynamic library handle pHandle. 351 */ 352 static void devsymDlClose(sqlite3_vfs *pVfs, void *pHandle){ 353 sqlite3OsDlClose(g.pVfs, pHandle); 354 } 355 #endif /* SQLITE_OMIT_LOAD_EXTENSION */ 356 357 /* 358 ** Populate the buffer pointed to by zBufOut with nByte bytes of 359 ** random data. 360 */ 361 static int devsymRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ 362 return sqlite3OsRandomness(g.pVfs, nByte, zBufOut); 363 } 364 365 /* 366 ** Sleep for nMicro microseconds. Return the number of microseconds 367 ** actually slept. 368 */ 369 static int devsymSleep(sqlite3_vfs *pVfs, int nMicro){ 370 return sqlite3OsSleep(g.pVfs, nMicro); 371 } 372 373 /* 374 ** Return the current time as a Julian Day number in *pTimeOut. 375 */ 376 static int devsymCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){ 377 return g.pVfs->xCurrentTime(g.pVfs, pTimeOut); 378 } 379 380 381 /* 382 ** This procedure registers the devsym vfs with SQLite. If the argument is 383 ** true, the devsym vfs becomes the new default vfs. It is the only publicly 384 ** available function in this file. 385 */ 386 void devsym_register(int iDeviceChar, int iSectorSize){ 387 if( g.pVfs==0 ){ 388 g.pVfs = sqlite3_vfs_find(0); 389 devsym_vfs.szOsFile += g.pVfs->szOsFile; 390 sqlite3_vfs_register(&devsym_vfs, 0); 391 } 392 if( iDeviceChar>=0 ){ 393 g.iDeviceChar = iDeviceChar; 394 }else{ 395 g.iDeviceChar = 0; 396 } 397 if( iSectorSize>=0 ){ 398 g.iSectorSize = iSectorSize; 399 }else{ 400 g.iSectorSize = 512; 401 } 402 } 403 404 #endif 405