| 2 |      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 | }
 |