Annotation of embedaddon/sqlite3/src/os.c, revision 1.1.1.1

1.1       misho       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: **     sqlite3OsRead()
                     31: **     sqlite3OsWrite()
                     32: **     sqlite3OsSync()
                     33: **     sqlite3OsFileSize()
                     34: **     sqlite3OsLock()
                     35: **     sqlite3OsCheckReservedLock()
                     36: **     sqlite3OsFileControl()
                     37: **     sqlite3OsShmMap()
                     38: **     sqlite3OsOpen()
                     39: **     sqlite3OsDelete()
                     40: **     sqlite3OsAccess()
                     41: **     sqlite3OsFullPathname()
                     42: **
                     43: */
                     44: #if defined(SQLITE_TEST)
                     45: int sqlite3_memdebug_vfs_oom_test = 1;
                     46:   #define DO_OS_MALLOC_TEST(x)                                       \
                     47:   if (sqlite3_memdebug_vfs_oom_test && (!x || !sqlite3IsMemJournal(x))) {  \
                     48:     void *pTstAlloc = sqlite3Malloc(10);                             \
                     49:     if (!pTstAlloc) return SQLITE_IOERR_NOMEM;                       \
                     50:     sqlite3_free(pTstAlloc);                                         \
                     51:   }
                     52: #else
                     53:   #define DO_OS_MALLOC_TEST(x)
                     54: #endif
                     55: 
                     56: /*
                     57: ** The following routines are convenience wrappers around methods
                     58: ** of the sqlite3_file object.  This is mostly just syntactic sugar. All
                     59: ** of this would be completely automatic if SQLite were coded using
                     60: ** C++ instead of plain old C.
                     61: */
                     62: int sqlite3OsClose(sqlite3_file *pId){
                     63:   int rc = SQLITE_OK;
                     64:   if( pId->pMethods ){
                     65:     rc = pId->pMethods->xClose(pId);
                     66:     pId->pMethods = 0;
                     67:   }
                     68:   return rc;
                     69: }
                     70: int sqlite3OsRead(sqlite3_file *id, void *pBuf, int amt, i64 offset){
                     71:   DO_OS_MALLOC_TEST(id);
                     72:   return id->pMethods->xRead(id, pBuf, amt, offset);
                     73: }
                     74: int sqlite3OsWrite(sqlite3_file *id, const void *pBuf, int amt, i64 offset){
                     75:   DO_OS_MALLOC_TEST(id);
                     76:   return id->pMethods->xWrite(id, pBuf, amt, offset);
                     77: }
                     78: int sqlite3OsTruncate(sqlite3_file *id, i64 size){
                     79:   return id->pMethods->xTruncate(id, size);
                     80: }
                     81: int sqlite3OsSync(sqlite3_file *id, int flags){
                     82:   DO_OS_MALLOC_TEST(id);
                     83:   return id->pMethods->xSync(id, flags);
                     84: }
                     85: int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){
                     86:   DO_OS_MALLOC_TEST(id);
                     87:   return id->pMethods->xFileSize(id, pSize);
                     88: }
                     89: int sqlite3OsLock(sqlite3_file *id, int lockType){
                     90:   DO_OS_MALLOC_TEST(id);
                     91:   return id->pMethods->xLock(id, lockType);
                     92: }
                     93: int sqlite3OsUnlock(sqlite3_file *id, int lockType){
                     94:   return id->pMethods->xUnlock(id, lockType);
                     95: }
                     96: int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut){
                     97:   DO_OS_MALLOC_TEST(id);
                     98:   return id->pMethods->xCheckReservedLock(id, pResOut);
                     99: }
                    100: 
                    101: /*
                    102: ** Use sqlite3OsFileControl() when we are doing something that might fail
                    103: ** and we need to know about the failures.  Use sqlite3OsFileControlHint()
                    104: ** when simply tossing information over the wall to the VFS and we do not
                    105: ** really care if the VFS receives and understands the information since it
                    106: ** is only a hint and can be safely ignored.  The sqlite3OsFileControlHint()
                    107: ** routine has no return value since the return value would be meaningless.
                    108: */
                    109: int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){
                    110:   DO_OS_MALLOC_TEST(id);
                    111:   return id->pMethods->xFileControl(id, op, pArg);
                    112: }
                    113: void sqlite3OsFileControlHint(sqlite3_file *id, int op, void *pArg){
                    114:   (void)id->pMethods->xFileControl(id, op, pArg);
                    115: }
                    116: 
                    117: int sqlite3OsSectorSize(sqlite3_file *id){
                    118:   int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize;
                    119:   return (xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE);
                    120: }
                    121: int sqlite3OsDeviceCharacteristics(sqlite3_file *id){
                    122:   return id->pMethods->xDeviceCharacteristics(id);
                    123: }
                    124: int sqlite3OsShmLock(sqlite3_file *id, int offset, int n, int flags){
                    125:   return id->pMethods->xShmLock(id, offset, n, flags);
                    126: }
                    127: void sqlite3OsShmBarrier(sqlite3_file *id){
                    128:   id->pMethods->xShmBarrier(id);
                    129: }
                    130: int sqlite3OsShmUnmap(sqlite3_file *id, int deleteFlag){
                    131:   return id->pMethods->xShmUnmap(id, deleteFlag);
                    132: }
                    133: int sqlite3OsShmMap(
                    134:   sqlite3_file *id,               /* Database file handle */
                    135:   int iPage,
                    136:   int pgsz,
                    137:   int bExtend,                    /* True to extend file if necessary */
                    138:   void volatile **pp              /* OUT: Pointer to mapping */
                    139: ){
                    140:   DO_OS_MALLOC_TEST(id);
                    141:   return id->pMethods->xShmMap(id, iPage, pgsz, bExtend, pp);
                    142: }
                    143: 
                    144: /*
                    145: ** The next group of routines are convenience wrappers around the
                    146: ** VFS methods.
                    147: */
                    148: int sqlite3OsOpen(
                    149:   sqlite3_vfs *pVfs, 
                    150:   const char *zPath, 
                    151:   sqlite3_file *pFile, 
                    152:   int flags, 
                    153:   int *pFlagsOut
                    154: ){
                    155:   int rc;
                    156:   DO_OS_MALLOC_TEST(0);
                    157:   /* 0x87f7f is a mask of SQLITE_OPEN_ flags that are valid to be passed
                    158:   ** down into the VFS layer.  Some SQLITE_OPEN_ flags (for example,
                    159:   ** SQLITE_OPEN_FULLMUTEX or SQLITE_OPEN_SHAREDCACHE) are blocked before
                    160:   ** reaching the VFS. */
                    161:   rc = pVfs->xOpen(pVfs, zPath, pFile, flags & 0x87f7f, pFlagsOut);
                    162:   assert( rc==SQLITE_OK || pFile->pMethods==0 );
                    163:   return rc;
                    164: }
                    165: int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
                    166:   DO_OS_MALLOC_TEST(0);
                    167:   assert( dirSync==0 || dirSync==1 );
                    168:   return pVfs->xDelete(pVfs, zPath, dirSync);
                    169: }
                    170: int sqlite3OsAccess(
                    171:   sqlite3_vfs *pVfs, 
                    172:   const char *zPath, 
                    173:   int flags, 
                    174:   int *pResOut
                    175: ){
                    176:   DO_OS_MALLOC_TEST(0);
                    177:   return pVfs->xAccess(pVfs, zPath, flags, pResOut);
                    178: }
                    179: int sqlite3OsFullPathname(
                    180:   sqlite3_vfs *pVfs, 
                    181:   const char *zPath, 
                    182:   int nPathOut, 
                    183:   char *zPathOut
                    184: ){
                    185:   DO_OS_MALLOC_TEST(0);
                    186:   zPathOut[0] = 0;
                    187:   return pVfs->xFullPathname(pVfs, zPath, nPathOut, zPathOut);
                    188: }
                    189: #ifndef SQLITE_OMIT_LOAD_EXTENSION
                    190: void *sqlite3OsDlOpen(sqlite3_vfs *pVfs, const char *zPath){
                    191:   return pVfs->xDlOpen(pVfs, zPath);
                    192: }
                    193: void sqlite3OsDlError(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
                    194:   pVfs->xDlError(pVfs, nByte, zBufOut);
                    195: }
                    196: void (*sqlite3OsDlSym(sqlite3_vfs *pVfs, void *pHdle, const char *zSym))(void){
                    197:   return pVfs->xDlSym(pVfs, pHdle, zSym);
                    198: }
                    199: void sqlite3OsDlClose(sqlite3_vfs *pVfs, void *pHandle){
                    200:   pVfs->xDlClose(pVfs, pHandle);
                    201: }
                    202: #endif /* SQLITE_OMIT_LOAD_EXTENSION */
                    203: int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
                    204:   return pVfs->xRandomness(pVfs, nByte, zBufOut);
                    205: }
                    206: int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){
                    207:   return pVfs->xSleep(pVfs, nMicro);
                    208: }
                    209: int sqlite3OsCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){
                    210:   int rc;
                    211:   /* IMPLEMENTATION-OF: R-49045-42493 SQLite will use the xCurrentTimeInt64()
                    212:   ** method to get the current date and time if that method is available
                    213:   ** (if iVersion is 2 or greater and the function pointer is not NULL) and
                    214:   ** will fall back to xCurrentTime() if xCurrentTimeInt64() is
                    215:   ** unavailable.
                    216:   */
                    217:   if( pVfs->iVersion>=2 && pVfs->xCurrentTimeInt64 ){
                    218:     rc = pVfs->xCurrentTimeInt64(pVfs, pTimeOut);
                    219:   }else{
                    220:     double r;
                    221:     rc = pVfs->xCurrentTime(pVfs, &r);
                    222:     *pTimeOut = (sqlite3_int64)(r*86400000.0);
                    223:   }
                    224:   return rc;
                    225: }
                    226: 
                    227: int sqlite3OsOpenMalloc(
                    228:   sqlite3_vfs *pVfs, 
                    229:   const char *zFile, 
                    230:   sqlite3_file **ppFile, 
                    231:   int flags,
                    232:   int *pOutFlags
                    233: ){
                    234:   int rc = SQLITE_NOMEM;
                    235:   sqlite3_file *pFile;
                    236:   pFile = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile);
                    237:   if( pFile ){
                    238:     rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags);
                    239:     if( rc!=SQLITE_OK ){
                    240:       sqlite3_free(pFile);
                    241:     }else{
                    242:       *ppFile = pFile;
                    243:     }
                    244:   }
                    245:   return rc;
                    246: }
                    247: int sqlite3OsCloseFree(sqlite3_file *pFile){
                    248:   int rc = SQLITE_OK;
                    249:   assert( pFile );
                    250:   rc = sqlite3OsClose(pFile);
                    251:   sqlite3_free(pFile);
                    252:   return rc;
                    253: }
                    254: 
                    255: /*
                    256: ** This function is a wrapper around the OS specific implementation of
                    257: ** sqlite3_os_init(). The purpose of the wrapper is to provide the
                    258: ** ability to simulate a malloc failure, so that the handling of an
                    259: ** error in sqlite3_os_init() by the upper layers can be tested.
                    260: */
                    261: int sqlite3OsInit(void){
                    262:   void *p = sqlite3_malloc(10);
                    263:   if( p==0 ) return SQLITE_NOMEM;
                    264:   sqlite3_free(p);
                    265:   return sqlite3_os_init();
                    266: }
                    267: 
                    268: /*
                    269: ** The list of all registered VFS implementations.
                    270: */
                    271: static sqlite3_vfs * SQLITE_WSD vfsList = 0;
                    272: #define vfsList GLOBAL(sqlite3_vfs *, vfsList)
                    273: 
                    274: /*
                    275: ** Locate a VFS by name.  If no name is given, simply return the
                    276: ** first VFS on the list.
                    277: */
                    278: sqlite3_vfs *sqlite3_vfs_find(const char *zVfs){
                    279:   sqlite3_vfs *pVfs = 0;
                    280: #if SQLITE_THREADSAFE
                    281:   sqlite3_mutex *mutex;
                    282: #endif
                    283: #ifndef SQLITE_OMIT_AUTOINIT
                    284:   int rc = sqlite3_initialize();
                    285:   if( rc ) return 0;
                    286: #endif
                    287: #if SQLITE_THREADSAFE
                    288:   mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
                    289: #endif
                    290:   sqlite3_mutex_enter(mutex);
                    291:   for(pVfs = vfsList; pVfs; pVfs=pVfs->pNext){
                    292:     if( zVfs==0 ) break;
                    293:     if( strcmp(zVfs, pVfs->zName)==0 ) break;
                    294:   }
                    295:   sqlite3_mutex_leave(mutex);
                    296:   return pVfs;
                    297: }
                    298: 
                    299: /*
                    300: ** Unlink a VFS from the linked list
                    301: */
                    302: static void vfsUnlink(sqlite3_vfs *pVfs){
                    303:   assert( sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)) );
                    304:   if( pVfs==0 ){
                    305:     /* No-op */
                    306:   }else if( vfsList==pVfs ){
                    307:     vfsList = pVfs->pNext;
                    308:   }else if( vfsList ){
                    309:     sqlite3_vfs *p = vfsList;
                    310:     while( p->pNext && p->pNext!=pVfs ){
                    311:       p = p->pNext;
                    312:     }
                    313:     if( p->pNext==pVfs ){
                    314:       p->pNext = pVfs->pNext;
                    315:     }
                    316:   }
                    317: }
                    318: 
                    319: /*
                    320: ** Register a VFS with the system.  It is harmless to register the same
                    321: ** VFS multiple times.  The new VFS becomes the default if makeDflt is
                    322: ** true.
                    323: */
                    324: int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
                    325:   MUTEX_LOGIC(sqlite3_mutex *mutex;)
                    326: #ifndef SQLITE_OMIT_AUTOINIT
                    327:   int rc = sqlite3_initialize();
                    328:   if( rc ) return rc;
                    329: #endif
                    330:   MUTEX_LOGIC( mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
                    331:   sqlite3_mutex_enter(mutex);
                    332:   vfsUnlink(pVfs);
                    333:   if( makeDflt || vfsList==0 ){
                    334:     pVfs->pNext = vfsList;
                    335:     vfsList = pVfs;
                    336:   }else{
                    337:     pVfs->pNext = vfsList->pNext;
                    338:     vfsList->pNext = pVfs;
                    339:   }
                    340:   assert(vfsList);
                    341:   sqlite3_mutex_leave(mutex);
                    342:   return SQLITE_OK;
                    343: }
                    344: 
                    345: /*
                    346: ** Unregister a VFS so that it is no longer accessible.
                    347: */
                    348: int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){
                    349: #if SQLITE_THREADSAFE
                    350:   sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
                    351: #endif
                    352:   sqlite3_mutex_enter(mutex);
                    353:   vfsUnlink(pVfs);
                    354:   sqlite3_mutex_leave(mutex);
                    355:   return SQLITE_OK;
                    356: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>