15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 2005 November 29
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The author disclaims copyright to this source code.  In place of
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** a legal notice, here is a blessing:
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**    May you do good and not evil.
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**    May you find forgiveness for yourself and forgive others.
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**    May you share freely, never taking more than you give.
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)******************************************************************************
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This file contains OS interface code that is common to all
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** architectures.
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define _SQLITE_OS_C_ 1
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sqliteInt.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef _SQLITE_OS_C_
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The default SQLite sqlite3_vfs implementations do not allocate
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** memory (actually, os_unix.c allocates a small amount of memory
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** from within OsOpen()), but some third-party implementations may.
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** So we test the effects of a malloc() failing and the sqlite3OsXXX()
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** function returning SQLITE_IOERR_NOMEM using the DO_OS_MALLOC_TEST macro.
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The following functions are instrumented for malloc() failure
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** testing:
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**     sqlite3OsOpen()
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**     sqlite3OsRead()
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**     sqlite3OsWrite()
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**     sqlite3OsSync()
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**     sqlite3OsLock()
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(SQLITE_TEST)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3_memdebug_vfs_oom_test = 1;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  #define DO_OS_MALLOC_TEST(x)                                       \
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (sqlite3_memdebug_vfs_oom_test && (!x || !sqlite3IsMemJournal(x))) {  \
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void *pTstAlloc = sqlite3Malloc(10);                             \
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!pTstAlloc) return SQLITE_IOERR_NOMEM;                       \
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3_free(pTstAlloc);                                         \
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  #define DO_OS_MALLOC_TEST(x)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The following routines are convenience wrappers around methods
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** of the sqlite3_file object.  This is mostly just syntactic sugar. All
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** of this would be completely automatic if SQLite were coded using
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** C++ instead of plain old C.
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3OsClose(sqlite3_file *pId){
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rc = SQLITE_OK;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( pId->pMethods ){
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rc = pId->pMethods->xClose(pId);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pId->pMethods = 0;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return rc;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3OsRead(sqlite3_file *id, void *pBuf, int amt, i64 offset){
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DO_OS_MALLOC_TEST(id);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return id->pMethods->xRead(id, pBuf, amt, offset);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3OsWrite(sqlite3_file *id, const void *pBuf, int amt, i64 offset){
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DO_OS_MALLOC_TEST(id);
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return id->pMethods->xWrite(id, pBuf, amt, offset);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3OsTruncate(sqlite3_file *id, i64 size){
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return id->pMethods->xTruncate(id, size);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3OsSync(sqlite3_file *id, int flags){
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DO_OS_MALLOC_TEST(id);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return id->pMethods->xSync(id, flags);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DO_OS_MALLOC_TEST(id);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return id->pMethods->xFileSize(id, pSize);
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3OsLock(sqlite3_file *id, int lockType){
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DO_OS_MALLOC_TEST(id);
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return id->pMethods->xLock(id, lockType);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3OsUnlock(sqlite3_file *id, int lockType){
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return id->pMethods->xUnlock(id, lockType);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut){
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DO_OS_MALLOC_TEST(id);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return id->pMethods->xCheckReservedLock(id, pResOut);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return id->pMethods->xFileControl(id, op, pArg);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3OsSectorSize(sqlite3_file *id){
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3OsDeviceCharacteristics(sqlite3_file *id){
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return id->pMethods->xDeviceCharacteristics(id);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3OsShmLock(sqlite3_file *id, int offset, int n, int flags){
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return id->pMethods->xShmLock(id, offset, n, flags);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void sqlite3OsShmBarrier(sqlite3_file *id){
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  id->pMethods->xShmBarrier(id);
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3OsShmUnmap(sqlite3_file *id, int deleteFlag){
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return id->pMethods->xShmUnmap(id, deleteFlag);
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3OsShmMap(
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_file *id,               /* Database file handle */
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int iPage,
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int pgsz,
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int bExtend,                    /* True to extend file if necessary */
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void volatile **pp              /* OUT: Pointer to mapping */
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return id->pMethods->xShmMap(id, iPage, pgsz, bExtend, pp);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The next group of routines are convenience wrappers around the
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** VFS methods.
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3OsOpen(
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_vfs *pVfs,
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char *zPath,
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_file *pFile,
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int flags,
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int *pFlagsOut
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rc;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DO_OS_MALLOC_TEST(0);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* 0x87f3f is a mask of SQLITE_OPEN_ flags that are valid to be passed
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** down into the VFS layer.  Some SQLITE_OPEN_ flags (for example,
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** SQLITE_OPEN_FULLMUTEX or SQLITE_OPEN_SHAREDCACHE) are blocked before
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** reaching the VFS. */
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rc = pVfs->xOpen(pVfs, zPath, pFile, flags & 0x87f3f, pFlagsOut);
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert( rc==SQLITE_OK || pFile->pMethods==0 );
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return rc;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return pVfs->xDelete(pVfs, zPath, dirSync);
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3OsAccess(
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_vfs *pVfs,
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char *zPath,
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int flags,
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int *pResOut
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DO_OS_MALLOC_TEST(0);
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return pVfs->xAccess(pVfs, zPath, flags, pResOut);
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3OsFullPathname(
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_vfs *pVfs,
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char *zPath,
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nPathOut,
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char *zPathOut
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  zPathOut[0] = 0;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return pVfs->xFullPathname(pVfs, zPath, nPathOut, zPathOut);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_LOAD_EXTENSION
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void *sqlite3OsDlOpen(sqlite3_vfs *pVfs, const char *zPath){
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return pVfs->xDlOpen(pVfs, zPath);
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void sqlite3OsDlError(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pVfs->xDlError(pVfs, nByte, zBufOut);
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void (*sqlite3OsDlSym(sqlite3_vfs *pVfs, void *pHdle, const char *zSym))(void){
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return pVfs->xDlSym(pVfs, pHdle, zSym);
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void sqlite3OsDlClose(sqlite3_vfs *pVfs, void *pHandle){
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pVfs->xDlClose(pVfs, pHandle);
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* SQLITE_OMIT_LOAD_EXTENSION */
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return pVfs->xRandomness(pVfs, nByte, zBufOut);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return pVfs->xSleep(pVfs, nMicro);
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3OsCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rc;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* IMPLEMENTATION-OF: R-49045-42493 SQLite will use the xCurrentTimeInt64()
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** method to get the current date and time if that method is available
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** (if iVersion is 2 or greater and the function pointer is not NULL) and
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** will fall back to xCurrentTime() if xCurrentTimeInt64() is
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** unavailable.
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  */
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( pVfs->iVersion>=2 && pVfs->xCurrentTimeInt64 ){
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rc = pVfs->xCurrentTimeInt64(pVfs, pTimeOut);
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }else{
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double r;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rc = pVfs->xCurrentTime(pVfs, &r);
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *pTimeOut = (sqlite3_int64)(r*86400000.0);
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return rc;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3OsOpenMalloc(
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_vfs *pVfs,
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char *zFile,
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_file **ppFile,
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int flags,
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int *pOutFlags
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rc = SQLITE_NOMEM;
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_file *pFile;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pFile = (sqlite3_file *)sqlite3Malloc(pVfs->szOsFile);
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( pFile ){
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags);
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( rc!=SQLITE_OK ){
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3_free(pFile);
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }else{
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *ppFile = pFile;
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return rc;
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3OsCloseFree(sqlite3_file *pFile){
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rc = SQLITE_OK;
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert( pFile );
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rc = sqlite3OsClose(pFile);
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_free(pFile);
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return rc;
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This function is a wrapper around the OS specific implementation of
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** sqlite3_os_init(). The purpose of the wrapper is to provide the
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** ability to simulate a malloc failure, so that the handling of an
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** error in sqlite3_os_init() by the upper layers can be tested.
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3OsInit(void){
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void *p = sqlite3_malloc(10);
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( p==0 ) return SQLITE_NOMEM;
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_free(p);
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return sqlite3_os_init();
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The list of all registered VFS implementations.
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static sqlite3_vfs * SQLITE_WSD vfsList = 0;
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define vfsList GLOBAL(sqlite3_vfs *, vfsList)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Locate a VFS by name.  If no name is given, simply return the
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** first VFS on the list.
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sqlite3_vfs *sqlite3_vfs_find(const char *zVfs){
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_vfs *pVfs = 0;
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if SQLITE_THREADSAFE
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_mutex *mutex;
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_AUTOINIT
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rc = sqlite3_initialize();
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( rc ) return 0;
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if SQLITE_THREADSAFE
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_mutex_enter(mutex);
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(pVfs = vfsList; pVfs; pVfs=pVfs->pNext){
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( zVfs==0 ) break;
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( strcmp(zVfs, pVfs->zName)==0 ) break;
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_mutex_leave(mutex);
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return pVfs;
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Unlink a VFS from the linked list
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void vfsUnlink(sqlite3_vfs *pVfs){
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert( sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)) );
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( pVfs==0 ){
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* No-op */
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }else if( vfsList==pVfs ){
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vfsList = pVfs->pNext;
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }else if( vfsList ){
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3_vfs *p = vfsList;
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while( p->pNext && p->pNext!=pVfs ){
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      p = p->pNext;
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( p->pNext==pVfs ){
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      p->pNext = pVfs->pNext;
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Register a VFS with the system.  It is harmless to register the same
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** VFS multiple times.  The new VFS becomes the default if makeDflt is
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** true.
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_mutex *mutex = 0;
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_AUTOINIT
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rc = sqlite3_initialize();
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( rc ) return rc;
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_mutex_enter(mutex);
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vfsUnlink(pVfs);
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( makeDflt || vfsList==0 ){
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pVfs->pNext = vfsList;
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vfsList = pVfs;
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }else{
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pVfs->pNext = vfsList->pNext;
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vfsList->pNext = pVfs;
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert(vfsList);
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_mutex_leave(mutex);
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return SQLITE_OK;
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Unregister a VFS so that it is no longer accessible.
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if SQLITE_THREADSAFE
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_mutex_enter(mutex);
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vfsUnlink(pVfs);
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_mutex_leave(mutex);
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return SQLITE_OK;
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
332