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

     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  #include "sqliteInt.h"
    17  
    18  /*
    19  ** If we compile with the SQLITE_TEST macro set, then the following block
    20  ** of code will give us the ability to simulate a disk I/O error.  This
    21  ** is used for testing the I/O recovery logic.
    22  */
    23  #if defined(SQLITE_TEST)
    24  int sqlite3_io_error_hit = 0;            /* Total number of I/O Errors */
    25  int sqlite3_io_error_hardhit = 0;        /* Number of non-benign errors */
    26  int sqlite3_io_error_pending = 0;        /* Count down to first I/O error */
    27  int sqlite3_io_error_persist = 0;        /* True if I/O errors persist */
    28  int sqlite3_io_error_benign = 0;         /* True if errors are benign */
    29  int sqlite3_diskfull_pending = 0;
    30  int sqlite3_diskfull = 0;
    31  #endif /* defined(SQLITE_TEST) */
    32  
    33  /*
    34  ** When testing, also keep a count of the number of open files.
    35  */
    36  #if defined(SQLITE_TEST)
    37  int sqlite3_open_file_count = 0;
    38  #endif /* defined(SQLITE_TEST) */
    39  
    40  /*
    41  ** The default SQLite sqlite3_vfs implementations do not allocate
    42  ** memory (actually, os_unix.c allocates a small amount of memory
    43  ** from within OsOpen()), but some third-party implementations may.
    44  ** So we test the effects of a malloc() failing and the sqlite3OsXXX()
    45  ** function returning SQLITE_IOERR_NOMEM using the DO_OS_MALLOC_TEST macro.
    46  **
    47  ** The following functions are instrumented for malloc() failure
    48  ** testing:
    49  **
    50  **     sqlite3OsRead()
    51  **     sqlite3OsWrite()
    52  **     sqlite3OsSync()
    53  **     sqlite3OsFileSize()
    54  **     sqlite3OsLock()
    55  **     sqlite3OsCheckReservedLock()
    56  **     sqlite3OsFileControl()
    57  **     sqlite3OsShmMap()
    58  **     sqlite3OsOpen()
    59  **     sqlite3OsDelete()
    60  **     sqlite3OsAccess()
    61  **     sqlite3OsFullPathname()
    62  **
    63  */
    64  #if defined(SQLITE_TEST)
    65  int sqlite3_memdebug_vfs_oom_test = 1;
    66    #define DO_OS_MALLOC_TEST(x)                                       \
    67    if (sqlite3_memdebug_vfs_oom_test && (!x || !sqlite3JournalIsInMemory(x))) { \
    68      void *pTstAlloc = sqlite3Malloc(10);                             \
    69      if (!pTstAlloc) return SQLITE_IOERR_NOMEM_BKPT;                  \
    70      sqlite3_free(pTstAlloc);                                         \
    71    }
    72  #else
    73    #define DO_OS_MALLOC_TEST(x)
    74  #endif
    75  
    76  /*
    77  ** The following routines are convenience wrappers around methods
    78  ** of the sqlite3_file object.  This is mostly just syntactic sugar. All
    79  ** of this would be completely automatic if SQLite were coded using
    80  ** C++ instead of plain old C.
    81  */
    82  void sqlite3OsClose(sqlite3_file *pId){
    83    if( pId->pMethods ){
    84      pId->pMethods->xClose(pId);
    85      pId->pMethods = 0;
    86    }
    87  }
    88  int sqlite3OsRead(sqlite3_file *id, void *pBuf, int amt, i64 offset){
    89    DO_OS_MALLOC_TEST(id);
    90    return id->pMethods->xRead(id, pBuf, amt, offset);
    91  }
    92  int sqlite3OsWrite(sqlite3_file *id, const void *pBuf, int amt, i64 offset){
    93    DO_OS_MALLOC_TEST(id);
    94    return id->pMethods->xWrite(id, pBuf, amt, offset);
    95  }
    96  int sqlite3OsTruncate(sqlite3_file *id, i64 size){
    97    return id->pMethods->xTruncate(id, size);
    98  }
    99  int sqlite3OsSync(sqlite3_file *id, int flags){
   100    DO_OS_MALLOC_TEST(id);
   101    return flags ? id->pMethods->xSync(id, flags) : SQLITE_OK;
   102  }
   103  int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){
   104    DO_OS_MALLOC_TEST(id);
   105    return id->pMethods->xFileSize(id, pSize);
   106  }
   107  int sqlite3OsLock(sqlite3_file *id, int lockType){
   108    DO_OS_MALLOC_TEST(id);
   109    return id->pMethods->xLock(id, lockType);
   110  }
   111  int sqlite3OsUnlock(sqlite3_file *id, int lockType){
   112    return id->pMethods->xUnlock(id, lockType);
   113  }
   114  int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut){
   115    DO_OS_MALLOC_TEST(id);
   116    return id->pMethods->xCheckReservedLock(id, pResOut);
   117  }
   118  
   119  /*
   120  ** Use sqlite3OsFileControl() when we are doing something that might fail
   121  ** and we need to know about the failures.  Use sqlite3OsFileControlHint()
   122  ** when simply tossing information over the wall to the VFS and we do not
   123  ** really care if the VFS receives and understands the information since it
   124  ** is only a hint and can be safely ignored.  The sqlite3OsFileControlHint()
   125  ** routine has no return value since the return value would be meaningless.
   126  */
   127  int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){
   128  #ifdef SQLITE_TEST
   129    if( op!=SQLITE_FCNTL_COMMIT_PHASETWO ){
   130      /* Faults are not injected into COMMIT_PHASETWO because, assuming SQLite
   131      ** is using a regular VFS, it is called after the corresponding
   132      ** transaction has been committed. Injecting a fault at this point
   133      ** confuses the test scripts - the COMMIT comand returns SQLITE_NOMEM
   134      ** but the transaction is committed anyway.
   135      **
   136      ** The core must call OsFileControl() though, not OsFileControlHint(),
   137      ** as if a custom VFS (e.g. zipvfs) returns an error here, it probably
   138      ** means the commit really has failed and an error should be returned
   139      ** to the user.  */
   140      DO_OS_MALLOC_TEST(id);
   141    }
   142  #endif
   143    return id->pMethods->xFileControl(id, op, pArg);
   144  }
   145  void sqlite3OsFileControlHint(sqlite3_file *id, int op, void *pArg){
   146    (void)id->pMethods->xFileControl(id, op, pArg);
   147  }
   148  
   149  int sqlite3OsSectorSize(sqlite3_file *id){
   150    int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize;
   151    return (xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE);
   152  }
   153  int sqlite3OsDeviceCharacteristics(sqlite3_file *id){
   154    return id->pMethods->xDeviceCharacteristics(id);
   155  }
   156  #ifndef SQLITE_OMIT_WAL
   157  int sqlite3OsShmLock(sqlite3_file *id, int offset, int n, int flags){
   158    return id->pMethods->xShmLock(id, offset, n, flags);
   159  }
   160  void sqlite3OsShmBarrier(sqlite3_file *id){
   161    id->pMethods->xShmBarrier(id);
   162  }
   163  int sqlite3OsShmUnmap(sqlite3_file *id, int deleteFlag){
   164    return id->pMethods->xShmUnmap(id, deleteFlag);
   165  }
   166  int sqlite3OsShmMap(
   167    sqlite3_file *id,               /* Database file handle */
   168    int iPage,
   169    int pgsz,
   170    int bExtend,                    /* True to extend file if necessary */
   171    void volatile **pp              /* OUT: Pointer to mapping */
   172  ){
   173    DO_OS_MALLOC_TEST(id);
   174    return id->pMethods->xShmMap(id, iPage, pgsz, bExtend, pp);
   175  }
   176  #endif /* SQLITE_OMIT_WAL */
   177  
   178  #if SQLITE_MAX_MMAP_SIZE>0
   179  /* The real implementation of xFetch and xUnfetch */
   180  int sqlite3OsFetch(sqlite3_file *id, i64 iOff, int iAmt, void **pp){
   181    DO_OS_MALLOC_TEST(id);
   182    return id->pMethods->xFetch(id, iOff, iAmt, pp);
   183  }
   184  int sqlite3OsUnfetch(sqlite3_file *id, i64 iOff, void *p){
   185    return id->pMethods->xUnfetch(id, iOff, p);
   186  }
   187  #else
   188  /* No-op stubs to use when memory-mapped I/O is disabled */
   189  int sqlite3OsFetch(sqlite3_file *id, i64 iOff, int iAmt, void **pp){
   190    *pp = 0;
   191    return SQLITE_OK;
   192  }
   193  int sqlite3OsUnfetch(sqlite3_file *id, i64 iOff, void *p){
   194    return SQLITE_OK;
   195  }
   196  #endif
   197  
   198  /*
   199  ** The next group of routines are convenience wrappers around the
   200  ** VFS methods.
   201  */
   202  int sqlite3OsOpen(
   203    sqlite3_vfs *pVfs,
   204    const char *zPath,
   205    sqlite3_file *pFile,
   206    int flags,
   207    int *pFlagsOut
   208  ){
   209    int rc;
   210    DO_OS_MALLOC_TEST(0);
   211    /* 0x87f7f is a mask of SQLITE_OPEN_ flags that are valid to be passed
   212    ** down into the VFS layer.  Some SQLITE_OPEN_ flags (for example,
   213    ** SQLITE_OPEN_FULLMUTEX or SQLITE_OPEN_SHAREDCACHE) are blocked before
   214    ** reaching the VFS. */
   215    rc = pVfs->xOpen(pVfs, zPath, pFile, flags & 0x87f7f, pFlagsOut);
   216    assert( rc==SQLITE_OK || pFile->pMethods==0 );
   217    return rc;
   218  }
   219  int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
   220    DO_OS_MALLOC_TEST(0);
   221    assert( dirSync==0 || dirSync==1 );
   222    return pVfs->xDelete(pVfs, zPath, dirSync);
   223  }
   224  int sqlite3OsAccess(
   225    sqlite3_vfs *pVfs,
   226    const char *zPath,
   227    int flags,
   228    int *pResOut
   229  ){
   230    DO_OS_MALLOC_TEST(0);
   231    return pVfs->xAccess(pVfs, zPath, flags, pResOut);
   232  }
   233  int sqlite3OsFullPathname(
   234    sqlite3_vfs *pVfs,
   235    const char *zPath,
   236    int nPathOut,
   237    char *zPathOut
   238  ){
   239    DO_OS_MALLOC_TEST(0);
   240    zPathOut[0] = 0;
   241    return pVfs->xFullPathname(pVfs, zPath, nPathOut, zPathOut);
   242  }
   243  #ifndef SQLITE_OMIT_LOAD_EXTENSION
   244  void *sqlite3OsDlOpen(sqlite3_vfs *pVfs, const char *zPath){
   245    return pVfs->xDlOpen(pVfs, zPath);
   246  }
   247  void sqlite3OsDlError(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
   248    pVfs->xDlError(pVfs, nByte, zBufOut);
   249  }
   250  void (*sqlite3OsDlSym(sqlite3_vfs *pVfs, void *pHdle, const char *zSym))(void){
   251    return pVfs->xDlSym(pVfs, pHdle, zSym);
   252  }
   253  void sqlite3OsDlClose(sqlite3_vfs *pVfs, void *pHandle){
   254    pVfs->xDlClose(pVfs, pHandle);
   255  }
   256  #endif /* SQLITE_OMIT_LOAD_EXTENSION */
   257  int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
   258    return pVfs->xRandomness(pVfs, nByte, zBufOut);
   259  }
   260  int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){
   261    return pVfs->xSleep(pVfs, nMicro);
   262  }
   263  int sqlite3OsGetLastError(sqlite3_vfs *pVfs){
   264    return pVfs->xGetLastError ? pVfs->xGetLastError(pVfs, 0, 0) : 0;
   265  }
   266  int sqlite3OsCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){
   267    int rc;
   268    /* IMPLEMENTATION-OF: R-49045-42493 SQLite will use the xCurrentTimeInt64()
   269    ** method to get the current date and time if that method is available
   270    ** (if iVersion is 2 or greater and the function pointer is not NULL) and
   271    ** will fall back to xCurrentTime() if xCurrentTimeInt64() is
   272    ** unavailable.
   273    */
   274    if( pVfs->iVersion>=2 && pVfs->xCurrentTimeInt64 ){
   275      rc = pVfs->xCurrentTimeInt64(pVfs, pTimeOut);
   276    }else{
   277      double r;
   278      rc = pVfs->xCurrentTime(pVfs, &r);
   279      *pTimeOut = (sqlite3_int64)(r*86400000.0);
   280    }
   281    return rc;
   282  }
   283  
   284  int sqlite3OsOpenMalloc(
   285    sqlite3_vfs *pVfs,
   286    const char *zFile,
   287    sqlite3_file **ppFile,
   288    int flags,
   289    int *pOutFlags
   290  ){
   291    int rc;
   292    sqlite3_file *pFile;
   293    pFile = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile);
   294    if( pFile ){
   295      rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags);
   296      if( rc!=SQLITE_OK ){
   297        sqlite3_free(pFile);
   298      }else{
   299        *ppFile = pFile;
   300      }
   301    }else{
   302      rc = SQLITE_NOMEM_BKPT;
   303    }
   304    return rc;
   305  }
   306  void sqlite3OsCloseFree(sqlite3_file *pFile){
   307    assert( pFile );
   308    sqlite3OsClose(pFile);
   309    sqlite3_free(pFile);
   310  }
   311  
   312  /*
   313  ** This function is a wrapper around the OS specific implementation of
   314  ** sqlite3_os_init(). The purpose of the wrapper is to provide the
   315  ** ability to simulate a malloc failure, so that the handling of an
   316  ** error in sqlite3_os_init() by the upper layers can be tested.
   317  */
   318  int sqlite3OsInit(void){
   319    void *p = sqlite3_malloc(10);
   320    if( p==0 ) return SQLITE_NOMEM_BKPT;
   321    sqlite3_free(p);
   322    return sqlite3_os_init();
   323  }
   324  
   325  /*
   326  ** The list of all registered VFS implementations.
   327  */
   328  static sqlite3_vfs * SQLITE_WSD vfsList = 0;
   329  #define vfsList GLOBAL(sqlite3_vfs *, vfsList)
   330  
   331  /*
   332  ** Locate a VFS by name.  If no name is given, simply return the
   333  ** first VFS on the list.
   334  */
   335  sqlite3_vfs *sqlite3_vfs_find(const char *zVfs){
   336    sqlite3_vfs *pVfs = 0;
   337  #if SQLITE_THREADSAFE
   338    sqlite3_mutex *mutex;
   339  #endif
   340  #ifndef SQLITE_OMIT_AUTOINIT
   341    int rc = sqlite3_initialize();
   342    if( rc ) return 0;
   343  #endif
   344  #if SQLITE_THREADSAFE
   345    mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
   346  #endif
   347    sqlite3_mutex_enter(mutex);
   348    for(pVfs = vfsList; pVfs; pVfs=pVfs->pNext){
   349      if( zVfs==0 ) break;
   350      if( strcmp(zVfs, pVfs->zName)==0 ) break;
   351    }
   352    sqlite3_mutex_leave(mutex);
   353    return pVfs;
   354  }
   355  
   356  /*
   357  ** Unlink a VFS from the linked list
   358  */
   359  static void vfsUnlink(sqlite3_vfs *pVfs){
   360    assert( sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)) );
   361    if( pVfs==0 ){
   362      /* No-op */
   363    }else if( vfsList==pVfs ){
   364      vfsList = pVfs->pNext;
   365    }else if( vfsList ){
   366      sqlite3_vfs *p = vfsList;
   367      while( p->pNext && p->pNext!=pVfs ){
   368        p = p->pNext;
   369      }
   370      if( p->pNext==pVfs ){
   371        p->pNext = pVfs->pNext;
   372      }
   373    }
   374  }
   375  
   376  /*
   377  ** Register a VFS with the system.  It is harmless to register the same
   378  ** VFS multiple times.  The new VFS becomes the default if makeDflt is
   379  ** true.
   380  */
   381  int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
   382    MUTEX_LOGIC(sqlite3_mutex *mutex;)
   383  #ifndef SQLITE_OMIT_AUTOINIT
   384    int rc = sqlite3_initialize();
   385    if( rc ) return rc;
   386  #endif
   387  #ifdef SQLITE_ENABLE_API_ARMOR
   388    if( pVfs==0 ) return SQLITE_MISUSE_BKPT;
   389  #endif
   390  
   391    MUTEX_LOGIC( mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
   392    sqlite3_mutex_enter(mutex);
   393    vfsUnlink(pVfs);
   394    if( makeDflt || vfsList==0 ){
   395      pVfs->pNext = vfsList;
   396      vfsList = pVfs;
   397    }else{
   398      pVfs->pNext = vfsList->pNext;
   399      vfsList->pNext = pVfs;
   400    }
   401    assert(vfsList);
   402    sqlite3_mutex_leave(mutex);
   403    return SQLITE_OK;
   404  }
   405  
   406  /*
   407  ** Unregister a VFS so that it is no longer accessible.
   408  */
   409  int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){
   410  #if SQLITE_THREADSAFE
   411    sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
   412  #endif
   413    sqlite3_mutex_enter(mutex);
   414    vfsUnlink(pVfs);
   415    sqlite3_mutex_leave(mutex);
   416    return SQLITE_OK;
   417  }