extensions/sqlite/sqlite-source/os.c
author Matt Woodrow <pred@alliedmods.net>
Mon Aug 17 10:53:54 2009 +1200 (2009-08-17)
changeset 2771 ea849fc91a9b
parent 1952 b7aa2b626807
permissions -rw-r--r--
Forgot makefiles patch
     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   return rc;
    60 }
    61 int sqlite3OsRead(sqlite3_file *id, void *pBuf, int amt, i64 offset){
    62   DO_OS_MALLOC_TEST;
    63   return id->pMethods->xRead(id, pBuf, amt, offset);
    64 }
    65 int sqlite3OsWrite(sqlite3_file *id, const void *pBuf, int amt, i64 offset){
    66   DO_OS_MALLOC_TEST;
    67   return id->pMethods->xWrite(id, pBuf, amt, offset);
    68 }
    69 int sqlite3OsTruncate(sqlite3_file *id, i64 size){
    70   return id->pMethods->xTruncate(id, size);
    71 }
    72 int sqlite3OsSync(sqlite3_file *id, int flags){
    73   DO_OS_MALLOC_TEST;
    74   return id->pMethods->xSync(id, flags);
    75 }
    76 int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){
    77   return id->pMethods->xFileSize(id, pSize);
    78 }
    79 int sqlite3OsLock(sqlite3_file *id, int lockType){
    80   DO_OS_MALLOC_TEST;
    81   return id->pMethods->xLock(id, lockType);
    82 }
    83 int sqlite3OsUnlock(sqlite3_file *id, int lockType){
    84   return id->pMethods->xUnlock(id, lockType);
    85 }
    86 int sqlite3OsCheckReservedLock(sqlite3_file *id){
    87   return id->pMethods->xCheckReservedLock(id);
    88 }
    89 int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){
    90   return id->pMethods->xFileControl(id,op,pArg);
    91 }
    92 
    93 #ifdef SQLITE_TEST
    94   /* The following two variables are used to override the values returned
    95   ** by the xSectorSize() and xDeviceCharacteristics() vfs methods for
    96   ** testing purposes. They are usually set by a test command implemented
    97   ** in test6.c.
    98   */
    99   int sqlite3_test_sector_size = 0;
   100   int sqlite3_test_device_characteristics = 0;
   101   int sqlite3OsDeviceCharacteristics(sqlite3_file *id){
   102     int dc = id->pMethods->xDeviceCharacteristics(id);
   103     return dc | sqlite3_test_device_characteristics;
   104   }
   105   int sqlite3OsSectorSize(sqlite3_file *id){
   106     if( sqlite3_test_sector_size==0 ){
   107       int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize;
   108       return (xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE);
   109     }
   110     return sqlite3_test_sector_size;
   111   }
   112 #else
   113   int sqlite3OsSectorSize(sqlite3_file *id){
   114     int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize;
   115     return (xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE);
   116   }
   117   int sqlite3OsDeviceCharacteristics(sqlite3_file *id){
   118     return id->pMethods->xDeviceCharacteristics(id);
   119   }
   120 #endif
   121 
   122 /*
   123 ** The next group of routines are convenience wrappers around the
   124 ** VFS methods.
   125 */
   126 int sqlite3OsOpen(
   127   sqlite3_vfs *pVfs, 
   128   const char *zPath, 
   129   sqlite3_file *pFile, 
   130   int flags, 
   131   int *pFlagsOut
   132 ){
   133   DO_OS_MALLOC_TEST;
   134   return pVfs->xOpen(pVfs, zPath, pFile, flags, pFlagsOut);
   135 }
   136 int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
   137   return pVfs->xDelete(pVfs, zPath, dirSync);
   138 }
   139 int sqlite3OsAccess(sqlite3_vfs *pVfs, const char *zPath, int flags){
   140   return pVfs->xAccess(pVfs, zPath, flags);
   141 }
   142 int sqlite3OsGetTempname(sqlite3_vfs *pVfs, int nBufOut, char *zBufOut){
   143   return pVfs->xGetTempname(pVfs, nBufOut, zBufOut);
   144 }
   145 int sqlite3OsFullPathname(
   146   sqlite3_vfs *pVfs, 
   147   const char *zPath, 
   148   int nPathOut, 
   149   char *zPathOut
   150 ){
   151   return pVfs->xFullPathname(pVfs, zPath, nPathOut, zPathOut);
   152 }
   153 void *sqlite3OsDlOpen(sqlite3_vfs *pVfs, const char *zPath){
   154   return pVfs->xDlOpen(pVfs, zPath);
   155 }
   156 void sqlite3OsDlError(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
   157   pVfs->xDlError(pVfs, nByte, zBufOut);
   158 }
   159 void *sqlite3OsDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){
   160   return pVfs->xDlSym(pVfs, pHandle, zSymbol);
   161 }
   162 void sqlite3OsDlClose(sqlite3_vfs *pVfs, void *pHandle){
   163   pVfs->xDlClose(pVfs, pHandle);
   164 }
   165 int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
   166   return pVfs->xRandomness(pVfs, nByte, zBufOut);
   167 }
   168 int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){
   169   return pVfs->xSleep(pVfs, nMicro);
   170 }
   171 int sqlite3OsCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
   172   return pVfs->xCurrentTime(pVfs, pTimeOut);
   173 }
   174 
   175 int sqlite3OsOpenMalloc(
   176   sqlite3_vfs *pVfs, 
   177   const char *zFile, 
   178   sqlite3_file **ppFile, 
   179   int flags,
   180   int *pOutFlags
   181 ){
   182   int rc = SQLITE_NOMEM;
   183   sqlite3_file *pFile;
   184   pFile = (sqlite3_file *)sqlite3_malloc(pVfs->szOsFile);
   185   if( pFile ){
   186     rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags);
   187     if( rc!=SQLITE_OK ){
   188       sqlite3_free(pFile);
   189     }else{
   190       *ppFile = pFile;
   191     }
   192   }
   193   return rc;
   194 }
   195 int sqlite3OsCloseFree(sqlite3_file *pFile){
   196   int rc = SQLITE_OK;
   197   if( pFile ){
   198     rc = sqlite3OsClose(pFile);
   199     sqlite3_free(pFile);
   200   }
   201   return rc;
   202 }
   203 
   204 /*
   205 ** The list of all registered VFS implementations.  This list is
   206 ** initialized to the single VFS returned by sqlite3OsDefaultVfs()
   207 ** upon the first call to sqlite3_vfs_find().
   208 */
   209 static sqlite3_vfs *vfsList = 0;
   210 
   211 /*
   212 ** Locate a VFS by name.  If no name is given, simply return the
   213 ** first VFS on the list.
   214 */
   215 sqlite3_vfs *sqlite3_vfs_find(const char *zVfs){
   216   sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
   217   sqlite3_vfs *pVfs;
   218   static int isInit = 0;
   219   sqlite3_mutex_enter(mutex);
   220   if( !isInit ){
   221     vfsList = sqlite3OsDefaultVfs();
   222     isInit = 1;
   223   }
   224   for(pVfs = vfsList; pVfs; pVfs=pVfs->pNext){
   225     if( zVfs==0 ) break;
   226     if( strcmp(zVfs, pVfs->zName)==0 ) break;
   227   }
   228   sqlite3_mutex_leave(mutex);
   229   return pVfs;
   230 }
   231 
   232 /*
   233 ** Unlink a VFS from the linked list
   234 */
   235 static void vfsUnlink(sqlite3_vfs *pVfs){
   236   assert( sqlite3_mutex_held(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)) );
   237   if( vfsList==pVfs ){
   238     vfsList = pVfs->pNext;
   239   }else{
   240     sqlite3_vfs *p = vfsList;
   241     while( p->pNext && p->pNext!=pVfs ){
   242       p = p->pNext;
   243     }
   244     if( p->pNext==pVfs ){
   245       p->pNext = pVfs->pNext;
   246     }
   247   }
   248 }
   249 
   250 /*
   251 ** Register a VFS with the system.  It is harmless to register the same
   252 ** VFS multiple times.  The new VFS becomes the default if makeDflt is
   253 ** true.
   254 */
   255 int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
   256   sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
   257   sqlite3_vfs_find(0);  /* Make sure we are initialized */
   258   sqlite3_mutex_enter(mutex);
   259   vfsUnlink(pVfs);
   260   if( makeDflt || vfsList==0 ){
   261     pVfs->pNext = vfsList;
   262     vfsList = pVfs;
   263   }else{
   264     pVfs->pNext = vfsList->pNext;
   265     vfsList->pNext = pVfs;
   266   }
   267   assert(vfsList);
   268   sqlite3_mutex_leave(mutex);
   269   return SQLITE_OK;
   270 }
   271 
   272 /*
   273 ** Unregister a VFS so that it is no longer accessible.
   274 */
   275 int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){
   276   sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
   277   sqlite3_mutex_enter(mutex);
   278   vfsUnlink(pVfs);
   279   assert(vfsList);
   280   sqlite3_mutex_leave(mutex);
   281   return SQLITE_OK;
   282 }