]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Begin migration to using sqlite3_vfs interface. (CVS 4240)
authordanielk1977 <danielk1977@noemail.net>
Fri, 17 Aug 2007 15:53:36 +0000 (15:53 +0000)
committerdanielk1977 <danielk1977@noemail.net>
Fri, 17 Aug 2007 15:53:36 +0000 (15:53 +0000)
FossilOrigin-Name: af3e3c7acdc67013dd733effebe981620d922dd1

21 files changed:
manifest
manifest.uuid
src/btree.c
src/loadext.c
src/main.c
src/mem1.c
src/os.c
src/os.h
src/os_unix.c
src/pager.c
src/pager.h
src/pragma.c
src/random.c
src/sqlite.h.in
src/sqliteInt.h
src/test1.c
src/test2.c
src/test6.c
src/vdbe.c
src/vdbeapi.c
src/vdbeaux.c

index a031cf3eb026d89e1bcd27979f361471bf67663b..58f528f71af887caa94a6d89e34dc5221b9de86e 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Begin\sadding\smutexes.\s\sCompiles\swithout\sSQLITE_OMIT_SHARED_CACHE\sbut\swe\nget\san\sassertion\sfault\son\sthe\sshared\scache\stesting.\s(CVS\s4239)
-D 2007-08-17T01:14:38
+C Begin\smigration\sto\susing\ssqlite3_vfs\sinterface.\s(CVS\s4240)
+D 2007-08-17T15:53:36
 F Makefile.in 0c0e53720f658c7a551046442dd7afba0b72bfbe
 F Makefile.linux-gcc 65241babba6faf1152bf86574477baab19190499
 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@@ -68,7 +68,7 @@ F src/alter.c f0aac0060ae8102e58f210b44d35b53438d53173
 F src/analyze.c a14237d869c6bea0846493b59317e4097e81a0b6
 F src/attach.c a52225c75b107be8c5bc144a2b6d20201be3f8f8
 F src/auth.c 5ea90bc93dfea46e9fe4bf531e14c7cd98219ecb
-F src/btree.c 409e7362338d3cf1f72961a01e75e9fbb577cc9f
+F src/btree.c c4e563b8a8301413984156909461dea882eabed8
 F src/btree.h 91ee529d581c1473d8e6e15299acc3b8de1d0674
 F src/btreeInt.h 6329e955a7dadd8628d5866e2465721b5fd25ef2
 F src/build.c add67be992307b4b11849a6611bfd3352aacde92
@@ -84,46 +84,46 @@ F src/hash.h 3ad3da76bfb954978d227bf495568b0e6da2c19e
 F src/insert.c 633322aef1799f6604fa805e12488bc628570b0c
 F src/legacy.c 6013a7cb7da1b72550b3d35d4fc598b3c3e5b8c1
 F src/limits.h 71ab25f17e35e0a9f3f6f234b8ed49cc56731d35
-F src/loadext.c aa1c6e584d39cc241226ec9390387bc2d4a23e8f
-F src/main.c 6e12fdab03efb8fb17aee8cfcd3bc32329cf1cda
+F src/loadext.c c0ccda3dbda109da087a8fd762deebe5fdf24a1d
+F src/main.c cb6635a4d2fe2b140942338ff5ab605f4c08fa5d
 F src/malloc.c 613c65f12ff0ee4edd017aa458209ab7a23cd7b1
 F src/md5.c c5fdfa5c2593eaee2e32a5ce6c6927c986eaf217
-F src/mem1.c 2c6a6e3b2c9c7cb8d398a8468095032407c3e0b7
+F src/mem1.c 30bf8be3846f92fdf88c490c5e5378512383bcbe
 F src/mem2.c 661ca7ebf6e4b964fecc95d24e8c89dbcfc9dfea
 F src/mutex.c 67b2efd36a1e67a7dc7b7fa852fd69953462c943
-F src/os.c e2faefbe0f5a8ca5e3b1c49ee1b5c6cfa0f0e279
-F src/os.h 8eff07babf74e5bc3f895f8a6c7c294dad5ff997
+F src/os.c c8034df18a06cd1e9dde7d6e096b6709345ee72e
+F src/os.h e54a81bc851724ad17206bfcb4a474f9481f9fc0
 F src/os_common.h a5c446d3b93f09f369d13bf217de4bed3437dd1c
 F src/os_os2.c cba4e96fadb949076c717108fe0599d1a3c2e446
 F src/os_os2.h e5f17dd69333632bbc3112881ea407c37d245eb3
 F src/os_test.c 49833426101f99aee4bb5f6a44b7c4b2029fda1c
 F src/os_test.h 903c93554c23d88f34f667f1979e4a1cee792af3
-F src/os_unix.c e685354a7f21cb47741efc6c681c5acea74597fc
+F src/os_unix.c bf86c474a5febb67684b967a8d2816b1d7f26891
 F src/os_unix.h 5768d56d28240d3fe4537fac08cc85e4fb52279e
 F src/os_win.c d868d5f9e95ec9c1b9e2a30c54c996053db6dddd
 F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
-F src/pager.c 812a3f78ea398764991d668d2d3d81a951e58fa3
-F src/pager.h 94110a5570dca30d54a883e880a3633b2e4c05ae
+F src/pager.c ee60b932e7b4ba355f2606505415b4d5183b1de1
+F src/pager.h 53087c6fb9db01aed17c7fd044662a27507e89b8
 F src/parse.y c03529c3b82702ada98ce405b390e3a9409708cf
-F src/pragma.c 873b0b2ab56248ef76d0387193b8f7a87782b73c
+F src/pragma.c 8f5e37c3cf6dbdeb3645bb80cc58cfc3324c0178
 F src/prepare.c 03292beeffce2d65debab12508a8ec1f5aec7241
 F src/printf.c a8f46e0ed360c18d40e89aa636533be300b406c2
-F src/random.c 6119474a6f6917f708c1dee25b9a8e519a620e88
+F src/random.c 00b30565f018f3a256c157432935de070231c73b
 F src/select.c 98c367bce3f38c5adfcc97de9ab5c79b0e5dc2b2
 F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
 F src/shell.c ac29402b538515fa4697282387be9c1205e6e9eb
-F src/sqlite.h.in 07eea55853b739b372d4744ceefd08795d013be9
+F src/sqlite.h.in f29eb4bc8dc8f4dc61690f339ebb82fec010d4c1
 F src/sqlite3ext.h 647a6b8a8f76ff6c9611e4a071531d8e63ff2d6b
-F src/sqliteInt.h 7298c560e00f2305e2ecc1d2cbdd66134f5049de
+F src/sqliteInt.h 442a6861cf3f535f410acad19a55b2fbca2564a7
 F src/sqliteLimit.h f14609c27636ebc217c9603ade26dbdd7d0f6afa
 F src/table.c c725e47f6f3092b9a7b569fc58e408e2173ee008
 F src/tclsqlite.c 0606c4f31711492eb4d7480a981eebb80914f3d9
-F src/test1.c a1d6eb85149053fac75b01b71439f00908a07c68
-F src/test2.c 4db48e4a487d4d18c2926d9600875613ad286ba8
+F src/test1.c a226ab03048491aa6c5d43d26097df96bdb162e7
+F src/test2.c 47bb59a0198651a9f0551ec956de151da7c24575
 F src/test3.c b87e8fcce45e1d3153aae9f04236076b7707a714
 F src/test4.c d22cb3ab4f9fdfd0a595b70d5328cee923b7322c
 F src/test5.c 7bc8a87c2b6fd076ec2ca9972946e71a367883ad
-F src/test6.c 14919eef8504da6814db7ab19608c786d836fcb2
+F src/test6.c 80990810f64ee96ba27cda5c09624bff383caa60
 F src/test7.c 91d914c2c2b2806157213f41f4185ad3a4970c07
 F src/test8.c 719c284607c1e91a893f5425df1e92b74c859aef
 F src/test9.c c0f38f7795cc51d37db6c63874d90f40f10d0f0e
@@ -144,11 +144,11 @@ F src/update.c e89b980b443d44b68bfc0b1746cdb6308e049ac9
 F src/utf.c 853f97ce0d3cff8dbaef517a6dc475f7001a67c5
 F src/util.c 0273ba16dbf9bab423b1b84c6d548d8f14c25f64
 F src/vacuum.c f45bd9d3aad8d68bb3b85cf89d7a797be5075fde
-F src/vdbe.c 10052a4f1e42e629aee0466b40983e2b61e0295a
+F src/vdbe.c b5cd895a0516466daacc564da332589a903e2eb0
 F src/vdbe.h 001c5b257567c1d3de7feb2203aac71d0d7b16a3
 F src/vdbeInt.h 8e360d326328e7a66100f468697edf9cfb4567dc
-F src/vdbeapi.c a503e3762826d55e808b28393ae1d7b0fa36b1e9
-F src/vdbeaux.c c6d50887e8f29706ae35b965298e58fa6ba0e9bf
+F src/vdbeapi.c ddfe341249929b89c47a0ff77f8043ef0987612b
+F src/vdbeaux.c 6468d5665a3dd932c2e7e4f6b1c0319334b9887a
 F src/vdbeblob.c cf9ee3c7d9977cbd896f8b118da4fb4268637f4f
 F src/vdbefifo.c 334c838c8f42d61a94813d136019ee566b5dc2f6
 F src/vdbemem.c 019952d44066a24aef70ca8c284cfd2d1073c398
@@ -529,7 +529,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
 F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
-P 160593dcc5690af715b775c81137c6e09cca6454
-R 5d5493a8682338889467b44d542e4cdc
-U drh
-Z d35e1fbff49f629248bfcae9f72cc56d
+P 4c1e9ffebe7c611a8b6a89153ae97ab9bca19ea3
+R 473ba7528424cad7a8d671117a18b080
+U danielk1977
+Z ac059cef33a845a67fcbf5f572a89687
index 8ac8ae7697df20d836e09e7465a3c1876765635a..660adc2420a23c0dca25c747d9f9430585cf0a03 100644 (file)
@@ -1 +1 @@
-4c1e9ffebe7c611a8b6a89153ae97ab9bca19ea3
\ No newline at end of file
+af3e3c7acdc67013dd733effebe981620d922dd1
\ No newline at end of file
index ce78a46e8d6b4f17bf2e0d28807975ceafd1a88a..f1ad2d3ce9c4e6390adedf8bd9a7684c55de91bd 100644 (file)
@@ -9,7 +9,7 @@
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
-** $Id: btree.c,v 1.399 2007/08/17 01:14:38 drh Exp $
+** $Id: btree.c,v 1.400 2007/08/17 15:53:36 danielk1977 Exp $
 **
 ** This file implements a external (disk-based) database using BTrees.
 ** See the header comment on "btreeInt.h" for additional information.
@@ -1063,6 +1063,7 @@ int sqlite3BtreeOpen(
   Btree **ppBtree,        /* Pointer to new Btree object written here */
   int flags               /* Options */
 ){
+  sqlite3_vfs *pVfs = (pSqlite?pSqlite->pVfs:sqlite3_find_vfs(0));
   BtShared *pBt = 0;      /* Shared part of btree structure */
   Btree *p;               /* Handle to return */
   int rc = SQLITE_OK;
@@ -1137,7 +1138,7 @@ int sqlite3BtreeOpen(
       rc = SQLITE_NOMEM;
       goto btree_open_out;
     }
-    rc = sqlite3PagerOpen(&pBt->pPager, zFilename, EXTRA_SIZE, flags);
+    rc = sqlite3PagerOpen(pVfs, &pBt->pPager, zFilename, EXTRA_SIZE, flags);
     if( rc==SQLITE_OK ){
       rc = sqlite3PagerReadFileheader(pBt->pPager,sizeof(zDbHeader),zDbHeader);
     }
index de085c7f14bd0fbf3196400ace47939ec809aa47..4f6e3b3dbdba44405dbd1016be9594a4d8745978 100644 (file)
@@ -267,6 +267,7 @@ int sqlite3_load_extension(
   const char *zProc,    /* Entry point.  Use "sqlite3_extension_init" if 0 */
   char **pzErrMsg       /* Put error message here if not 0 */
 ){
+  sqlite3_vfs *pVfs = db->pVfs;
   void *handle;
   int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*);
   char *zErrmsg = 0;
@@ -289,7 +290,7 @@ int sqlite3_load_extension(
     zProc = "sqlite3_extension_init";
   }
 
-  handle = sqlite3OsDlopen(zFile);
+  handle = sqlite3OsDlOpen(pVfs, zFile);
   if( handle==0 ){
     if( pzErrMsg ){
       *pzErrMsg = sqlite3_mprintf("unable to open shared library [%s]", zFile);
@@ -297,20 +298,20 @@ int sqlite3_load_extension(
     return SQLITE_ERROR;
   }
   xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*))
-                   sqlite3OsDlsym(handle, zProc);
+                   sqlite3OsDlSym(pVfs, handle, zProc);
   if( xInit==0 ){
     if( pzErrMsg ){
        *pzErrMsg = sqlite3_mprintf("no entry point [%s] in shared library [%s]",
                                    zProc, zFile);
     }
-    sqlite3OsDlclose(handle);
+    sqlite3OsDlClose(pVfs, handle);
     return SQLITE_ERROR;
   }else if( xInit(db, &zErrmsg, &sqlite3_apis) ){
     if( pzErrMsg ){
       *pzErrMsg = sqlite3_mprintf("error during initialization: %s", zErrmsg);
     }
     sqlite3_free(zErrmsg);
-    sqlite3OsDlclose(handle);
+    sqlite3OsDlClose(pVfs, handle);
     return SQLITE_ERROR;
   }
 
@@ -337,7 +338,7 @@ int sqlite3_load_extension(
 void sqlite3CloseExtensions(sqlite3 *db){
   int i;
   for(i=0; i<db->nExtension; i++){
-    sqlite3OsDlclose(db->aExtension[i]);
+    sqlite3OsDlClose(db->pVfs, db->aExtension[i]);
   }
   sqlite3_free(db->aExtension);
 }
@@ -372,14 +373,14 @@ static void **aAutoExtension = 0;
 int sqlite3_auto_extension(void *xInit){
   int i;
   int rc = SQLITE_OK;
-  sqlite3OsEnterMutex();
+  sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_GLOBAL);
+  sqlite3_mutex_enter(mutex);
   for(i=0; i<nAutoExtension; i++){
     if( aAutoExtension[i]==xInit ) break;
   }
   if( i==nAutoExtension ){
-    nAutoExtension++;
-    aAutoExtension = sqlite3_realloc( aAutoExtension,
-                                     nAutoExtension*sizeof(aAutoExtension[0]) );
+    int nByte = (++nAutoExtension)*sizeof(aAutoExtension[0]);
+    aAutoExtension = sqlite3_realloc(aAutoExtension, nByte);
     if( aAutoExtension==0 ){
       nAutoExtension = 0;
       rc = SQLITE_NOMEM;
@@ -387,7 +388,7 @@ int sqlite3_auto_extension(void *xInit){
       aAutoExtension[nAutoExtension-1] = xInit;
     }
   }
-  sqlite3OsLeaveMutex();
+  sqlite3_mutex_leave(mutex);
   assert( (rc&0xff)==rc );
   return rc;
 }
@@ -396,11 +397,12 @@ int sqlite3_auto_extension(void *xInit){
 ** Reset the automatic extension loading mechanism.
 */
 void sqlite3_reset_auto_extension(void){
-  sqlite3OsEnterMutex();
+  sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_GLOBAL);
+  sqlite3_mutex_enter(mutex);
   sqlite3_free(aAutoExtension);
   aAutoExtension = 0;
   nAutoExtension = 0;
-  sqlite3OsLeaveMutex();
+  sqlite3_mutex_leave(mutex);
 }
 
 /*
@@ -418,7 +420,8 @@ int sqlite3AutoLoadExtensions(sqlite3 *db){
   }
   for(i=0; go; i++){
     char *zErrmsg = 0;
-    sqlite3OsEnterMutex();
+    sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_GLOBAL);
+    sqlite3_mutex_enter(mutex);
     if( i>=nAutoExtension ){
       xInit = 0;
       go = 0;
@@ -426,7 +429,7 @@ int sqlite3AutoLoadExtensions(sqlite3 *db){
       xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*))
               aAutoExtension[i];
     }
-    sqlite3OsLeaveMutex();
+    sqlite3_mutex_leave(mutex);
     if( xInit && xInit(db, &zErrmsg, &sqlite3_apis) ){
       sqlite3Error(db, SQLITE_ERROR,
             "automatic extension loading failed: %s", zErrmsg);
index 4e8b7a8a7759c9aaf0ca434996cfda57ca8ae378..b3eab17579eabb9e8e416a12984058b214decc10 100644 (file)
@@ -14,7 +14,7 @@
 ** other files are for internal use by SQLite and should not be
 ** accessed by users of the library.
 **
-** $Id: main.c,v 1.383 2007/08/17 01:14:38 drh Exp $
+** $Id: main.c,v 1.384 2007/08/17 15:53:36 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -304,7 +304,8 @@ static int sqliteDefaultBusyCallback(
   static const u8 totals[] =
      { 0, 1, 3,  8, 18, 33, 53, 78, 103, 128, 178, 228 };
 # define NDELAY (sizeof(delays)/sizeof(delays[0]))
-  int timeout = ((sqlite3 *)ptr)->busyTimeout;
+  sqlite3 *db = (sqlite3 *)ptr;
+  int timeout = db->busyTimeout;
   int delay, prior;
 
   assert( count>=0 );
@@ -319,7 +320,7 @@ static int sqliteDefaultBusyCallback(
     delay = timeout - prior;
     if( delay<=0 ) return 0;
   }
-  sqlite3OsSleep(delay);
+  sqlite3OsSleep(db->pVfs, delay);
   return 1;
 #else
   int timeout = ((sqlite3 *)ptr)->busyTimeout;
@@ -898,6 +899,7 @@ static int openDatabase(
   /* Allocate the sqlite data structure */
   db = sqlite3MallocZero( sizeof(sqlite3) );
   if( db==0 ) goto opendb_out;
+  db->pVfs = sqlite3_find_vfs(0);
   db->errMask = 0xff;
   db->priorNewRowid = 0;
   db->magic = SQLITE_MAGIC_BUSY;
@@ -1374,7 +1376,9 @@ int sqlite3_clear_bindings(sqlite3_stmt *pStmt){
 ** Sleep for a little while.  Return the amount of time slept.
 */
 int sqlite3_sleep(int ms){
-  return sqlite3OsSleep(ms);
+  sqlite3_vfs *pVfs;
+  pVfs = sqlite3_find_vfs(0);
+  return sqlite3OsSleep(pVfs, 1000*ms);
 }
 
 /*
index 4fc77b04fec718a0c4f925a04b7c8f4180849a29..52f61547f382719da4719e55b301b62a6b2953fa 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains the C functions that implement a memory
 ** allocation subsystem for use by SQLite.  
 **
-** $Id: mem1.c,v 1.5 2007/08/16 19:40:17 drh Exp $
+** $Id: mem1.c,v 1.6 2007/08/17 15:53:36 danielk1977 Exp $
 */
 
 /*
@@ -204,7 +204,7 @@ void *sqlite3_realloc(void *pPrior, unsigned int nBytes){
   }
   if( nBytes==0 ){
     sqlite3_free(pPrior);
-    return;
+    return 0;
   }
   p = pPrior;
   p--;
index d55cfa703287f079b4f60a606267f816d1efbcf3..4307a57c60bc60658690a60dc71f7bb6f9bf0b70 100644 (file)
--- a/src/os.c
+++ b/src/os.c
 ** of this would be completely automatic if SQLite were coded using
 ** C++ instead of plain old C.
 */
-int sqlite3OsClose(sqlite3_file **pId){
-  int rc = SQLITE_OK;
-  sqlite3_file *id;
-  if( pId!=0 && (id = *pId)!=0 ){
-    rc = id->pMethods->xClose(id);
-    if( rc==SQLITE_OK ){
-      *pId = 0;
-    }
-  }
-  return rc;
+int sqlite3OsClose(sqlite3_file *pId){
+  if( !pId->pMethods ) return SQLITE_OK;
+  return pId->pMethods->xClose(pId);
 }
 int sqlite3OsRead(sqlite3_file *id, void *pBuf, int amt, i64 offset){
   return id->pMethods->xRead(id, pBuf, amt, offset);
@@ -82,17 +75,83 @@ int sqlite3OsDeviceCharacteristics(sqlite3_file *id){
   }
 #endif
 
-#ifdef SQLITE_ENABLE_REDEF_IO
-/*
-** A function to return a pointer to the virtual function table.
-** This routine really does not accomplish very much since the
-** virtual function table is a global variable and anybody who
-** can call this function can just as easily access the variable
-** for themselves.  Nevertheless, we include this routine for
-** backwards compatibility with an earlier redefinable I/O
-** interface design.
+int sqlite3OsOpen(
+  sqlite3_vfs *pVfs, 
+  const char *zPath, 
+  sqlite3_file *pFile, 
+  int flags, 
+  int *pFlagsOut
+){
+  return pVfs->xOpen(pVfs->pAppData, zPath, pFile, flags, pFlagsOut);
+}
+int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath){
+  return pVfs->xDelete(pVfs->pAppData, zPath);
+}
+int sqlite3OsAccess(sqlite3_vfs *pVfs, const char *zPath, int flags){
+  return pVfs->xAccess(pVfs->pAppData, zPath, flags);
+}
+int sqlite3OsGetTempName(sqlite3_vfs *pVfs, char *zBufOut){
+  return pVfs->xGetTempName(pVfs->pAppData, zBufOut);
+}
+int sqlite3OsFullPathname(sqlite3_vfs *pVfs, const char *zPath, char *zPathOut){
+  return pVfs->xFullPathname(pVfs->pAppData, zPath, zPathOut);
+}
+void *sqlite3OsDlOpen(sqlite3_vfs *pVfs, const char *zPath){
+  return pVfs->xDlOpen(pVfs->pAppData, zPath);
+}
+void sqlite3OsDlError(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
+  pVfs->xDlError(pVfs->pAppData, nByte, zBufOut);
+}
+void *sqlite3OsDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){
+  return pVfs->xDlSym(pHandle, zSymbol);
+}
+void sqlite3OsDlClose(sqlite3_vfs *pVfs, void *pHandle){
+  pVfs->xDlClose(pHandle);
+}
+int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
+  return pVfs->xRandomness(pVfs->pAppData, nByte, zBufOut);
+}
+int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){
+  return pVfs->xSleep(pVfs->pAppData, nMicro);
+}
+int sqlite3OsCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
+  return pVfs->xCurrentTime(pVfs->pAppData, pTimeOut);
+}
+
+int sqlite3OsOpenMalloc(
+  sqlite3_vfs *pVfs, 
+  const char *zFile, 
+  sqlite3_file **ppFile, 
+  int flags
+){
+  int rc = SQLITE_NOMEM;
+  sqlite3_file *pFile;
+  pFile = (sqlite3_file *)sqlite3_malloc(pVfs->szOsFile);
+  if( pFile ){
+    rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, 0);
+    if( rc!=SQLITE_OK ){
+      sqlite3_free(pFile);
+    }else{
+      *ppFile = pFile;
+    }
+  }
+  return rc;
+}
+int sqlite3OsCloseFree(sqlite3_file *pFile){
+  int rc = SQLITE_OK;
+  if( pFile ){
+    rc = sqlite3OsClose(pFile);
+    sqlite3_free(pFile);
+  }
+  return rc;
+}
+
+/* 
+** Default vfs implementation. Defined by the various os_X.c implementations.
 */
-struct sqlite3OsVtbl *sqlite3_os_switch(void){
-  return &sqlite3Os;
+extern sqlite3_vfs sqlite3DefaultVfs;
+
+sqlite3_vfs *sqlite3_find_vfs(const char *zVfs){
+  return &sqlite3DefaultVfs;
 }
-#endif
+
index 30bc914433b44e20eb3e21aa61d41cf1fad4ca7d..d6b3f5a3390890249f2b228d6e51fb1ab1613308 100644 (file)
--- a/src/os.h
+++ b/src/os.h
 # define TEMP_FILE_PREFIX "etilqs_"
 #endif
 
+#if 0
+
 /*
 ** Define the interfaces for Unix, Windows, and OS/2.
 */
 #define sqlite3OsDlclose            sqlite3Os2Dlclose
 #endif
 
+#endif
 
 
 
@@ -345,10 +348,10 @@ extern unsigned int sqlite3_pending_byte;
 #define SHARED_FIRST      (PENDING_BYTE+2)
 #define SHARED_SIZE       510
 
-/*
-** Prototypes for operating system interface routines.
+/* 
+** Functions for accessing sqlite3_file methods 
 */
-int sqlite3OsClose(sqlite3_file**);
+int sqlite3OsClose(sqlite3_file*);
 int sqlite3OsRead(sqlite3_file*, void*, int amt, i64 offset);
 int sqlite3OsWrite(sqlite3_file*, const void*, int amt, i64 offset);
 int sqlite3OsTruncate(sqlite3_file*, i64 size);
@@ -361,10 +364,33 @@ int sqlite3OsCheckReservedLock(sqlite3_file *id);
 int sqlite3OsSectorSize(sqlite3_file *id);
 int sqlite3OsDeviceCharacteristics(sqlite3_file *id);
 
+/* 
+** Functions for accessing sqlite3_vfs methods 
+*/
+int sqlite3OsOpen(sqlite3_vfs *, const char *, sqlite3_file*, int, int *);
+int sqlite3OsDelete(sqlite3_vfs *, const char *);
+int sqlite3OsAccess(sqlite3_vfs *, const char *, int);
+int sqlite3OsGetTempName(sqlite3_vfs *, char *);
+int sqlite3OsFullPathname(sqlite3_vfs *, const char *, char *);
+void *sqlite3OsDlOpen(sqlite3_vfs *, const char *);
+void sqlite3OsDlError(sqlite3_vfs *, int, char *);
+void *sqlite3OsDlSym(sqlite3_vfs *, void *, const char *);
+void sqlite3OsDlClose(sqlite3_vfs *, void *);
+int sqlite3OsRandomness(sqlite3_vfs *, int, char *);
+int sqlite3OsSleep(sqlite3_vfs *, int);
+int sqlite3OsCurrentTime(sqlite3_vfs *, double*);
+
+/*
+** Convenience functions for opening and closing files using 
+** sqlite3_malloc() to obtain space for the file-handle structure.
+*/
+int sqlite3OsOpenMalloc(sqlite3_vfs *, const char *, sqlite3_file **, int); 
+int sqlite3OsCloseFree(sqlite3_file *);
+
+#if 0
 int sqlite3OsOpenReadWrite(const char*, sqlite3_file**, int*);
 int sqlite3OsOpenExclusive(const char*, sqlite3_file**, int);
 int sqlite3OsOpenReadOnly(const char*, sqlite3_file**);
-
 int sqlite3OsDelete(const char*);
 int sqlite3OsFileExists(const char*);
 char *sqlite3OsFullPathname(const char*);
@@ -385,6 +411,7 @@ int sqlite3OsAllocationSize(void *);
 void *sqlite3OsDlopen(const char*);
 void *sqlite3OsDlsym(void*, const char*);
 int sqlite3OsDlclose(void*);
+#endif
 
 #if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
   int sqlite3OsFileHandle(sqlite3_file *id);
@@ -478,7 +505,7 @@ struct sqlite3OsVtbl {
     sqlite3OsEnterMutex,
     sqlite3OsLeaveMutex,
     sqlite3OsInMutex,
-    sqlite3OsThreadSpecificData,
+    0,
     sqlite3OsMalloc,
     sqlite3OsRealloc,
     sqlite3OsFree,
index 71f4bafdd879768be5b3f7a436ef8c4585e4147f..a3d3ba4ec5eae41b3e1f4b32c22f481929c774cb 100644 (file)
 # define SQLITE_DEFAULT_FILE_PERMISSIONS 0644
 #endif
 
+/*
+** Maximum supported path-length.
+*/
+#define MAX_PATHNAME 512
 
 
 /*
@@ -386,6 +390,13 @@ typedef enum {
 } sqlite3LockingStyle;
 #endif /* SQLITE_ENABLE_LOCKING_STYLE */
 
+static void enterMutex(){
+  sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_GLOBAL));
+}
+static void leaveMutex(){
+  sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_GLOBAL));
+}
+
 #ifdef SQLITE_UNIX_THREADS
 /*
 ** This variable records whether or not threads can override each others
@@ -529,7 +540,6 @@ static void testThreadLockingBehavior(int fd_orig){
 ** Release a lockInfo structure previously allocated by findLockInfo().
 */
 static void releaseLockInfo(struct lockInfo *pLock){
-  assert( sqlite3OsInMutex(1) );
   if (pLock == NULL)
     return;
   pLock->nRef--;
@@ -543,7 +553,6 @@ static void releaseLockInfo(struct lockInfo *pLock){
 ** Release a openCnt structure previously allocated by findLockInfo().
 */
 static void releaseOpenCnt(struct openCnt *pOpen){
-  assert( sqlite3OsInMutex(1) );
   if (pOpen == NULL)
     return;
   pOpen->nRef--;
@@ -646,7 +655,6 @@ static int findLockInfo(
   rc = fstat(fd, &statbuf);
   if( rc!=0 ) return 1;
 
-  assert( sqlite3OsInMutex(1) );
   memset(&key1, 0, sizeof(key1));
   key1.dev = statbuf.st_dev;
   key1.ino = statbuf.st_ino;
@@ -820,6 +828,7 @@ static int allocateUnixFile(
 ** On failure, the function returns SQLITE_CANTOPEN and leaves
 ** *id and *pReadonly unchanged.
 */
+#if 0
 int sqlite3UnixOpenReadWrite(
   const char *zFilename,
   sqlite3_file **pId,
@@ -903,6 +912,7 @@ int sqlite3UnixOpenReadOnly(const char *zFilename, sqlite3_file **pId){
     zFilename, pId, allocateUnixFile(h, pId, zFilename, 0)
   );
 }
+#endif
 
 /*
 ** Attempt to open a file descriptor for the directory that contains a
@@ -943,46 +953,6 @@ static int unixOpenDirectory(
   return SQLITE_OK;
 }
 
-/*
-** Create a temporary file name in zBuf.  zBuf must be big enough to
-** hold at least SQLITE_TEMPNAME_SIZE characters.
-*/
-int sqlite3UnixTempFileName(char *zBuf){
-  static const char *azDirs[] = {
-     0,
-     "/var/tmp",
-     "/usr/tmp",
-     "/tmp",
-     ".",
-  };
-  static const unsigned char zChars[] =
-    "abcdefghijklmnopqrstuvwxyz"
-    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-    "0123456789";
-  int i, j;
-  struct stat buf;
-  const char *zDir = ".";
-  azDirs[0] = sqlite3_temp_directory;
-  for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); i++){
-    if( azDirs[i]==0 ) continue;
-    if( stat(azDirs[i], &buf) ) continue;
-    if( !S_ISDIR(buf.st_mode) ) continue;
-    if( access(azDirs[i], 07) ) continue;
-    zDir = azDirs[i];
-    break;
-  }
-  do{
-    sqlite3_snprintf(SQLITE_TEMPNAME_SIZE, zBuf, "%s/"TEMP_FILE_PREFIX, zDir);
-    j = strlen(zBuf);
-    sqlite3Randomness(15, &zBuf[j]);
-    for(i=0; i<15; i++, j++){
-      zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
-    }
-    zBuf[j] = 0;
-  }while( access(zBuf,0)==0 );
-  return SQLITE_OK; 
-}
-
 /*
 ** Check that a given pathname is a directory and is writable 
 **
@@ -1325,7 +1295,7 @@ static int unixCheckReservedLock(sqlite3_file *id){
   unixFile *pFile = (unixFile*)id;
 
   assert( pFile );
-  sqlite3OsEnterMutex(); /* Because pFile->pLock is shared across threads */
+  enterMutex(); /* Because pFile->pLock is shared across threads */
 
   /* Check if a thread in this process holds such a lock */
   if( pFile->pLock->locktype>SHARED_LOCK ){
@@ -1346,7 +1316,7 @@ static int unixCheckReservedLock(sqlite3_file *id){
     }
   }
   
-  sqlite3OsLeaveMutex();
+  leaveMutex();
   OSTRACE3("TEST WR-LOCK %d %d\n", pFile->h, r);
 
   return r;
@@ -1428,7 +1398,7 @@ static int unixLock(sqlite3_file *id, int locktype){
 
   /* If there is already a lock of this type or more restrictive on the
   ** OsFile, do nothing. Don't use the end_lock: exit path, as
-  ** sqlite3OsEnterMutex() hasn't been called yet.
+  ** enterMutex() hasn't been called yet.
   */
   if( pFile->locktype>=locktype ){
     OSTRACE3("LOCK    %d %s ok (already held)\n", pFile->h,
@@ -1444,13 +1414,13 @@ static int unixLock(sqlite3_file *id, int locktype){
 
   /* This mutex is needed because pFile->pLock is shared across threads
   */
-  sqlite3OsEnterMutex();
+  enterMutex();
 
   /* Make sure the current thread owns the pFile.
   */
   rc = transferOwnership(pFile);
   if( rc!=SQLITE_OK ){
-    sqlite3OsLeaveMutex();
+    leaveMutex();
     return rc;
   }
   pLock = pFile->pLock;
@@ -1565,7 +1535,7 @@ static int unixLock(sqlite3_file *id, int locktype){
   }
 
 end_lock:
-  sqlite3OsLeaveMutex();
+  leaveMutex();
   OSTRACE4("LOCK    %d %s %s\n", pFile->h, locktypeName(locktype), 
       rc==SQLITE_OK ? "ok" : "failed");
   return rc;
@@ -1595,7 +1565,7 @@ static int unixUnlock(sqlite3_file *id, int locktype){
   if( CHECK_THREADID(pFile) ){
     return SQLITE_MISUSE;
   }
-  sqlite3OsEnterMutex();
+  enterMutex();
   pLock = pFile->pLock;
   assert( pLock->cnt!=0 );
   if( pFile->locktype>SHARED_LOCK ){
@@ -1656,7 +1626,7 @@ static int unixUnlock(sqlite3_file *id, int locktype){
       pOpen->aPending = 0;
     }
   }
-  sqlite3OsLeaveMutex();
+  leaveMutex();
   pFile->locktype = locktype;
   return rc;
 }
@@ -1670,7 +1640,7 @@ static int unixClose(sqlite3_file *id){
   unixUnlock(id, NO_LOCK);
   if( pFile->dirfd>=0 ) close(pFile->dirfd);
   pFile->dirfd = -1;
-  sqlite3OsEnterMutex();
+  enterMutex();
 
   if( pFile->pOpen->nLock ){
     /* If there are outstanding locks, do not actually close the file just
@@ -1695,11 +1665,11 @@ static int unixClose(sqlite3_file *id){
   releaseLockInfo(pFile->pLock);
   releaseOpenCnt(pFile->pOpen);
 
-  sqlite3OsLeaveMutex();
+  leaveMutex();
   pFile->isOpen = 0;
   OSTRACE2("CLOSE   %-3d\n", pFile->h);
   OpenCounter(-1);
-  sqlite3_free(id);
+  memset(pFile, 0, sizeof(unixFile));
   return SQLITE_OK;
 }
 
@@ -1806,7 +1776,7 @@ static int afpUnixLock(OsFile *id, int locktype)
          locktypeName(locktype), locktypeName(pFile->locktype), getpid());  
   /* If there is already a lock of this type or more restrictive on the
     ** OsFile, do nothing. Don't use the afp_end_lock: exit path, as
-    ** sqlite3OsEnterMutex() hasn't been called yet.
+    ** enterMutex() hasn't been called yet.
     */
   if( pFile->locktype>=locktype ){
     OSTRACE3("LOCK    %d %s ok (already held)\n", pFile->h,
@@ -1822,13 +1792,13 @@ static int afpUnixLock(OsFile *id, int locktype)
   
   /* This mutex is needed because pFile->pLock is shared across threads
     */
-  sqlite3OsEnterMutex();
+  enterMutex();
 
   /* Make sure the current thread owns the pFile.
     */
   rc = transferOwnership(pFile);
   if( rc!=SQLITE_OK ){
-    sqlite3OsLeaveMutex();
+    leaveMutex();
     return rc;
   }
     
@@ -1915,7 +1885,7 @@ static int afpUnixLock(OsFile *id, int locktype)
   }
   
 afp_end_lock:
-    sqlite3OsLeaveMutex();
+    leaveMutex();
   OSTRACE4("LOCK    %d %s %s\n", pFile->h, locktypeName(locktype), 
          rc==SQLITE_OK ? "ok" : "failed");
   return rc;
@@ -1945,7 +1915,7 @@ static int afpUnixUnlock(OsFile *id, int locktype) {
   if( CHECK_THREADID(pFile) ){
     return SQLITE_MISUSE;
   }
-  sqlite3OsEnterMutex();
+  enterMutex();
   if( pFile->locktype>SHARED_LOCK ){
     if( locktype==SHARED_LOCK ){
       int failed = 0;
@@ -1989,7 +1959,7 @@ static int afpUnixUnlock(OsFile *id, int locktype) {
   }
   if (rc == SQLITE_OK)
     pFile->locktype = locktype;
-  sqlite3OsLeaveMutex();
+  leaveMutex();
   return rc;
 }
 
@@ -2103,10 +2073,10 @@ static int flockUnixClose(OsFile **pId) {
   
   if( id->dirfd>=0 ) close(id->dirfd);
   id->dirfd = -1;
-  sqlite3OsEnterMutex();
+  enterMutex();
   
   close(id->h);  
-  sqlite3OsLeaveMutex();
+  leaveMutex();
   id->isOpen = 0;
   OSTRACE2("CLOSE   %-3d\n", id->h);
   OpenCounter(-1);
@@ -2221,11 +2191,11 @@ static int dotlockUnixClose(OsFile **pId) {
   
   if( id->dirfd>=0 ) close(id->dirfd);
   id->dirfd = -1;
-  sqlite3OsEnterMutex();
+  enterMutex();
   
   close(id->h);
   
-  sqlite3OsLeaveMutex();
+  leaveMutex();
   id->isOpen = 0;
   OSTRACE2("CLOSE   %-3d\n", id->h);
   OpenCounter(-1);
@@ -2263,11 +2233,11 @@ static int nolockUnixClose(OsFile **pId) {
   if( !id ) return SQLITE_OK;
   if( id->dirfd>=0 ) close(id->dirfd);
   id->dirfd = -1;
-  sqlite3OsEnterMutex();
+  enterMutex();
   
   close(id->h);
   
-  sqlite3OsLeaveMutex();
+  leaveMutex();
   id->isOpen = 0;
   OSTRACE2("CLOSE   %-3d\n", id->h);
   OpenCounter(-1);
@@ -2278,56 +2248,6 @@ static int nolockUnixClose(OsFile **pId) {
 
 #endif /* SQLITE_ENABLE_LOCKING_STYLE */
 
-/*
-** Turn a relative pathname into a full pathname.  Return a pointer
-** to the full pathname stored in space obtained from sqliteMalloc().
-** The calling function is responsible for freeing this space once it
-** is no longer needed.
-*/
-char *sqlite3UnixFullPathname(const char *zRelative){
-  char *zFull = 0;
-  if( zRelative[0]=='/' ){
-    sqlite3SetString(&zFull, zRelative, (char*)0);
-  }else{
-    char *zBuf = sqlite3_malloc(5000);
-    if( zBuf==0 ){
-      return 0;
-    }
-    zBuf[0] = 0;
-    sqlite3SetString(&zFull, getcwd(zBuf, 5000), "/", zRelative,
-                    (char*)0);
-    sqlite3_free(zBuf);
-  }
-
-#if 0
-  /*
-  ** Remove "/./" path elements and convert "/A/./" path elements
-  ** to just "/".
-  */
-  if( zFull ){
-    int i, j;
-    for(i=j=0; zFull[i]; i++){
-      if( zFull[i]=='/' ){
-        if( zFull[i+1]=='/' ) continue;
-        if( zFull[i+1]=='.' && zFull[i+2]=='/' ){
-          i += 1;
-          continue;
-        }
-        if( zFull[i+1]=='.' && zFull[i+2]=='.' && zFull[i+3]=='/' ){
-          while( j>0 && zFull[j-1]!='/' ){ j--; }
-          i += 3;
-          continue;
-        }
-      }
-      zFull[j++] = zFull[i];
-    }
-    zFull[j] = 0;
-  }
-#endif
-
-  return zFull;
-}
-
 /*
 ** Change the value of the fullsync flag in the given file descriptor.
 */
@@ -2510,9 +2430,9 @@ static int allocateUnixFile(
   memset(&f, 0, sizeof(f));
   lockingStyle = sqlite3DetectLockingStyle(zFilename, h);
   if ( lockingStyle == posixLockingStyle ) {
-    sqlite3OsEnterMutex();
+    enterMutex();
     rc = findLockInfo(h, &f.pLock, &f.pOpen);
-    sqlite3OsLeaveMutex();
+    leaveMutex();
     if( rc ){
       close(h);
       unlink(zFilename);
@@ -2532,10 +2452,10 @@ static int allocateUnixFile(
   pNew = sqlite3_malloc( sizeof(unixFile) );
   if( pNew==0 ){
     close(h);
-    sqlite3OsEnterMutex();
+    enterMutex();
     releaseLockInfo(f.pLock);
     releaseOpenCnt(f.pOpen);
-    sqlite3OsLeaveMutex();
+    leaveMutex();
     *pId = 0;
     return SQLITE_NOMEM;
   }else{
@@ -2590,50 +2510,34 @@ static int allocateUnixFile(
   }
 }
 #else /* SQLITE_ENABLE_LOCKING_STYLE */
-static int allocateUnixFile(
+static int fillInUnixFile(
   int h,                 /* Open file descriptor on file being opened */
-  sqlite3_file **pId,    /* Write the resul unixFile structure here */
-  const char *zFilename, /* Name of the file being opened */
-  int delFlag            /* If true, delete the file on or before closing */
+  sqlite3_file *pId,     /* Write to the unixFile structure here */
+  const char *zFilename  /* Name of the file being opened */
 ){
-  unixFile *pNew;
-  unixFile f;
+  unixFile *pNew = (unixFile *)pId;
   int rc;
 
 #ifdef FD_CLOEXEC
   fcntl(h, F_SETFD, fcntl(h, F_GETFD, 0) | FD_CLOEXEC);
 #endif
-  memset(&f, 0, sizeof(f));
-  sqlite3OsEnterMutex();
-  rc = findLockInfo(h, &f.pLock, &f.pOpen);
-  sqlite3OsLeaveMutex();
-  if( delFlag ){
-    unlink(zFilename);
-  }
+
+  enterMutex();
+  rc = findLockInfo(h, &pNew->pLock, &pNew->pOpen);
+  leaveMutex();
   if( rc ){
     close(h);
     return SQLITE_NOMEM;
   }
+
   OSTRACE3("OPEN    %-3d %s\n", h, zFilename);
-  f.dirfd = -1;
-  f.h = h;
-  SET_THREADID(&f);
-  pNew = sqlite3_malloc( sizeof(unixFile) );
-  if( pNew==0 ){
-    close(h);
-    sqlite3OsEnterMutex();
-    releaseLockInfo(f.pLock);
-    releaseOpenCnt(f.pOpen);
-    sqlite3OsLeaveMutex();
-    *pId = 0;
-    return SQLITE_NOMEM;
-  }else{
-    *pNew = f;
-    pNew->pMethod = &sqlite3UnixIoMethod;
-    *pId = (sqlite3_file*)pNew;
-    OpenCounter(+1);
-    return SQLITE_OK;
-  }
+  pNew->dirfd = -1;
+  pNew->h = h;
+  SET_THREADID(pNew);
+
+  pNew->pMethod = &sqlite3UnixIoMethod;
+  OpenCounter(+1);
+  return SQLITE_OK;
 }
 #endif /* SQLITE_ENABLE_LOCKING_STYLE */
 
@@ -2643,6 +2547,199 @@ static int allocateUnixFile(
 ** with other miscellanous aspects of the operating system interface
 ****************************************************************************/
 
+/*
+** Previously, the SQLite OS layer used three functions in place of this
+** one:
+**
+**     sqlite3OsOpenReadWrite();
+**     sqlite3OsOpenReadOnly();
+**     sqlite3OsOpenExclusive();
+**
+** These calls correspond to the following combinations of flags:
+**
+**     ReadWrite() ->     (READWRITE | CREATE)
+**     ReadOnly()  ->     (READONLY) 
+**     OpenExclusive() -> (READWRITE | CREATE | EXCLUSIVE)
+**
+** The old OpenExclusive() accepted a boolean argument - "delFlag". If
+** true, the file was configured to be automatically deleted when the
+** file handle closed. To achieve the same effect using this new 
+** interface, add the DELETEONCLOSE flag to those specified above for 
+** OpenExclusive().
+*/
+static int unixOpen(
+  void *pNotUsed, 
+  const char *zPath, 
+  sqlite3_file *pFile,
+  int flags,
+  int *pOutFlags
+){
+  int fd = 0;
+  int oflags = 0;
+
+  int isExclusive  = (flags & SQLITE_OPEN_EXCLUSIVE);
+  int isDelete     = (flags & SQLITE_OPEN_DELETEONCLOSE);
+  int isCreate     = (flags & SQLITE_OPEN_CREATE);
+  int isReadonly   = (flags & SQLITE_OPEN_READONLY);
+  int isReadWrite  = (flags & SQLITE_OPEN_READWRITE);
+
+  /* Exactly one of the READWRITE and READONLY flags must be set */
+  assert((isReadonly==0 || isReadWrite==0) && (isReadWrite || isReadonly));
+
+  /* If isCreate is true, then the file must be opened for read/write access. */
+  assert(isCreate==0 || isReadWrite);
+
+  /* If isExclusive is true, then isCreate must also be true */
+  assert(isExclusive==0 || isCreate);
+
+  if( isReadonly )  oflags |= O_RDONLY;
+  if( isReadWrite ) oflags |= O_RDWR;
+  if( isCreate )    oflags |= O_CREAT;
+  if( isExclusive ) oflags |= (O_EXCL|O_NOFOLLOW);
+  oflags |= (O_LARGEFILE|O_BINARY);
+
+  memset(pFile, 0, sizeof(unixFile));
+  fd = open(zPath, oflags, isDelete?0600:SQLITE_DEFAULT_FILE_PERMISSIONS);
+  if( fd<0 && isReadWrite && !isExclusive ){
+    /* Failed to open the file for read/write access. Try read-only. */
+    flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
+    flags |= SQLITE_OPEN_READONLY;
+    return unixOpen(pNotUsed, zPath, pFile, flags, pOutFlags);
+  }
+  if( fd<0 ){
+    return SQLITE_CANTOPEN;
+  }
+  if( isDelete ){
+    unlink(zPath);
+  }
+  if( pOutFlags ){
+    *pOutFlags = flags;
+  }
+
+  assert(fd!=0);
+  return fillInUnixFile(fd, pFile, zPath);
+}
+
+/*
+** Delete the file at zPath.
+*/
+static int unixDelete(void *pNotUsed, const char *zPath){
+  SimulateIOError(return SQLITE_IOERR_DELETE);
+  unlink(zPath);
+  return SQLITE_OK;
+}
+
+static int unixAccess(void *pNotUsed, const char *zPath, int flags){
+  int amode;
+  switch( flags ){
+    case SQLITE_ACCESS_EXISTS:
+      amode = F_OK;
+      break;
+    case SQLITE_ACCESS_READWRITE:
+      amode = W_OK|R_OK;
+      break;
+    case SQLITE_ACCESS_READONLY:
+      amode = R_OK;
+      break;
+
+    default:
+      assert(!"Invalid flags argument");
+  }
+  return (access(zPath, amode)==0);
+}
+
+/*
+** Create a temporary file name in zBuf.  zBuf must be big enough to
+** hold at least MAX_PATHNAME characters.
+*/
+static int unixGetTempName(void *pNotUsed, char *zBuf){
+  static const char *azDirs[] = {
+     0,
+     "/var/tmp",
+     "/usr/tmp",
+     "/tmp",
+     ".",
+  };
+  static const unsigned char zChars[] =
+    "abcdefghijklmnopqrstuvwxyz"
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+    "0123456789";
+  int i, j;
+  struct stat buf;
+  const char *zDir = ".";
+  azDirs[0] = sqlite3_temp_directory;
+  for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); i++){
+    if( azDirs[i]==0 ) continue;
+    if( stat(azDirs[i], &buf) ) continue;
+    if( !S_ISDIR(buf.st_mode) ) continue;
+    if( access(azDirs[i], 07) ) continue;
+    zDir = azDirs[i];
+    break;
+  }
+  do{
+    sqlite3_snprintf(MAX_PATHNAME-17, zBuf, "%s/"TEMP_FILE_PREFIX, zDir);
+    j = strlen(zBuf);
+    sqlite3Randomness(15, &zBuf[j]);
+    for(i=0; i<15; i++, j++){
+      zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
+    }
+    zBuf[j] = 0;
+  }while( access(zBuf,0)==0 );
+  return SQLITE_OK;
+}
+
+
+/*
+** Turn a relative pathname into a full pathname. The relative path
+** is stored as a nul-terminated string in the buffer pointed to by
+** zPath. 
+**
+** zOut points to a buffer of at least sqlite3_vfs.mxPathname bytes 
+** (in this case, MAX_PATHNAME bytes). The full-path is written to
+** this buffer before returning.
+*/
+static int unixFullPathname(void *pNotUsed, const char *zPath, char *zOut){
+  zOut[MAX_PATHNAME-1] = '\0';
+  if( zPath[0]=='/' ){
+    strncpy(zOut, zPath, MAX_PATHNAME-1);
+  }else{
+    int nCwd;
+    if( getcwd(zOut, MAX_PATHNAME-1)==0 ){
+      return SQLITE_ERROR;
+    }
+    nCwd = strlen(zOut);
+    zOut[nCwd] = '/';
+    strncpy(&zOut[nCwd+1], zPath, MAX_PATHNAME-1-nCwd-1);
+  }
+  return SQLITE_OK;
+
+#if 0
+  /*
+  ** Remove "/./" path elements and convert "/A/./" path elements
+  ** to just "/".
+  */
+  if( zFull ){
+    int i, j;
+    for(i=j=0; zFull[i]; i++){
+      if( zFull[i]=='/' ){
+        if( zFull[i+1]=='/' ) continue;
+        if( zFull[i+1]=='.' && zFull[i+2]=='/' ){
+          i += 1;
+          continue;
+        }
+        if( zFull[i+1]=='.' && zFull[i+2]=='.' && zFull[i+3]=='/' ){
+          while( j>0 && zFull[j-1]!='/' ){ j--; }
+          i += 3;
+          continue;
+        }
+      }
+      zFull[j++] = zFull[i];
+    }
+    zFull[j] = 0;
+  }
+#endif
+}
+
 
 #ifndef SQLITE_OMIT_LOAD_EXTENSION
 /*
@@ -2650,23 +2747,46 @@ static int allocateUnixFile(
 ** within the shared library, and closing the shared library.
 */
 #include <dlfcn.h>
-void *sqlite3UnixDlopen(const char *zFilename){
+static void *unixDlOpen(void *pNotUsed, const char *zFilename){
   return dlopen(zFilename, RTLD_NOW | RTLD_GLOBAL);
 }
-void *sqlite3UnixDlsym(void *pHandle, const char *zSymbol){
+static void unixDlError(void *pNotUsed, int nBuf, char *zBufOut){
+  char *zErr;
+  enterMutex();
+  zErr = dlerror();
+  if( zErr ){
+    strncpy(zBufOut, zErr, nBuf-1);
+    zBufOut[nBuf-1] = '\0';
+  }else if(nBuf>0) {
+    zBufOut[0] = '\0';
+  }
+  leaveMutex();
+}
+void *unixDlSym(void *pHandle, const char *zSymbol){
   return dlsym(pHandle, zSymbol);
 }
-int sqlite3UnixDlclose(void *pHandle){
-  return dlclose(pHandle);
+void unixDlClose(void *pHandle){
+  dlclose(pHandle);
 }
-#endif /* SQLITE_OMIT_LOAD_EXTENSION */
+#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
+  #define unixDlOpen  0
+  #define unixDlError 0
+  #define unixDlSym   0
+  #define unixDlClose 0
+#endif
+
+/*
+** Both arguments are integers. This macro returns the lowest of the 
+** two arguments. 
+*/
+#define MIN(x,y) ((x)>(y)?(y):(x))
 
 /*
 ** Get information to seed the random number generator.  The seed
 ** is written into the buffer zBuf[256].  The calling function must
 ** supply a sufficiently large buffer.
 */
-int sqlite3UnixRandomSeed(char *zBuf){
+static int unixRandomness(void *pNotUsed, int nBuf, char *zBuf){
   /* We have to initialize zBuf to prevent valgrind from reporting
   ** errors.  The reports issued by valgrind are incorrect - we would
   ** prefer that the randomness be increased by making use of the
@@ -2679,7 +2799,7 @@ int sqlite3UnixRandomSeed(char *zBuf){
   ** that we always use the same random number sequence.  This makes the
   ** tests repeatable.
   */
-  memset(zBuf, 0, 256);
+  memset(zBuf, 0, nBuf);
 #if !defined(SQLITE_TEST)
   {
     int pid, fd;
@@ -2687,11 +2807,13 @@ int sqlite3UnixRandomSeed(char *zBuf){
     if( fd<0 ){
       time_t t;
       time(&t);
-      memcpy(zBuf, &t, sizeof(t));
-      pid = getpid();
-      memcpy(&zBuf[sizeof(time_t)], &pid, sizeof(pid));
+      memcpy(zBuf, &t, MIN(nBuf, sizeof(t)));
+      if( (nBuf-sizeof(t))>0 ){
+        pid = getpid();
+        memcpy(&zBuf[sizeof(t)], &pid, MIN(nBuf-sizeof(t), sizeof(pid)));
+      }
     }else{
-      read(fd, zBuf, 256);
+      read(fd, zBuf, nBuf);
       close(fd);
     }
   }
@@ -2699,120 +2821,19 @@ int sqlite3UnixRandomSeed(char *zBuf){
   return SQLITE_OK;
 }
 
+
 /*
 ** Sleep for a little while.  Return the amount of time slept.
-** The argument is the number of milliseconds we want to sleep.
+** The argument is the number of microseconds we want to sleep.
 */
-int sqlite3UnixSleep(int ms){
+static int unixSleep(void *pNotUsed, int microseconds){
 #if defined(HAVE_USLEEP) && HAVE_USLEEP
-  usleep(ms*1000);
-  return ms;
-#else
-  sleep((ms+999)/1000);
-  return 1000*((ms+999)/1000);
-#endif
-}
-
-/*
-** Static variables used for thread synchronization.
-**
-** inMutex      the nesting depth of the recursive mutex.  The thread
-**              holding mutexMain can read this variable at any time.
-**              But is must hold mutexAux to change this variable.  Other
-**              threads must hold mutexAux to read the variable and can
-**              never write.
-**
-** mutexOwner   The thread id of the thread holding mutexMain.  Same
-**              access rules as for inMutex.
-**
-** mutexOwnerValid   True if the value in mutexOwner is valid.  The same
-**                   access rules apply as for inMutex.
-**
-** mutexMain    The main mutex.  Hold this mutex in order to get exclusive
-**              access to SQLite data structures.
-**
-** mutexAux     An auxiliary mutex needed to access variables defined above.
-**
-** Mutexes are always acquired in this order: mutexMain mutexAux.   It
-** is not necessary to acquire mutexMain in order to get mutexAux - just
-** do not attempt to acquire them in the reverse order: mutexAux mutexMain.
-** Either get the mutexes with mutexMain first or get mutexAux only.
-**
-** When running on a platform where the three variables inMutex, mutexOwner,
-** and mutexOwnerValid can be set atomically, the mutexAux is not required.
-** On many systems, all three are 32-bit integers and writing to a 32-bit
-** integer is atomic.  I think.  But there are no guarantees.  So it seems
-** safer to protect them using mutexAux.
-*/
-static int inMutex = 0;
-#ifdef SQLITE_UNIX_THREADS
-static pthread_t mutexOwner;          /* Thread holding mutexMain */
-static int mutexOwnerValid = 0;       /* True if mutexOwner is valid */
-static pthread_mutex_t mutexMain = PTHREAD_MUTEX_INITIALIZER; /* The mutex */
-static pthread_mutex_t mutexAux = PTHREAD_MUTEX_INITIALIZER;  /* Aux mutex */
-#endif
-
-/*
-** The following pair of routine implement mutual exclusion for
-** multi-threaded processes.  Only a single thread is allowed to
-** executed code that is surrounded by EnterMutex() and LeaveMutex().
-**
-** SQLite uses only a single Mutex.  There is not much critical
-** code and what little there is executes quickly and without blocking.
-**
-** As of version 3.3.2, this mutex must be recursive.
-*/
-void sqlite3UnixEnterMutex(){
-#ifdef SQLITE_UNIX_THREADS
-  pthread_mutex_lock(&mutexAux);
-  if( !mutexOwnerValid || !pthread_equal(mutexOwner, pthread_self()) ){
-    pthread_mutex_unlock(&mutexAux);
-    pthread_mutex_lock(&mutexMain);
-    assert( inMutex==0 );
-    assert( !mutexOwnerValid );
-    pthread_mutex_lock(&mutexAux);
-    mutexOwner = pthread_self();
-    mutexOwnerValid = 1;
-  }
-  inMutex++;
-  pthread_mutex_unlock(&mutexAux);
+  usleep(microseconds);
+  return microseconds;
 #else
-  inMutex++;
-#endif
-}
-void sqlite3UnixLeaveMutex(){
-  assert( inMutex>0 );
-#ifdef SQLITE_UNIX_THREADS
-  pthread_mutex_lock(&mutexAux);
-  inMutex--;
-  assert( pthread_equal(mutexOwner, pthread_self()) );
-  if( inMutex==0 ){
-    assert( mutexOwnerValid );
-    mutexOwnerValid = 0;
-    pthread_mutex_unlock(&mutexMain);
-  }
-  pthread_mutex_unlock(&mutexAux);
-#else
-  inMutex--;
-#endif
-}
-
-/*
-** Return TRUE if the mutex is currently held.
-**
-** If the thisThrd parameter is true, return true only if the
-** calling thread holds the mutex.  If the parameter is false, return
-** true if any thread holds the mutex.
-*/
-int sqlite3UnixInMutex(int thisThrd){
-#ifdef SQLITE_UNIX_THREADS
-  int rc;
-  pthread_mutex_lock(&mutexAux);
-  rc = inMutex>0 && (thisThrd==0 || pthread_equal(mutexOwner,pthread_self()));
-  pthread_mutex_unlock(&mutexAux);
-  return rc;
-#else
-  return inMutex>0;
+  int seconds = (microseconds+999999)/1000000;
+  sleep(seconds);
+  return seconds;
 #endif
 }
 
@@ -2829,7 +2850,7 @@ int sqlite3_current_time = 0;
 ** current time and date as a Julian Day number into *prNow and
 ** return 0.  Return 1 if the time and date cannot be found.
 */
-int sqlite3UnixCurrentTime(double *prNow){
+static int unixCurrentTime(void *pNotUsed, double *prNow){
 #ifdef NO_GETTOD
   time_t t;
   time(&t);
@@ -2846,5 +2867,31 @@ int sqlite3UnixCurrentTime(double *prNow){
 #endif
   return 0;
 }
+
+
+sqlite3_vfs sqlite3DefaultVfs = {
+  1,                  /* iVersion */
+  sizeof(unixFile),   /* szOsFile */
+  MAX_PATHNAME,       /* mxPathname */
+  0,                  /* nRef */
+  0,                  /* vfsMutex */
+  0,                  /* pNext */
+  0,                  /* pPrev */
+  "unix",             /* zName */
+  0,                  /* pAppData */
+
+  unixOpen,           /* xOpen */
+  unixDelete,         /* xDelete */
+  unixAccess,         /* xAccess */
+  unixGetTempName,    /* xGetTempName */
+  unixFullPathname,   /* xFullPathname */
+  unixDlOpen,         /* xDlOpen */
+  unixDlError,        /* xDlError */
+  unixDlSym,          /* xDlSym */
+  unixDlClose,        /* xDlClose */
+  unixRandomness,     /* xRandomness */
+  unixSleep,          /* xSleep */
+  unixCurrentTime     /* xCurrentTime */
+};
  
 #endif /* OS_UNIX */
index 418b13ef142ef23260f61ff41c0b4b2b47c8768d..5fbedba319ddadf58359f6a5f61c19618b589c9a 100644 (file)
@@ -18,7 +18,7 @@
 ** file simultaneously, or one process from reading the database while
 ** another is writing.
 **
-** @(#) $Id: pager.c,v 1.358 2007/08/16 10:09:03 danielk1977 Exp $
+** @(#) $Id: pager.c,v 1.359 2007/08/17 15:53:37 danielk1977 Exp $
 */
 #ifndef SQLITE_OMIT_DISKIO
 #include "sqliteInt.h"
@@ -297,6 +297,7 @@ struct PgHistory {
 ** APIs, they may still be used successfully.
 */
 struct Pager {
+  sqlite3_vfs *pVfs;          /* OS functions to use for IO */
   u8 journalOpen;             /* True if journal file descriptors is valid */
   u8 journalStarted;          /* True if header of journal is synced */
   u8 useJournal;              /* Use a rollback journal on this file */
@@ -1011,7 +1012,7 @@ static int pager_end_transaction(Pager *pPager){
   }
   sqlite3PagerStmtCommit(pPager);
   if( pPager->stmtOpen && !pPager->exclusiveMode ){
-    sqlite3OsClose(&pPager->stfd);
+    sqlite3OsClose(pPager->stfd);
     pPager->stmtOpen = 0;
   }
   if( pPager->journalOpen ){
@@ -1020,10 +1021,10 @@ static int pager_end_transaction(Pager *pPager){
       pPager->journalOff = 0;
       pPager->journalStarted = 0;
     }else{
-      sqlite3OsClose(&pPager->jfd);
+      sqlite3OsClose(pPager->jfd);
       pPager->journalOpen = 0;
       if( rc==SQLITE_OK ){
-        rc = sqlite3OsDelete(pPager->zJournal);
+        rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal);
       }
     }
     sqlite3_free( pPager->aInJournal );
@@ -1225,21 +1226,29 @@ static int pager_playback_one_page(
 ** children.  If all children are either missing or do not refer to
 ** a different master journal, then this master journal can be deleted.
 */
-static int pager_delmaster(const char *zMaster){
+static int pager_delmaster(Pager *pPager, const char *zMaster){
+  sqlite3_vfs *pVfs = pPager->pVfs;
   int rc;
   int master_open = 0;
-  sqlite3_file *master = 0;
+  sqlite3_file *pMaster;
+  sqlite3_file *pJournal;
   char *zMasterJournal = 0; /* Contents of master journal file */
   i64 nMasterJournal;       /* Size of master journal file */
 
   /* Open the master journal file exclusively in case some other process
   ** is running this routine also. Not that it makes too much difference.
   */
-  rc = sqlite3OsOpenReadOnly(zMaster, &master);
-  assert( rc!=SQLITE_OK || master );
+  pMaster = (sqlite3_file *)sqlite3_malloc(pVfs->szOsFile * 2);
+  if( !pMaster ){
+    rc = SQLITE_NOMEM;
+  }else{
+    pJournal = (sqlite3_file *)(((u8 *)pMaster) + pVfs->szOsFile);
+    rc = sqlite3OsOpen(pVfs, zMaster, pMaster, SQLITE_OPEN_READONLY, 0);
+  }
   if( rc!=SQLITE_OK ) goto delmaster_out;
   master_open = 1;
-  rc = sqlite3OsFileSize(master, &nMasterJournal);
+
+  rc = sqlite3OsFileSize(pMaster, &nMasterJournal);
   if( rc!=SQLITE_OK ) goto delmaster_out;
 
   if( nMasterJournal>0 ){
@@ -1254,27 +1263,25 @@ static int pager_delmaster(const char *zMaster){
       rc = SQLITE_NOMEM;
       goto delmaster_out;
     }
-    rc = sqlite3OsRead(master, zMasterJournal, nMasterJournal, 0);
+    rc = sqlite3OsRead(pMaster, zMasterJournal, nMasterJournal, 0);
     if( rc!=SQLITE_OK ) goto delmaster_out;
 
     zJournal = zMasterJournal;
     while( (zJournal-zMasterJournal)<nMasterJournal ){
-      if( sqlite3OsFileExists(zJournal) ){
+      if( sqlite3OsAccess(pVfs, zJournal, SQLITE_ACCESS_EXISTS) ){
         /* One of the journals pointed to by the master journal exists.
         ** Open it and check if it points at the master journal. If
         ** so, return without deleting the master journal file.
         */
-        sqlite3_file *journal = 0;
         int c;
 
-        rc = sqlite3OsOpenReadOnly(zJournal, &journal);
-        assert( rc!=SQLITE_OK || journal );
+        rc = sqlite3OsOpen(pVfs, zJournal, pJournal, SQLITE_OPEN_READONLY, 0);
         if( rc!=SQLITE_OK ){
           goto delmaster_out;
         }
 
-        rc = readMasterJournal(journal, &zMasterPtr);
-        sqlite3OsClose(&journal);
+        rc = readMasterJournal(pJournal, &zMasterPtr);
+        sqlite3OsClose(pJournal);
         if( rc!=SQLITE_OK ){
           goto delmaster_out;
         }
@@ -1290,15 +1297,16 @@ static int pager_delmaster(const char *zMaster){
     }
   }
   
-  rc = sqlite3OsDelete(zMaster);
+  rc = sqlite3OsDelete(pVfs, zMaster);
 
 delmaster_out:
   if( zMasterJournal ){
     sqlite3_free(zMasterJournal);
   }  
   if( master_open ){
-    sqlite3OsClose(&master);
+    sqlite3OsClose(pMaster);
   }
+  sqlite3_free(pMaster);
   return rc;
 }
 
@@ -1388,6 +1396,7 @@ static void setSectorSize(Pager *pPager){
 ** and an error code is returned.
 */
 static int pager_playback(Pager *pPager, int isHot){
+  sqlite3_vfs *pVfs = pPager->pVfs;
   i64 szJ;                 /* Size of the journal file in bytes */
   u32 nRec;                /* Number of Records in the journal */
   int i;                   /* Loop counter */
@@ -1411,7 +1420,9 @@ static int pager_playback(Pager *pPager, int isHot){
   */
   rc = readMasterJournal(pPager->jfd, &zMaster);
   assert( rc!=SQLITE_DONE );
-  if( rc!=SQLITE_OK || (zMaster && !sqlite3OsFileExists(zMaster)) ){
+  if( rc!=SQLITE_OK 
+   || (zMaster && !sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS)) 
+  ){
     sqlite3_free(zMaster);
     zMaster = 0;
     if( rc==SQLITE_DONE ) rc = SQLITE_OK;
@@ -1496,7 +1507,7 @@ end_playback:
     ** see if it is possible to delete the master journal.
     */
     if( rc==SQLITE_OK ){
-      rc = pager_delmaster(zMaster);
+      rc = pager_delmaster(pPager, zMaster);
     }
     sqlite3_free(zMaster);
   }
@@ -1681,20 +1692,36 @@ int sqlite3_opentemp_count = 0;
 ** The OS will automatically delete the temporary file when it is
 ** closed.
 */
-static int sqlite3PagerOpentemp(sqlite3_file **pFd){
+static int sqlite3PagerOpentemp(
+  sqlite3_vfs *pVfs, 
+  sqlite3_file *pFile, 
+  char *zNameOut
+){
   int cnt = 8;
   int rc;
-  char zFile[SQLITE_TEMPNAME_SIZE];
+  int flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_EXCLUSIVE);
+
+  char *zFree = 0;
+  if( zNameOut==0 ){
+    zFree = (char *)sqlite3_malloc(pVfs->mxPathname);
+    if( !zFree ){
+      return SQLITE_NOMEM;
+    }
+    zNameOut = zFree;
+  }
 
 #ifdef SQLITE_TEST
   sqlite3_opentemp_count++;  /* Used for testing and analysis only */
 #endif
+
   do{
     cnt--;
-    sqlite3OsTempFileName(zFile);
-    rc = sqlite3OsOpenExclusive(zFile, pFd, 1);
-    assert( rc!=SQLITE_OK || *pFd );
+    sqlite3OsGetTempName(pVfs, zNameOut);
+    rc = sqlite3OsOpen(pVfs, zNameOut, pFile, flags, 0);
+    assert( rc!=SQLITE_OK || pFile->pMethods );
   }while( cnt>0 && rc!=SQLITE_OK && rc!=SQLITE_NOMEM );
+
+  sqlite3_free(zFree);
   return rc;
 }
 
@@ -1713,15 +1740,15 @@ static int sqlite3PagerOpentemp(sqlite3_file **pFd){
 ** in-memory database.
 */
 int sqlite3PagerOpen(
+  sqlite3_vfs *pVfs,
   Pager **ppPager,         /* Return the Pager structure here */
   const char *zFilename,   /* Name of the database file to open */
   int nExtra,              /* Extra bytes append to each in-memory page */
   int flags                /* flags controlling this file */
 ){
+  u8 *pPtr;
   Pager *pPager = 0;
   char *zFullPathname = 0;
-  int nameLen;  /* Compiler is wrong. This is always initialized before use */
-  sqlite3_file *fd = 0;
   int rc = SQLITE_OK;
   int i;
   int tempFile = 0;
@@ -1729,7 +1756,7 @@ int sqlite3PagerOpen(
   int readOnly = 0;
   int useJournal = (flags & PAGER_OMIT_JOURNAL)==0;
   int noReadlock = (flags & PAGER_NO_READLOCK)!=0;
-  char zTemp[SQLITE_TEMPNAME_SIZE];
+
 #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
   /* A malloc() cannot fail in sqlite3ThreadData() as one or more calls to 
   ** malloc() must have already been made by this thread before it gets
@@ -1750,6 +1777,24 @@ int sqlite3PagerOpen(
   */
   *ppPager = 0;
 
+  /* Allocate memory for the pager structure */
+  pPager = sqlite3MallocZero(
+    sizeof(*pPager) +           /* Pager structure */
+    pVfs->szOsFile * 3 +        /* The db, journal and stmt journal files */ 
+    pVfs->mxPathname * 3 + 30   /* zFilename, zDirectory, zJournal */
+  );
+  if( !pPager ){
+    return SQLITE_NOMEM;
+  }
+  pPtr = (u8 *)&pPager[1];
+  pPager->fd = (sqlite3_file*)&pPtr[pVfs->szOsFile*0];
+  pPager->jfd = (sqlite3_file*)&pPtr[pVfs->szOsFile*1];
+  pPager->stfd = (sqlite3_file*)&pPtr[pVfs->szOsFile*2];
+  pPager->zFilename = (char*)&pPtr[pVfs->szOsFile*3];
+  pPager->zDirectory = &pPager->zFilename[pVfs->mxPathname];
+  pPager->zJournal = &pPager->zDirectory[pVfs->mxPathname];
+  pPager->pVfs = pVfs;
+
   /* Open the pager file and set zFullPathname to point at malloc()ed 
   ** memory containing the complete filename (i.e. including the directory).
   */
@@ -1757,65 +1802,56 @@ int sqlite3PagerOpen(
 #ifndef SQLITE_OMIT_MEMORYDB
     if( strcmp(zFilename,":memory:")==0 ){
       memDb = 1;
-      zFullPathname = sqlite3StrDup("");
+      pPager->zFilename[0] = '\0';
     }else
 #endif
     {
-      zFullPathname = sqlite3OsFullPathname(zFilename);
-      if( zFullPathname ){
-        rc = sqlite3OsOpenReadWrite(zFullPathname, &fd, &readOnly);
-        assert( rc!=SQLITE_OK || fd );
+      rc = sqlite3OsFullPathname(pVfs, zFilename, pPager->zFilename);
+      if( rc==SQLITE_OK ){
+        if( strlen(pPager->zFilename)>(pVfs->mxPathname - strlen("-journal")) ){
+          rc = SQLITE_CANTOPEN;
+        }else{
+          int flag = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
+          int fout = 0;
+          rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, flag, &fout);
+          readOnly = (fout&SQLITE_OPEN_READONLY);
+        }
       }
     }
   }else{
-    rc = sqlite3PagerOpentemp(&fd);
-    sqlite3OsTempFileName(zTemp);
-    zFilename = zTemp;
-    zFullPathname = sqlite3OsFullPathname(zFilename);
+    rc = sqlite3PagerOpentemp(pVfs, pPager->fd, pPager->zFilename);
     if( rc==SQLITE_OK ){
       tempFile = 1;
     }
   }
 
-  /* Allocate the Pager structure. As part of the same allocation, allocate
-  ** space for the full paths of the file, directory and journal 
-  ** (Pager.zFilename, Pager.zDirectory and Pager.zJournal).
-  */
-  if( zFullPathname ){
-    nameLen = strlen(zFullPathname);
-    pPager = sqlite3MallocZero( sizeof(*pPager) + nameLen*3 + 30 );
-    if( pPager && rc==SQLITE_OK ){
-      pPager->pTmpSpace = (char *)sqlite3_malloc(SQLITE_DEFAULT_PAGE_SIZE);
-    }
+  if( pPager && rc==SQLITE_OK ){
+    pPager->pTmpSpace = (char *)sqlite3_malloc(SQLITE_DEFAULT_PAGE_SIZE);
   }
 
-
   /* If an error occured in either of the blocks above, free the memory 
   ** pointed to by zFullPathname, free the Pager structure and close the 
   ** file. Since the pager is not allocated there is no need to set 
   ** any Pager.errMask variables.
   */
-  if( !pPager || !zFullPathname || !pPager->pTmpSpace || rc!=SQLITE_OK ){
-    sqlite3OsClose(&fd);
-    sqlite3_free(zFullPathname);
+  if( !pPager || !pPager->pTmpSpace ){
+    sqlite3OsClose(pPager->fd);
     sqlite3_free(pPager);
     return ((rc==SQLITE_OK)?SQLITE_NOMEM:rc);
   }
 
   PAGERTRACE3("OPEN %d %s\n", FILEHANDLEID(fd), zFullPathname);
   IOTRACE(("OPEN %p %s\n", pPager, zFullPathname))
-  pPager->zFilename = (char*)&pPager[1];
-  pPager->zDirectory = &pPager->zFilename[nameLen+1];
-  pPager->zJournal = &pPager->zDirectory[nameLen+1];
-  memcpy(pPager->zFilename, zFullPathname, nameLen+1);
-  memcpy(pPager->zDirectory, zFullPathname, nameLen+1);
 
-  for(i=nameLen; i>0 && pPager->zDirectory[i-1]!='/'; i--){}
+  /* Fill in Pager.zDirectory[] */
+  memcpy(pPager->zDirectory, pPager->zFilename, pVfs->mxPathname);
+  for(i=strlen(pPager->zDirectory); i>0 && pPager->zDirectory[i-1]!='/'; i--){}
   if( i>0 ) pPager->zDirectory[i-1] = 0;
-  memcpy(pPager->zJournal, zFullPathname,nameLen);
-  sqlite3_free(zFullPathname);
-  memcpy(&pPager->zJournal[nameLen], "-journal",sizeof("-journal"));
-  pPager->fd = fd;
+
+  /* Fill in Pager.zJournal[] */
+  memcpy(pPager->zJournal, pPager->zFilename, pVfs->mxPathname);
+  memcpy(&pPager->zJournal[strlen(pPager->zJournal)], "-journal", 9);
+
   /* pPager->journalOpen = 0; */
   pPager->useJournal = useJournal && !memDb;
   pPager->noReadlock = noReadlock && readOnly;
@@ -1846,7 +1882,7 @@ int sqlite3PagerOpen(
   /* pPager->pFirstSynced = 0; */
   /* pPager->pLast = 0; */
   pPager->nExtra = FORCE_ALIGNMENT(nExtra);
-  assert(fd||memDb);
+  assert(pPager->fd->pMethods||memDb);
   if( !memDb ){
     setSectorSize(pPager);
   }
@@ -2229,13 +2265,13 @@ int sqlite3PagerClose(Pager *pPager){
   IOTRACE(("CLOSE %p\n", pPager))
   assert( pPager->errCode || (pPager->journalOpen==0 && pPager->stmtOpen==0) );
   if( pPager->journalOpen ){
-    sqlite3OsClose(&pPager->jfd);
+    sqlite3OsClose(pPager->jfd);
   }
   sqlite3_free(pPager->aInJournal);
   if( pPager->stmtOpen ){
-    sqlite3OsClose(&pPager->stfd);
+    sqlite3OsClose(pPager->stfd);
   }
-  sqlite3OsClose(&pPager->fd);
+  sqlite3OsClose(pPager->fd);
   /* Temp files are automatically deleted by the OS
   ** if( pPager->tempFile ){
   **   sqlite3OsDelete(pPager->zFilename);
@@ -2579,15 +2615,16 @@ static PgHdr *pager_get_all_dirty_pages(Pager *pPager){
 ** database with the same name.  Just delete the journal.
 */
 static int hasHotJournal(Pager *pPager){
+  sqlite3_vfs *pVfs = pPager->pVfs;
   if( !pPager->useJournal ) return 0;
-  if( !sqlite3OsFileExists(pPager->zJournal) ){
+  if( !sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS) ){
     return 0;
   }
   if( sqlite3OsCheckReservedLock(pPager->fd) ){
     return 0;
   }
   if( sqlite3PagerPagecount(pPager)==0 ){
-    sqlite3OsDelete(pPager->zJournal);
+    sqlite3OsDelete(pVfs, pPager->zJournal);
     return 0;
   }else{
     return 1;
@@ -2702,9 +2739,11 @@ int sqlite3PagerReleaseMemory(int nReq){
   ** some of the code invoked by this function may also
   ** try to obtain the mutex, resulting in a deadlock.
   */
+#if 0
   if( sqlite3OsInMutex(0) ){
     return 0;
   }
+#endif
 
   /* Outermost loop runs for at most two iterations. First iteration we
   ** try to find memory that can be released without calling fsync(). Second
@@ -2817,6 +2856,7 @@ static int pagerSharedLock(Pager *pPager){
   int rc = SQLITE_OK;
 
   if( pPager->state==PAGER_UNLOCK ){
+    sqlite3_vfs *pVfs = pPager->pVfs;
     if( !MEMDB ){
       assert( pPager->nRef==0 );
       if( !pPager->noReadlock ){
@@ -2864,14 +2904,15 @@ static int pagerSharedLock(Pager *pPager){
         ** a read/write file handle.
         */
         rc = SQLITE_BUSY;
-        if( sqlite3OsFileExists(pPager->zJournal) ){
-          int ro;
+        if( sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS) ){
+          int fout = 0;
+          int flags = SQLITE_OPEN_READWRITE;
           assert( !pPager->tempFile );
-          rc = sqlite3OsOpenReadWrite(pPager->zJournal, &pPager->jfd, &ro);
-          assert( rc!=SQLITE_OK || pPager->jfd );
-          if( ro ){
+          rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, flags, &fout);
+          assert( rc!=SQLITE_OK || pPager->jfd->pMethods );
+          if( fout&SQLITE_OPEN_READONLY ){
             rc = SQLITE_BUSY;
-            sqlite3OsClose(&pPager->jfd);
+            sqlite3OsClose(pPager->jfd);
           }
         }
         if( rc!=SQLITE_OK ){
@@ -3294,6 +3335,9 @@ int sqlite3PagerUnref(DbPage *pPg){
 ** write lock if anything goes wrong.
 */
 static int pager_open_journal(Pager *pPager){
+  sqlite3_vfs *pVfs = pPager->pVfs;
+  int flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_EXCLUSIVE|SQLITE_OPEN_CREATE);
+
   int rc;
   assert( !MEMDB );
   assert( pPager->state>=PAGER_RESERVED );
@@ -3306,15 +3350,18 @@ static int pager_open_journal(Pager *pPager){
     rc = SQLITE_NOMEM;
     goto failed_to_open_journal;
   }
-  rc = sqlite3OsOpenExclusive(pPager->zJournal, &pPager->jfd,
-                                 pPager->tempFile);
-  assert( rc!=SQLITE_OK || pPager->jfd );
+
+  if( pPager->tempFile ){
+    flags |= SQLITE_OPEN_DELETEONCLOSE;
+  }
+  rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, flags, 0);
+  assert( rc!=SQLITE_OK || pPager->jfd->pMethods );
   pPager->journalOff = 0;
   pPager->setMaster = 0;
   pPager->journalHdr = 0;
   if( rc!=SQLITE_OK ){
     if( rc==SQLITE_NOMEM ){
-      sqlite3OsDelete(pPager->zJournal);
+      sqlite3OsDelete(pVfs, pPager->zJournal);
     }
     goto failed_to_open_journal;
   }
@@ -4180,7 +4227,7 @@ int sqlite3PagerStmtBegin(Pager *pPager){
   pPager->stmtHdrOff = 0;
   pPager->stmtCksum = pPager->cksumInit;
   if( !pPager->stmtOpen ){
-    rc = sqlite3PagerOpentemp(&pPager->stfd);
+    rc = sqlite3PagerOpentemp(pPager->pVfs, pPager->stfd, 0);
     if( rc ) goto stmt_begin_failed;
     pPager->stmtOpen = 1;
     pPager->stmtNRec = 0;
index ca193dae1d06091e2187a812a45a525f050c9019..554c4999adc79d6c3e610d7c70a2153e0eb59fdd 100644 (file)
@@ -13,7 +13,7 @@
 ** subsystem.  The page cache subsystem reads and writes a file a page
 ** at a time and provides a journal for rollback.
 **
-** @(#) $Id: pager.h,v 1.61 2007/05/08 21:45:28 drh Exp $
+** @(#) $Id: pager.h,v 1.62 2007/08/17 15:53:37 danielk1977 Exp $
 */
 
 #ifndef _PAGER_H_
@@ -54,8 +54,7 @@ typedef struct PgHdr DbPage;
 ** See source code comments for a detailed description of the following
 ** routines:
 */
-int sqlite3PagerOpen(Pager **ppPager, const char *zFilename,
-                     int nExtra, int flags);
+int sqlite3PagerOpen(sqlite3_vfs *, Pager **ppPager, const char *, int, int);
 void sqlite3PagerSetBusyhandler(Pager*, BusyHandler *pBusyHandler);
 void sqlite3PagerSetDestructor(Pager*, void(*)(DbPage*,int));
 void sqlite3PagerSetReiniter(Pager*, void(*)(DbPage*,int));
index 66edcee87b2710f3548bb29225f392a03c7bd240..f5ed28a4e089e9c0f4cbbea9a1e9e6e0bae27883 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** This file contains code used to implement the PRAGMA command.
 **
-** $Id: pragma.c,v 1.144 2007/08/16 10:09:03 danielk1977 Exp $
+** $Id: pragma.c,v 1.145 2007/08/17 15:53:37 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -557,7 +557,9 @@ void sqlite3Pragma(
         sqlite3VdbeAddOp(v, OP_Callback, 1, 0);
       }
     }else{
-      if( zRight[0] && !sqlite3OsIsDirWritable(zRight) ){
+      if( zRight[0] 
+       && !sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE) 
+      ){
         sqlite3ErrorMsg(pParse, "not a writable directory");
         goto pragma_out;
       }
index 03ed7a424b92cfca84b8906a190b9833898d59f6..27ee0e508ca7e147bb7537715b7707d822c3fc6d 100644 (file)
@@ -15,7 +15,7 @@
 ** Random numbers are used by some of the database backends in order
 ** to generate random integer keys for tables or random filenames.
 **
-** $Id: random.c,v 1.16 2007/01/05 14:38:56 drh Exp $
+** $Id: random.c,v 1.17 2007/08/17 15:53:37 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -63,7 +63,7 @@ static int randomByte(void){
     char k[256];
     prng.j = 0;
     prng.i = 0;
-    sqlite3OsRandomSeed(k);
+    sqlite3OsRandomness(sqlite3_find_vfs(0), 256, k);
     for(i=0; i<256; i++){
       prng.s[i] = i;
     }
@@ -92,9 +92,9 @@ static int randomByte(void){
 */
 void sqlite3Randomness(int N, void *pBuf){
   unsigned char *zBuf = pBuf;
-  sqlite3OsEnterMutex();
+  sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_PRNG));
   while( N-- ){
     *(zBuf++) = randomByte();
   }
-  sqlite3OsLeaveMutex();
+  sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_PRNG));
 }
index 8492399d2ebe3d4bffe1d2c0aa2577c824a81c8c..2378b7861ff99bcaa365655ddff1e9f56d316287 100644 (file)
@@ -30,7 +30,7 @@
 ** the version number) and changes its name to "sqlite3.h" as
 ** part of the build process.
 **
-** @(#) $Id: sqlite.h.in,v 1.227 2007/08/17 01:14:38 drh Exp $
+** @(#) $Id: sqlite.h.in,v 1.228 2007/08/17 15:53:37 danielk1977 Exp $
 */
 #ifndef _SQLITE3_H_
 #define _SQLITE3_H_
@@ -644,10 +644,10 @@ struct sqlite3_vfs {
   int (*xAccess)(void *pAppData, const char *zName, int flags);
   int (*xGetTempName)(void *pAppData, char *zOut);
   int (*xFullPathname)(void *pAppData, const char *zName, char *zOut);
-  void *(*xDlOpen)(void *pAppData, char *zFilename);
-  void (*xDlError)(void*, int nByte, char *zErrMsg);
+  void *(*xDlOpen)(void *pAppData, const char *zFilename);
+  void (*xDlError)(void *pAppData, int nByte, char *zErrMsg);
   void *(*xDlSym)(void*, const char *zSymbol);
-  void (*xDlclose)(void*);
+  void (*xDlClose)(void*);
   int (*xRandomness)(void *pAppData, int nByte, char *zOut);
   int (*xSleep)(void *pAppData, int microseconds);
   int (*xCurrentTime)(void *pAppData, double*);
@@ -655,6 +655,10 @@ struct sqlite3_vfs {
   ** value will increment whenever this happens. */
 };
 
+#define SQLITE_ACCESS_EXISTS    0
+#define SQLITE_ACCESS_READWRITE 1
+#define SQLITE_ACCESS_READONLY  2
+
 /*
 ** CAPI3REF: Enable Or Disable Extended Result Codes
 **
index 7a7238320d9bc456e9593a4650f1f73472eedef9..7ae793c6022f6d6556717ba484b3fa0a2e9a1fe1 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.590 2007/08/17 01:14:38 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.591 2007/08/17 15:53:37 danielk1977 Exp $
 */
 #ifndef _SQLITEINT_H_
 #define _SQLITEINT_H_
@@ -187,7 +187,7 @@ typedef UINT8_TYPE i8;             /* 1-byte signed integer */
 */
 #define SQLITE_MUTEX_MEM      1    /* Used by the memory allocator */
 #define SQLITE_MUTEX_PRNG     2    /* Used by pseudorandom generator */
-#define SQLITE_MUTEX_CACHE    3    /* Used by shared cache */
+#define SQLITE_MUTEX_GLOBAL   3    /* Used by global variables */
 #define SQLITE_MUTEX_STATIC_MAX 3
 
 /*
index 599ef2fac6570f98ae658605445a76081f0944a0..012f22a71e41a3e6bae177b031fed50ce17f7b61 100644 (file)
@@ -13,7 +13,7 @@
 ** is not included in the SQLite library.  It is used for automated
 ** testing of the SQLite library.
 **
-** $Id: test1.c,v 1.263 2007/08/17 01:14:38 drh Exp $
+** $Id: test1.c,v 1.264 2007/08/17 15:53:37 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include "tcl.h"
@@ -3587,6 +3587,7 @@ static int test_stmt_int(
 }
 
 #ifndef SQLITE_OMIT_DISKIO
+#if 0
 /*
 ** Usage:  sqlite3OsOpenReadWrite <filename>
 */
@@ -3744,6 +3745,7 @@ static int test_sqlite3OsTempFileName(
   return TCL_OK;
 }
 #endif
+#endif
 
 /*
 ** Usage:  sqlite_set_magic  DB  MAGIC-NUMBER
@@ -4285,6 +4287,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
 
      /* Functions from os.h */
 #ifndef SQLITE_OMIT_DISKIO
+#if 0
      { "sqlite3OsOpenReadWrite",test_sqlite3OsOpenReadWrite, 0 },
      { "sqlite3OsClose",        test_sqlite3OsClose, 0 },
      { "sqlite3OsLock",         test_sqlite3OsLock, 0 },
@@ -4293,6 +4296,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
      /* Custom test interfaces */
      { "sqlite3OsUnlock",         test_sqlite3OsUnlock, 0    },
 #endif
+#endif
 #ifndef SQLITE_OMIT_UTF16
      { "add_test_collate",        test_collate, 0            },
      { "add_test_collate_needed", test_collate_needed, 0     },
index c8464c6c941366d2c1bf7f807bb1ee66fdff57b0..a45d60c965388ba3fd459c82e8c2e5a39b99af24 100644 (file)
@@ -13,7 +13,7 @@
 ** is not included in the SQLite library.  It is used for automated
 ** testing of the SQLite library.
 **
-** $Id: test2.c,v 1.45 2007/08/16 10:09:03 danielk1977 Exp $
+** $Id: test2.c,v 1.46 2007/08/17 15:53:37 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -78,7 +78,7 @@ static int pager_open(
     return TCL_ERROR;
   }
   if( Tcl_GetInt(interp, argv[2], &nPage) ) return TCL_ERROR;
-  rc = sqlite3PagerOpen(&pPager, argv[1], 0, 0);
+  rc = sqlite3PagerOpen(sqlite3_find_vfs(0), &pPager, argv[1], 0, 0);
   if( rc!=SQLITE_OK ){
     Tcl_AppendResult(interp, errorName(rc), 0);
     return TCL_ERROR;
@@ -528,18 +528,21 @@ static int fake_big_file(
   int argc,              /* Number of arguments */
   const char **argv      /* Text of each argument */
 ){
+  sqlite3_vfs *pVfs;
+  sqlite3_file *fd = 0;
+  int flags = SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE;
   int rc;
   int n;
   i64 offset;
-  sqlite3_file *fd = 0;
-  int readOnly = 0;
   if( argc!=3 ){
     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
        " N-MEGABYTES FILE\"", 0);
     return TCL_ERROR;
   }
   if( Tcl_GetInt(interp, argv[1], &n) ) return TCL_ERROR;
-  rc = sqlite3OsOpenReadWrite(argv[2], &fd, &readOnly);
+
+  pVfs = sqlite3_find_vfs(0);
+  rc = sqlite3OsOpenMalloc(pVfs, argv[2], &fd, flags);
   if( rc ){
     Tcl_AppendResult(interp, "open failed: ", errorName(rc), 0);
     return TCL_ERROR;
@@ -547,7 +550,7 @@ static int fake_big_file(
   offset = n;
   offset *= 1024*1024;
   rc = sqlite3OsWrite(fd, "Hello, World!", 14, offset);
-  sqlite3OsClose(&fd);
+  sqlite3OsCloseFree(fd);
   if( rc ){
     Tcl_AppendResult(interp, "write failed: ", errorName(rc), 0);
     return TCL_ERROR;
index 6c9dc6787f997dbc55894bb4b70237721fca14a0..cc02b5f31538a5bc8c96e31b3a0ef638dac339ab 100644 (file)
@@ -263,7 +263,7 @@ static int writeListAppend(
 
   assert((zBuf && nBuf) || (!nBuf && !zBuf));
 
-  pNew = (WriteBuffer *)sqlite3_malloc(sizeof(WriteBuffer) + nBuf);
+  pNew = (WriteBuffer *)sqlite3MallocZero(sizeof(WriteBuffer) + nBuf);
   pNew->iOffset = iOffset;
   pNew->nBuf = nBuf;
   pNew->pFile = (CrashFile *)pFile;
@@ -544,8 +544,8 @@ static int crashParamsObjCmd(
   int objc,
   Tcl_Obj *CONST objv[]
 ){
+  sqlite3_vfs *pVfs;
   int i;
-
   int iDelay;
   const char *zCrashFile;
   int nCrashFile;
@@ -575,17 +575,19 @@ static int crashParamsObjCmd(
   
   if( objc<3 ){
     Tcl_WrongNumArgs(interp, 1, objv, "?OPTIONS? DELAY CRASHFILE");
-    return TCL_ERROR;
+    goto error;
   }
 
-  zCrashFile = sqlite3OsFullPathname(Tcl_GetString(objv[objc-1]));
+  pVfs = sqlite3_find_vfs(0);
+  zCrashFile = sqlite3_malloc(pVfs->mxPathname);
+  sqlite3OsFullPathname(pVfs, Tcl_GetString(objv[objc-1]), zCrashFile);
   nCrashFile = strlen(zCrashFile);
   if( nCrashFile>=sizeof(g.zCrashFile) ){
     Tcl_AppendResult(interp, "Filename is too long: \"", zCrashFile, "\"", 0);
-    return TCL_ERROR;
+    goto error;
   }
   if( Tcl_GetIntFromObj(interp, objv[objc-2], &iDelay) ){
-    return TCL_ERROR;
+    goto error;
   }
 
   for(i=1; i<(objc-2); i+=2){
@@ -599,16 +601,16 @@ static int crashParamsObjCmd(
         "Bad option: \"", zOpt, 
         "\" - must be \"-characteristics\" or \"-sectorsize\"", 0
       );
-      return TCL_ERROR;
+      goto error;
     }
     if( i==objc-3 ){
       Tcl_AppendResult(interp, "Option requires an argument: \"", zOpt, "\"",0);
-      return TCL_ERROR;
+      goto error;
     }
 
     if( zOpt[1]=='s' ){
       if( Tcl_GetIntFromObj(interp, objv[i+1], &iSectorSize) ){
-        return TCL_ERROR;
+        goto error;
       }
       setSectorsize = 1;
     }else{
@@ -616,7 +618,7 @@ static int crashParamsObjCmd(
       Tcl_Obj **apObj;
       int nObj;
       if( Tcl_ListObjGetElements(interp, objv[i+1], &nObj, &apObj) ){
-        return TCL_ERROR;
+        goto error;
       }
       for(j=0; j<nObj; j++){
         int rc;
@@ -630,7 +632,7 @@ static int crashParamsObjCmd(
         );
         Tcl_DecrRefCount(pFlag);
         if( rc ){
-          return TCL_ERROR;
+          goto error;
         }
 
         iDc |= aFlag[iChoice].iValue;
@@ -647,9 +649,13 @@ static int crashParamsObjCmd(
   }
   g.iCrash = iDelay;
   memcpy(g.zCrashFile, zCrashFile, nCrashFile+1);
-
+  sqlite3_free(zCrashFile);
   sqlite3CrashTestEnable = 1;
   return TCL_OK;
+
+error:
+  sqlite3_free(zCrashFile);
+  return TCL_ERROR;
 }
 
 #endif /* SQLITE_OMIT_DISKIO */
index 02069a3f480da7e03b5b8578299aba7a5830b139..6b12c5f93865402d4b759a166a1f2dcc142c91bd 100644 (file)
@@ -43,7 +43,7 @@
 ** in this file for details.  If in doubt, do not deviate from existing
 ** commenting and indentation practices when changing or adding code.
 **
-** $Id: vdbe.c,v 1.641 2007/08/16 10:09:03 danielk1977 Exp $
+** $Id: vdbe.c,v 1.642 2007/08/17 15:53:37 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -486,7 +486,7 @@ int sqlite3VdbeExec(
   sqlite3VdbeIOTraceSql(p);
 #ifdef SQLITE_DEBUG
   if( (p->db->flags & SQLITE_VdbeListing)!=0
-    || sqlite3OsFileExists("vdbe_explain")
+    || sqlite3OsAccess(db->pVfs, "vdbe_explain", SQLITE_ACCESS_EXISTS)
   ){
     int i;
     printf("VDBE Program Listing:\n");
@@ -495,7 +495,7 @@ int sqlite3VdbeExec(
       sqlite3VdbePrintOp(stdout, i, &p->aOp[i]);
     }
   }
-  if( sqlite3OsFileExists("vdbe_trace") ){
+  if( sqlite3OsAccess(db->pVfs, "vdbe_trace", SQLITE_ACCESS_EXISTS) ){
     p->trace = stdout;
   }
 #endif
@@ -519,7 +519,8 @@ int sqlite3VdbeExec(
       }
       sqlite3VdbePrintOp(p->trace, pc, pOp);
     }
-    if( p->trace==0 && pc==0 && sqlite3OsFileExists("vdbe_sqltrace") ){
+    if( p->trace==0 && pc==0 
+     && sqlite3OsAccess(db->pVfs, "vdbe_sqltrace", SQLITE_ACCESS_EXISTS) ){
       sqlite3VdbePrintSql(p);
     }
 #endif
index 948d4b0428e8ee9479eed89dd29e819ccd6f2584..e8d9ddad560b02873bddabba80a4f3a65d6a6265 100644 (file)
@@ -221,7 +221,7 @@ static int sqlite3Step(Vdbe *p){
     }
     if( db->xProfile && !db->init.busy ){
       double rNow;
-      sqlite3OsCurrentTime(&rNow);
+      sqlite3OsCurrentTime(db->pVfs, &rNow);
       p->startTime = (rNow - (int)rNow)*3600.0*24.0*1000000000.0;
     }
 #endif
@@ -258,7 +258,7 @@ static int sqlite3Step(Vdbe *p){
     double rNow;
     u64 elapseTime;
 
-    sqlite3OsCurrentTime(&rNow);
+    sqlite3OsCurrentTime(db->pVfs, &rNow);
     elapseTime = (rNow - (int)rNow)*3600.0*24.0*1000000000.0 - p->startTime;
     assert( p->nOp>0 );
     assert( p->aOp[p->nOp-1].opcode==OP_Noop );
index ec8bd84876fcd505b8a5f20c8d69c2ddac345e26..3771296d403786e6196af15135de0ff21537492d 100644 (file)
@@ -1132,10 +1132,12 @@ static int vdbeCommit(sqlite3 *db){
   */
 #ifndef SQLITE_OMIT_DISKIO
   else{
+    sqlite3_vfs *pVfs = db->pVfs;
+    int flag = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_EXCLUSIVE);
     int needSync = 0;
     char *zMaster = 0;   /* File-name for the master journal */
     char const *zMainFile = sqlite3BtreeGetFilename(db->aDb[0].pBt);
-    sqlite3_file *master = 0;
+    sqlite3_file *pMaster = 0;
     i64 offset = 0;
 
     /* Select a master journal file name */
@@ -1147,12 +1149,14 @@ static int vdbeCommit(sqlite3 *db){
       if( !zMaster ){
         return SQLITE_NOMEM;
       }
-    }while( sqlite3OsFileExists(zMaster) );
+    }while( sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS) );
 
     /* Open the master journal. */
-    rc = sqlite3OsOpenExclusive(zMaster, &master, 0);
+    pMaster = sqlite3_malloc(pVfs->szOsFile);
+    rc = sqlite3OsOpen(pVfs, zMaster, pMaster, flag, 0);
     if( rc!=SQLITE_OK ){
       sqlite3_free(zMaster);
+      sqlite3_free(pMaster);
       return rc;
     }
  
@@ -1171,12 +1175,13 @@ static int vdbeCommit(sqlite3 *db){
         if( !needSync && !sqlite3BtreeSyncDisabled(pBt) ){
           needSync = 1;
         }
-        rc = sqlite3OsWrite(master, zFile, strlen(zFile)+1, offset);
+        rc = sqlite3OsWrite(pMaster, zFile, strlen(zFile)+1, offset);
         offset += strlen(zFile)+1;
         if( rc!=SQLITE_OK ){
-          sqlite3OsClose(&master);
-          sqlite3OsDelete(zMaster);
+          sqlite3OsClose(pMaster);
+          sqlite3OsDelete(pVfs, zMaster);
           sqlite3_free(zMaster);
+          sqlite3_free(pMaster);
           return rc;
         }
       }
@@ -1214,9 +1219,10 @@ static int vdbeCommit(sqlite3 *db){
         rc = sqlite3BtreeCommitPhaseOne(pBt, zMaster);
       }
     }
-    sqlite3OsClose(&master);
+    sqlite3OsClose(pMaster);
     if( rc!=SQLITE_OK ){
       sqlite3_free(zMaster);
+      sqlite3_free(pMaster);
       return rc;
     }
 
@@ -1224,13 +1230,17 @@ static int vdbeCommit(sqlite3 *db){
     ** doing this the directory is synced again before any individual
     ** transaction files are deleted.
     */
-    rc = sqlite3OsDelete(zMaster);
+    rc = sqlite3OsDelete(pVfs, zMaster);
     sqlite3_free(zMaster);
+    sqlite3_free(pMaster);
     zMaster = 0;
+    pMaster = 0;
     if( rc ){
       return rc;
     }
+#if 0
     rc = sqlite3OsSyncDirectory(zMainFile);
+#endif
     if( rc!=SQLITE_OK ){
       /* This is not good. The master journal file has been deleted, but
       ** the directory sync failed. There is no completely safe course of