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