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