persistentstorage/sql/SQLite364/os.c
changeset 0 08ec8eefde2f
equal deleted inserted replaced
-1:000000000000 0:08ec8eefde2f
       
     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 ** $Id: os.c,v 1.124 2008/10/07 15:25:48 drh Exp $
       
    17 */
       
    18 #define _SQLITE_OS_C_ 1
       
    19 #include "sqliteInt.h"
       
    20 #undef _SQLITE_OS_C_
       
    21 
       
    22 /*
       
    23 ** The default SQLite sqlite3_vfs implementations do not allocate
       
    24 ** memory (actually, os_unix.c allocates a small amount of memory
       
    25 ** from within OsOpen()), but some third-party implementations may.
       
    26 ** So we test the effects of a malloc() failing and the sqlite3OsXXX()
       
    27 ** function returning SQLITE_IOERR_NOMEM using the DO_OS_MALLOC_TEST macro.
       
    28 **
       
    29 ** The following functions are instrumented for malloc() failure 
       
    30 ** testing:
       
    31 **
       
    32 **     sqlite3OsOpen()
       
    33 **     sqlite3OsRead()
       
    34 **     sqlite3OsWrite()
       
    35 **     sqlite3OsSync()
       
    36 **     sqlite3OsLock()
       
    37 **
       
    38 */
       
    39 #if defined(SQLITE_TEST) && (SQLITE_OS_WIN==0)
       
    40   #define DO_OS_MALLOC_TEST if (1) {            \
       
    41     void *pTstAlloc = sqlite3Malloc(10);       \
       
    42     if (!pTstAlloc) return SQLITE_IOERR_NOMEM;  \
       
    43     sqlite3_free(pTstAlloc);                    \
       
    44   }
       
    45 #else
       
    46   #define DO_OS_MALLOC_TEST
       
    47 #endif
       
    48 
       
    49 /*
       
    50 ** The following routines are convenience wrappers around methods
       
    51 ** of the sqlite3_file object.  This is mostly just syntactic sugar. All
       
    52 ** of this would be completely automatic if SQLite were coded using
       
    53 ** C++ instead of plain old C.
       
    54 */
       
    55 int sqlite3OsClose(sqlite3_file *pId){
       
    56   int rc = SQLITE_OK;
       
    57   if( pId->pMethods ){
       
    58     rc = pId->pMethods->xClose(pId);
       
    59     pId->pMethods = 0;
       
    60   }
       
    61   return rc;
       
    62 }
       
    63 int sqlite3OsRead(sqlite3_file *id, void *pBuf, int amt, i64 offset){
       
    64   DO_OS_MALLOC_TEST;
       
    65   return id->pMethods->xRead(id, pBuf, amt, offset);
       
    66 }
       
    67 int sqlite3OsWrite(sqlite3_file *id, const void *pBuf, int amt, i64 offset){
       
    68   DO_OS_MALLOC_TEST;
       
    69   return id->pMethods->xWrite(id, pBuf, amt, offset);
       
    70 }
       
    71 int sqlite3OsTruncate(sqlite3_file *id, i64 size){
       
    72   return id->pMethods->xTruncate(id, size);
       
    73 }
       
    74 int sqlite3OsSync(sqlite3_file *id, int flags){
       
    75   DO_OS_MALLOC_TEST;
       
    76   return id->pMethods->xSync(id, flags);
       
    77 }
       
    78 int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){
       
    79   DO_OS_MALLOC_TEST;
       
    80   return id->pMethods->xFileSize(id, pSize);
       
    81 }
       
    82 int sqlite3OsLock(sqlite3_file *id, int lockType){
       
    83   DO_OS_MALLOC_TEST;
       
    84   return id->pMethods->xLock(id, lockType);
       
    85 }
       
    86 int sqlite3OsUnlock(sqlite3_file *id, int lockType){
       
    87   return id->pMethods->xUnlock(id, lockType);
       
    88 }
       
    89 int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut){
       
    90   DO_OS_MALLOC_TEST;
       
    91   return id->pMethods->xCheckReservedLock(id, pResOut);
       
    92 }
       
    93 int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){
       
    94   return id->pMethods->xFileControl(id, op, pArg);
       
    95 }
       
    96 int sqlite3OsSectorSize(sqlite3_file *id){
       
    97   int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize;
       
    98   return (xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE);
       
    99 }
       
   100 int sqlite3OsDeviceCharacteristics(sqlite3_file *id){
       
   101   return id->pMethods->xDeviceCharacteristics(id);
       
   102 }
       
   103 
       
   104 /*
       
   105 ** The next group of routines are convenience wrappers around the
       
   106 ** VFS methods.
       
   107 */
       
   108 int sqlite3OsOpen(
       
   109   sqlite3_vfs *pVfs, 
       
   110   const char *zPath, 
       
   111   sqlite3_file *pFile, 
       
   112   int flags, 
       
   113   int *pFlagsOut
       
   114 ){
       
   115   DO_OS_MALLOC_TEST;
       
   116   return pVfs->xOpen(pVfs, zPath, pFile, flags, pFlagsOut);
       
   117 }
       
   118 int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
       
   119   return pVfs->xDelete(pVfs, zPath, dirSync);
       
   120 }
       
   121 int sqlite3OsAccess(
       
   122   sqlite3_vfs *pVfs, 
       
   123   const char *zPath, 
       
   124   int flags, 
       
   125   int *pResOut
       
   126 ){
       
   127   DO_OS_MALLOC_TEST;
       
   128   return pVfs->xAccess(pVfs, zPath, flags, pResOut);
       
   129 }
       
   130 int sqlite3OsFullPathname(
       
   131   sqlite3_vfs *pVfs, 
       
   132   const char *zPath, 
       
   133   int nPathOut, 
       
   134   char *zPathOut
       
   135 ){
       
   136   return pVfs->xFullPathname(pVfs, zPath, nPathOut, zPathOut);
       
   137 }
       
   138 #ifndef SQLITE_OMIT_LOAD_EXTENSION
       
   139 void *sqlite3OsDlOpen(sqlite3_vfs *pVfs, const char *zPath){
       
   140   return pVfs->xDlOpen(pVfs, zPath);
       
   141 }
       
   142 void sqlite3OsDlError(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
       
   143   pVfs->xDlError(pVfs, nByte, zBufOut);
       
   144 }
       
   145 void *sqlite3OsDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){
       
   146   return pVfs->xDlSym(pVfs, pHandle, zSymbol);
       
   147 }
       
   148 void sqlite3OsDlClose(sqlite3_vfs *pVfs, void *pHandle){
       
   149   pVfs->xDlClose(pVfs, pHandle);
       
   150 }
       
   151 #endif /* SQLITE_OMIT_LOAD_EXTENSION */
       
   152 int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
       
   153   return pVfs->xRandomness(pVfs, nByte, zBufOut);
       
   154 }
       
   155 int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){
       
   156   return pVfs->xSleep(pVfs, nMicro);
       
   157 }
       
   158 int sqlite3OsCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
       
   159   return pVfs->xCurrentTime(pVfs, pTimeOut);
       
   160 }
       
   161 
       
   162 int sqlite3OsOpenMalloc(
       
   163   sqlite3_vfs *pVfs, 
       
   164   const char *zFile, 
       
   165   sqlite3_file **ppFile, 
       
   166   int flags,
       
   167   int *pOutFlags
       
   168 ){
       
   169   int rc = SQLITE_NOMEM;
       
   170   sqlite3_file *pFile;
       
   171   pFile = (sqlite3_file *)sqlite3Malloc(pVfs->szOsFile);
       
   172   if( pFile ){
       
   173     rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags);
       
   174     if( rc!=SQLITE_OK ){
       
   175       sqlite3_free(pFile);
       
   176     }else{
       
   177       *ppFile = pFile;
       
   178     }
       
   179   }
       
   180   return rc;
       
   181 }
       
   182 int sqlite3OsCloseFree(sqlite3_file *pFile){
       
   183   int rc = SQLITE_OK;
       
   184   assert( pFile );
       
   185   rc = sqlite3OsClose(pFile);
       
   186   sqlite3_free(pFile);
       
   187   return rc;
       
   188 }
       
   189 
       
   190 /*
       
   191 ** The list of all registered VFS implementations.
       
   192 */
       
   193 static sqlite3_vfs * SQLITE_WSD vfsList = 0;
       
   194 #define vfsList GLOBAL(sqlite3_vfs *, vfsList)
       
   195 
       
   196 /*
       
   197 ** Locate a VFS by name.  If no name is given, simply return the
       
   198 ** first VFS on the list.
       
   199 */
       
   200 sqlite3_vfs *sqlite3_vfs_find(const char *zVfs){
       
   201   sqlite3_vfs *pVfs = 0;
       
   202 #if SQLITE_THREADSAFE
       
   203   sqlite3_mutex *mutex;
       
   204 #endif
       
   205 #ifndef SQLITE_OMIT_AUTOINIT
       
   206   int rc = sqlite3_initialize();
       
   207   if( rc ) return 0;
       
   208 #endif
       
   209 #if SQLITE_THREADSAFE
       
   210   mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
       
   211 #endif
       
   212   sqlite3_mutex_enter(mutex);
       
   213   for(pVfs = vfsList; pVfs; pVfs=pVfs->pNext){
       
   214     if( zVfs==0 ) break;
       
   215     if( strcmp(zVfs, pVfs->zName)==0 ) break;
       
   216   }
       
   217   sqlite3_mutex_leave(mutex);
       
   218   return pVfs;
       
   219 }
       
   220 
       
   221 /*
       
   222 ** Unlink a VFS from the linked list
       
   223 */
       
   224 static void vfsUnlink(sqlite3_vfs *pVfs){
       
   225   assert( sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)) );
       
   226   if( pVfs==0 ){
       
   227     /* No-op */
       
   228   }else if( vfsList==pVfs ){
       
   229     vfsList = pVfs->pNext;
       
   230   }else if( vfsList ){
       
   231     sqlite3_vfs *p = vfsList;
       
   232     while( p->pNext && p->pNext!=pVfs ){
       
   233       p = p->pNext;
       
   234     }
       
   235     if( p->pNext==pVfs ){
       
   236       p->pNext = pVfs->pNext;
       
   237     }
       
   238   }
       
   239 }
       
   240 
       
   241 /*
       
   242 ** Register a VFS with the system.  It is harmless to register the same
       
   243 ** VFS multiple times.  The new VFS becomes the default if makeDflt is
       
   244 ** true.
       
   245 */
       
   246 int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
       
   247   sqlite3_mutex *mutex = 0;
       
   248 #ifndef SQLITE_OMIT_AUTOINIT
       
   249   int rc = sqlite3_initialize();
       
   250   if( rc ) return rc;
       
   251 #endif
       
   252   mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
       
   253   sqlite3_mutex_enter(mutex);
       
   254   vfsUnlink(pVfs);
       
   255   if( makeDflt || vfsList==0 ){
       
   256     pVfs->pNext = vfsList;
       
   257     vfsList = pVfs;
       
   258   }else{
       
   259     pVfs->pNext = vfsList->pNext;
       
   260     vfsList->pNext = pVfs;
       
   261   }
       
   262   assert(vfsList);
       
   263   sqlite3_mutex_leave(mutex);
       
   264   return SQLITE_OK;
       
   265 }
       
   266 
       
   267 /*
       
   268 ** Unregister a VFS so that it is no longer accessible.
       
   269 */
       
   270 int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){
       
   271 #if SQLITE_THREADSAFE
       
   272   sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
       
   273 #endif
       
   274   sqlite3_mutex_enter(mutex);
       
   275   vfsUnlink(pVfs);
       
   276   sqlite3_mutex_leave(mutex);
       
   277   return SQLITE_OK;
       
   278 }