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