modernc.org/cc@v1.0.1/v2/testdata/_sqlite/src/test_devsym.c (about)

     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  #define WRITECRASH_NAME "writecrash"
    32  
    33  typedef struct devsym_file devsym_file;
    34  struct devsym_file {
    35    sqlite3_file base;
    36    sqlite3_file *pReal;
    37  };
    38  
    39  /*
    40  ** Method declarations for devsym_file.
    41  */
    42  static int devsymClose(sqlite3_file*);
    43  static int devsymRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
    44  static int devsymWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst);
    45  static int devsymTruncate(sqlite3_file*, sqlite3_int64 size);
    46  static int devsymSync(sqlite3_file*, int flags);
    47  static int devsymFileSize(sqlite3_file*, sqlite3_int64 *pSize);
    48  static int devsymLock(sqlite3_file*, int);
    49  static int devsymUnlock(sqlite3_file*, int);
    50  static int devsymCheckReservedLock(sqlite3_file*, int *);
    51  static int devsymFileControl(sqlite3_file*, int op, void *pArg);
    52  static int devsymSectorSize(sqlite3_file*);
    53  static int devsymDeviceCharacteristics(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 devsymShmUnmap(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  struct DevsymGlobal {
    77    sqlite3_vfs *pVfs;
    78    int iDeviceChar;
    79    int iSectorSize;
    80    int nWriteCrash;
    81  };
    82  struct DevsymGlobal g = {0, 0, 512, 0};
    83  
    84  /*
    85  ** Close an devsym-file.
    86  */
    87  static int devsymClose(sqlite3_file *pFile){
    88    devsym_file *p = (devsym_file *)pFile;
    89    sqlite3OsClose(p->pReal);
    90    return SQLITE_OK;
    91  }
    92  
    93  /*
    94  ** Read data from an devsym-file.
    95  */
    96  static int devsymRead(
    97    sqlite3_file *pFile, 
    98    void *zBuf, 
    99    int iAmt, 
   100    sqlite_int64 iOfst
   101  ){
   102    devsym_file *p = (devsym_file *)pFile;
   103    return sqlite3OsRead(p->pReal, zBuf, iAmt, iOfst);
   104  }
   105  
   106  /*
   107  ** Write data to an devsym-file.
   108  */
   109  static int devsymWrite(
   110    sqlite3_file *pFile, 
   111    const void *zBuf, 
   112    int iAmt, 
   113    sqlite_int64 iOfst
   114  ){
   115    devsym_file *p = (devsym_file *)pFile;
   116    return sqlite3OsWrite(p->pReal, zBuf, iAmt, iOfst);
   117  }
   118  
   119  /*
   120  ** Truncate an devsym-file.
   121  */
   122  static int devsymTruncate(sqlite3_file *pFile, sqlite_int64 size){
   123    devsym_file *p = (devsym_file *)pFile;
   124    return sqlite3OsTruncate(p->pReal, size);
   125  }
   126  
   127  /*
   128  ** Sync an devsym-file.
   129  */
   130  static int devsymSync(sqlite3_file *pFile, int flags){
   131    devsym_file *p = (devsym_file *)pFile;
   132    return sqlite3OsSync(p->pReal, flags);
   133  }
   134  
   135  /*
   136  ** Return the current file-size of an devsym-file.
   137  */
   138  static int devsymFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
   139    devsym_file *p = (devsym_file *)pFile;
   140    return sqlite3OsFileSize(p->pReal, pSize);
   141  }
   142  
   143  /*
   144  ** Lock an devsym-file.
   145  */
   146  static int devsymLock(sqlite3_file *pFile, int eLock){
   147    devsym_file *p = (devsym_file *)pFile;
   148    return sqlite3OsLock(p->pReal, eLock);
   149  }
   150  
   151  /*
   152  ** Unlock an devsym-file.
   153  */
   154  static int devsymUnlock(sqlite3_file *pFile, int eLock){
   155    devsym_file *p = (devsym_file *)pFile;
   156    return sqlite3OsUnlock(p->pReal, eLock);
   157  }
   158  
   159  /*
   160  ** Check if another file-handle holds a RESERVED lock on an devsym-file.
   161  */
   162  static int devsymCheckReservedLock(sqlite3_file *pFile, int *pResOut){
   163    devsym_file *p = (devsym_file *)pFile;
   164    return sqlite3OsCheckReservedLock(p->pReal, pResOut);
   165  }
   166  
   167  /*
   168  ** File control method. For custom operations on an devsym-file.
   169  */
   170  static int devsymFileControl(sqlite3_file *pFile, int op, void *pArg){
   171    devsym_file *p = (devsym_file *)pFile;
   172    return sqlite3OsFileControl(p->pReal, op, pArg);
   173  }
   174  
   175  /*
   176  ** Return the sector-size in bytes for an devsym-file.
   177  */
   178  static int devsymSectorSize(sqlite3_file *pFile){
   179    return g.iSectorSize;
   180  }
   181  
   182  /*
   183  ** Return the device characteristic flags supported by an devsym-file.
   184  */
   185  static int devsymDeviceCharacteristics(sqlite3_file *pFile){
   186    return g.iDeviceChar;
   187  }
   188  
   189  /*
   190  ** Shared-memory methods are all pass-thrus.
   191  */
   192  static int devsymShmLock(sqlite3_file *pFile, int ofst, int n, int flags){
   193    devsym_file *p = (devsym_file *)pFile;
   194    return sqlite3OsShmLock(p->pReal, ofst, n, flags);
   195  }
   196  static int devsymShmMap(
   197    sqlite3_file *pFile, 
   198    int iRegion, 
   199    int szRegion, 
   200    int isWrite, 
   201    void volatile **pp
   202  ){
   203    devsym_file *p = (devsym_file *)pFile;
   204    return sqlite3OsShmMap(p->pReal, iRegion, szRegion, isWrite, pp);
   205  }
   206  static void devsymShmBarrier(sqlite3_file *pFile){
   207    devsym_file *p = (devsym_file *)pFile;
   208    sqlite3OsShmBarrier(p->pReal);
   209  }
   210  static int devsymShmUnmap(sqlite3_file *pFile, int delFlag){
   211    devsym_file *p = (devsym_file *)pFile;
   212    return sqlite3OsShmUnmap(p->pReal, delFlag);
   213  }
   214  
   215  
   216  
   217  /*
   218  ** Open an devsym file handle.
   219  */
   220  static int devsymOpen(
   221    sqlite3_vfs *pVfs,
   222    const char *zName,
   223    sqlite3_file *pFile,
   224    int flags,
   225    int *pOutFlags
   226  ){
   227  static sqlite3_io_methods devsym_io_methods = {
   228    2,                                /* iVersion */
   229    devsymClose,                      /* xClose */
   230    devsymRead,                       /* xRead */
   231    devsymWrite,                      /* xWrite */
   232    devsymTruncate,                   /* xTruncate */
   233    devsymSync,                       /* xSync */
   234    devsymFileSize,                   /* xFileSize */
   235    devsymLock,                       /* xLock */
   236    devsymUnlock,                     /* xUnlock */
   237    devsymCheckReservedLock,          /* xCheckReservedLock */
   238    devsymFileControl,                /* xFileControl */
   239    devsymSectorSize,                 /* xSectorSize */
   240    devsymDeviceCharacteristics,      /* xDeviceCharacteristics */
   241    devsymShmMap,                     /* xShmMap */
   242    devsymShmLock,                    /* xShmLock */
   243    devsymShmBarrier,                 /* xShmBarrier */
   244    devsymShmUnmap                    /* xShmUnmap */
   245  };
   246  
   247    int rc;
   248    devsym_file *p = (devsym_file *)pFile;
   249    p->pReal = (sqlite3_file *)&p[1];
   250    rc = sqlite3OsOpen(g.pVfs, zName, p->pReal, flags, pOutFlags);
   251    if( p->pReal->pMethods ){
   252      pFile->pMethods = &devsym_io_methods;
   253    }
   254    return rc;
   255  }
   256  
   257  /*
   258  ** Delete the file located at zPath. If the dirSync argument is true,
   259  ** ensure the file-system modifications are synced to disk before
   260  ** returning.
   261  */
   262  static int devsymDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
   263    return sqlite3OsDelete(g.pVfs, zPath, dirSync);
   264  }
   265  
   266  /*
   267  ** Test for access permissions. Return true if the requested permission
   268  ** is available, or false otherwise.
   269  */
   270  static int devsymAccess(
   271    sqlite3_vfs *pVfs, 
   272    const char *zPath, 
   273    int flags, 
   274    int *pResOut
   275  ){
   276    return sqlite3OsAccess(g.pVfs, zPath, flags, pResOut);
   277  }
   278  
   279  /*
   280  ** Populate buffer zOut with the full canonical pathname corresponding
   281  ** to the pathname in zPath. zOut is guaranteed to point to a buffer
   282  ** of at least (DEVSYM_MAX_PATHNAME+1) bytes.
   283  */
   284  static int devsymFullPathname(
   285    sqlite3_vfs *pVfs, 
   286    const char *zPath, 
   287    int nOut, 
   288    char *zOut
   289  ){
   290    return sqlite3OsFullPathname(g.pVfs, zPath, nOut, zOut);
   291  }
   292  
   293  #ifndef SQLITE_OMIT_LOAD_EXTENSION
   294  /*
   295  ** Open the dynamic library located at zPath and return a handle.
   296  */
   297  static void *devsymDlOpen(sqlite3_vfs *pVfs, const char *zPath){
   298    return sqlite3OsDlOpen(g.pVfs, zPath);
   299  }
   300  
   301  /*
   302  ** Populate the buffer zErrMsg (size nByte bytes) with a human readable
   303  ** utf-8 string describing the most recent error encountered associated 
   304  ** with dynamic libraries.
   305  */
   306  static void devsymDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
   307    sqlite3OsDlError(g.pVfs, nByte, zErrMsg);
   308  }
   309  
   310  /*
   311  ** Return a pointer to the symbol zSymbol in the dynamic library pHandle.
   312  */
   313  static void (*devsymDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){
   314    return sqlite3OsDlSym(g.pVfs, p, zSym);
   315  }
   316  
   317  /*
   318  ** Close the dynamic library handle pHandle.
   319  */
   320  static void devsymDlClose(sqlite3_vfs *pVfs, void *pHandle){
   321    sqlite3OsDlClose(g.pVfs, pHandle);
   322  }
   323  #endif /* SQLITE_OMIT_LOAD_EXTENSION */
   324  
   325  /*
   326  ** Populate the buffer pointed to by zBufOut with nByte bytes of 
   327  ** random data.
   328  */
   329  static int devsymRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
   330    return sqlite3OsRandomness(g.pVfs, nByte, zBufOut);
   331  }
   332  
   333  /*
   334  ** Sleep for nMicro microseconds. Return the number of microseconds 
   335  ** actually slept.
   336  */
   337  static int devsymSleep(sqlite3_vfs *pVfs, int nMicro){
   338    return sqlite3OsSleep(g.pVfs, nMicro);
   339  }
   340  
   341  /*
   342  ** Return the current time as a Julian Day number in *pTimeOut.
   343  */
   344  static int devsymCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
   345    return g.pVfs->xCurrentTime(g.pVfs, pTimeOut);
   346  }
   347  
   348  /*
   349  ** Return the sector-size in bytes for an writecrash-file.
   350  */
   351  static int writecrashSectorSize(sqlite3_file *pFile){
   352    devsym_file *p = (devsym_file *)pFile;
   353    return sqlite3OsSectorSize(p->pReal);
   354  }
   355  
   356  /*
   357  ** Return the device characteristic flags supported by an writecrash-file.
   358  */
   359  static int writecrashDeviceCharacteristics(sqlite3_file *pFile){
   360    devsym_file *p = (devsym_file *)pFile;
   361    return sqlite3OsDeviceCharacteristics(p->pReal);
   362  }
   363  
   364  /*
   365  ** Write data to an writecrash-file.
   366  */
   367  static int writecrashWrite(
   368    sqlite3_file *pFile, 
   369    const void *zBuf, 
   370    int iAmt, 
   371    sqlite_int64 iOfst
   372  ){
   373    devsym_file *p = (devsym_file *)pFile;
   374    if( g.nWriteCrash>0 ){
   375      g.nWriteCrash--;
   376      if( g.nWriteCrash==0 ) abort();
   377    }
   378    return sqlite3OsWrite(p->pReal, zBuf, iAmt, iOfst);
   379  }
   380  
   381  /*
   382  ** Open an writecrash file handle.
   383  */
   384  static int writecrashOpen(
   385    sqlite3_vfs *pVfs,
   386    const char *zName,
   387    sqlite3_file *pFile,
   388    int flags,
   389    int *pOutFlags
   390  ){
   391  static sqlite3_io_methods writecrash_io_methods = {
   392    2,                                /* iVersion */
   393    devsymClose,                      /* xClose */
   394    devsymRead,                       /* xRead */
   395    writecrashWrite,                  /* xWrite */
   396    devsymTruncate,                   /* xTruncate */
   397    devsymSync,                       /* xSync */
   398    devsymFileSize,                   /* xFileSize */
   399    devsymLock,                       /* xLock */
   400    devsymUnlock,                     /* xUnlock */
   401    devsymCheckReservedLock,          /* xCheckReservedLock */
   402    devsymFileControl,                /* xFileControl */
   403    writecrashSectorSize,             /* xSectorSize */
   404    writecrashDeviceCharacteristics,  /* xDeviceCharacteristics */
   405    devsymShmMap,                     /* xShmMap */
   406    devsymShmLock,                    /* xShmLock */
   407    devsymShmBarrier,                 /* xShmBarrier */
   408    devsymShmUnmap                    /* xShmUnmap */
   409  };
   410  
   411    int rc;
   412    devsym_file *p = (devsym_file *)pFile;
   413    p->pReal = (sqlite3_file *)&p[1];
   414    rc = sqlite3OsOpen(g.pVfs, zName, p->pReal, flags, pOutFlags);
   415    if( p->pReal->pMethods ){
   416      pFile->pMethods = &writecrash_io_methods;
   417    }
   418    return rc;
   419  }
   420  
   421  static sqlite3_vfs devsym_vfs = {
   422    2,                     /* iVersion */
   423    sizeof(devsym_file),      /* szOsFile */
   424    DEVSYM_MAX_PATHNAME,      /* mxPathname */
   425    0,                     /* pNext */
   426    DEVSYM_VFS_NAME,          /* zName */
   427    0,                     /* pAppData */
   428    devsymOpen,               /* xOpen */
   429    devsymDelete,             /* xDelete */
   430    devsymAccess,             /* xAccess */
   431    devsymFullPathname,       /* xFullPathname */
   432  #ifndef SQLITE_OMIT_LOAD_EXTENSION
   433    devsymDlOpen,             /* xDlOpen */
   434    devsymDlError,            /* xDlError */
   435    devsymDlSym,              /* xDlSym */
   436    devsymDlClose,            /* xDlClose */
   437  #else
   438    0,                        /* xDlOpen */
   439    0,                        /* xDlError */
   440    0,                        /* xDlSym */
   441    0,                        /* xDlClose */
   442  #endif /* SQLITE_OMIT_LOAD_EXTENSION */
   443    devsymRandomness,         /* xRandomness */
   444    devsymSleep,              /* xSleep */
   445    devsymCurrentTime,        /* xCurrentTime */
   446    0,                        /* xGetLastError */
   447    0                         /* xCurrentTimeInt64 */
   448  };
   449  
   450  static sqlite3_vfs writecrash_vfs = {
   451    2,                     /* iVersion */
   452    sizeof(devsym_file),      /* szOsFile */
   453    DEVSYM_MAX_PATHNAME,      /* mxPathname */
   454    0,                     /* pNext */
   455    WRITECRASH_NAME,          /* zName */
   456    0,                     /* pAppData */
   457    writecrashOpen,           /* xOpen */
   458    devsymDelete,             /* xDelete */
   459    devsymAccess,             /* xAccess */
   460    devsymFullPathname,       /* xFullPathname */
   461  #ifndef SQLITE_OMIT_LOAD_EXTENSION
   462    devsymDlOpen,             /* xDlOpen */
   463    devsymDlError,            /* xDlError */
   464    devsymDlSym,              /* xDlSym */
   465    devsymDlClose,            /* xDlClose */
   466  #else
   467    0,                        /* xDlOpen */
   468    0,                        /* xDlError */
   469    0,                        /* xDlSym */
   470    0,                        /* xDlClose */
   471  #endif /* SQLITE_OMIT_LOAD_EXTENSION */
   472    devsymRandomness,         /* xRandomness */
   473    devsymSleep,              /* xSleep */
   474    devsymCurrentTime,        /* xCurrentTime */
   475    0,                        /* xGetLastError */
   476    0                         /* xCurrentTimeInt64 */
   477  };
   478  
   479  
   480  /*
   481  ** This procedure registers the devsym vfs with SQLite. If the argument is
   482  ** true, the devsym vfs becomes the new default vfs. It is the only publicly
   483  ** available function in this file.
   484  */
   485  void devsym_register(int iDeviceChar, int iSectorSize){
   486  
   487    if( g.pVfs==0 ){
   488      g.pVfs = sqlite3_vfs_find(0);
   489      devsym_vfs.szOsFile += g.pVfs->szOsFile;
   490      writecrash_vfs.szOsFile += g.pVfs->szOsFile;
   491      sqlite3_vfs_register(&devsym_vfs, 0);
   492      sqlite3_vfs_register(&writecrash_vfs, 0);
   493    }
   494    if( iDeviceChar>=0 ){
   495      g.iDeviceChar = iDeviceChar;
   496    }else{
   497      g.iDeviceChar = 0;
   498    }
   499    if( iSectorSize>=0 ){
   500      g.iSectorSize = iSectorSize;
   501    }else{
   502      g.iSectorSize = 512;
   503    }
   504  }
   505  
   506  void devsym_unregister(){
   507    sqlite3_vfs_unregister(&devsym_vfs);
   508    g.pVfs = 0;
   509    g.iDeviceChar = 0;
   510    g.iSectorSize = 0;
   511  }
   512  
   513  void devsym_crash_on_write(int nWrite){
   514    if( g.pVfs==0 ){
   515      g.pVfs = sqlite3_vfs_find(0);
   516      devsym_vfs.szOsFile += g.pVfs->szOsFile;
   517      writecrash_vfs.szOsFile += g.pVfs->szOsFile;
   518      sqlite3_vfs_register(&devsym_vfs, 0);
   519      sqlite3_vfs_register(&writecrash_vfs, 0);
   520    }
   521    g.nWriteCrash = nWrite;
   522  }
   523  
   524  #endif