]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
The win32 driver compiles but does not yet work well. Many bugs
authordrh <drh@noemail.net>
Fri, 24 Aug 2007 03:51:33 +0000 (03:51 +0000)
committerdrh <drh@noemail.net>
Fri, 24 Aug 2007 03:51:33 +0000 (03:51 +0000)
fixed. (CVS 4282)

FossilOrigin-Name: 3a68fcddfa9184e4b310ce0a21312c54b9462ec8

21 files changed:
manifest
manifest.uuid
src/btree.c
src/date.c
src/main.c
src/malloc.c
src/mem1.c
src/mem2.c
src/os.c
src/os.h
src/os_unix.c
src/os_win.c
src/pager.c
src/printf.c
src/sqlite.h.in
src/test6.c
src/test_malloc.c
src/vdbeapi.c
src/vdbeaux.c
src/vtab.c
test/diskfull.test

index 032d5098ea0a0cdd461c16773049cb550a6cbe09..ad4bafe7c9f7bda474cab1ac05a11f95ef8eabff 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Make\scomments\sand\svariable\snaming\smore\sconsistent\sWRT\srowid\sversus\ndocid/blockid.\s\sThis\sshould\shave\sno\scode\simpact.\s(CVS\s4281)
-D 2007-08-23T20:28:49
+C The\swin32\sdriver\scompiles\sbut\sdoes\snot\syet\swork\swell.\s\sMany\sbugs\nfixed.\s(CVS\s4282)
+D 2007-08-24T03:51:33
 F Makefile.in 0c0e53720f658c7a551046442dd7afba0b72bfbe
 F Makefile.linux-gcc 65241babba6faf1152bf86574477baab19190499
 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@@ -80,13 +80,13 @@ F src/alter.c f0aac0060ae8102e58f210b44d35b53438d53173
 F src/analyze.c a14237d869c6bea0846493b59317e4097e81a0b6
 F src/attach.c a52225c75b107be8c5bc144a2b6d20201be3f8f8
 F src/auth.c 083c1205b45e3f52291ec539d396b4fc557856b3
-F src/btree.c 8fa6341b74ab70a28001e4ed4bc5ba14ce1401a6
+F src/btree.c fe9d292cee1a7fee1e5834ecaa3eb2103f7398bc
 F src/btree.h 76c89673981cb77575300c0b78a76eaa00a28743
 F src/btreeInt.h 7fc6e51dc3d4bbed15639a8ea1aae737631d6670
 F src/build.c bc7406e2ea5bfa8276ee1abeae1db27a98fd0b33
 F src/callback.c a542236a68060caad378efa30006ca46cf77b1b2
 F src/complete.c b6dea59fb6d7b3201fa1e0e552cda8c2258a4f50
-F src/date.c a80b33f6e70d619978622547d2c78ab8b036b31a
+F src/date.c af235f38f50809abd0a96da3bb3e0cc32be6226e
 F src/delete.c 849846d06d29851dde0d9f424a5de5817eb140d1
 F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b
 F src/expr.c 978afdceb2693ef58ec0040a43fe57afc6e4236c
@@ -98,34 +98,34 @@ F src/journal.c 03d6b5cc1afe7c5e3cd0af55415f5168eb094398
 F src/legacy.c 7e1b1c57694e49cbadf561e2a7d9cd984dc743b5
 F src/limits.h 71ab25f17e35e0a9f3f6f234b8ed49cc56731d35
 F src/loadext.c 8b31e2e0e961918fa045515459aee1c122d8c266
-F src/main.c 527f27c74d22d83713abbd1550fd5a4ecce89aca
-F src/malloc.c 8078d4c3f9217c0bb018e432d8655c14996bb107
+F src/main.c 795ec066ce38908b5c35ca4353bb601d022e2275
+F src/malloc.c d4282f50964ab1ca31f504c97b7cf2fdb4d4195d
 F src/md5.c c5fdfa5c2593eaee2e32a5ce6c6927c986eaf217
-F src/mem1.c 7b023d45dd71944414db469c742457239e24d74d
-F src/mem2.c 48919353f72b8f6e957a0021eb9deaf863998189
+F src/mem1.c afe2fbf6d7e8247c6c9f69c1481358b1cad60c08
+F src/mem2.c dfe802143189d491ae00f2c5aa50ce619d02f5bf
 F src/mutex.c 9cf641f556a4119ef90ed41b82f2d5647f81686e
-F src/os.c 86593b6e8cc22304d7c2d24b06c0aae49254b181
-F src/os.h 399c89cafa93b9ef35c3dc70f77644d10936b535
+F src/os.c 3b0d37208ea3ec9e1f913fbdeaf88841ed443b9d
+F src/os.h 2bfbbad126a775e4d8c7d59eb4d9585a5fd7dfb5
 F src/os_common.h a5c446d3b93f09f369d13bf217de4bed3437dd1c
 F src/os_os2.c 8769301bff502de642ad2634cedcb77d967ce199
 F src/os_os2.h c3f7d0af7e3453d1d7aa81b06c0a56f5a226530b
 F src/os_test.c 49833426101f99aee4bb5f6a44b7c4b2029fda1c
 F src/os_test.h 903c93554c23d88f34f667f1979e4a1cee792af3
-F src/os_unix.c 3ff776e03535b64df12dcc272a913a52d69f3e4a
+F src/os_unix.c c45b20f868fab1178710ea2f1c8043ce706d3a99
 F src/os_unix.h 5768d56d28240d3fe4537fac08cc85e4fb52279e
-F src/os_win.c 29c0e19c1072679a4c7818c49fab2f35d2ad7747
+F src/os_win.c 1cb94dd33d38e01de82d77bef107c7f3323463ec
 F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
-F src/pager.c 0879439873a9da769ee400b3b8c0967afd786fe8
+F src/pager.c 89dfc6a0bd72898d147264517a43bdf35348dd2c
 F src/pager.h 53087c6fb9db01aed17c7fd044662a27507e89b8
 F src/parse.y 2d2ce439dc6184621fb0b86f4fc5aca7f391a590
 F src/pragma.c 9b989506a1b7c8aecd6befb8235e2f57a4aba7e5
 F src/prepare.c 29ea14cf6b0558f2f80aa53e112bff55f1119e36
-F src/printf.c 0f46bc3a805d5620f5aedfec1c3768d293a5ee5e
+F src/printf.c 33d23a68e498006136ca9770579cf2d14a7ec68e
 F src/random.c 4a22746501bf36b0a088c66e38dde5daba6a35da
 F src/select.c 98c367bce3f38c5adfcc97de9ab5c79b0e5dc2b2
 F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
 F src/shell.c ac29402b538515fa4697282387be9c1205e6e9eb
-F src/sqlite.h.in a1a5bc9e7e63bf73c2bb68be3749dec2bbd8cc44
+F src/sqlite.h.in 09a5256ee80dfc7cb4353739f78e4267be323574
 F src/sqlite3ext.h 9a26028378c288af500d8b94ed079666fed5806b
 F src/sqliteInt.h 951229c727f14f12f1c5555d2ed079bd2201415c
 F src/sqliteLimit.h f14609c27636ebc217c9603ade26dbdd7d0f6afa
@@ -136,7 +136,7 @@ F src/test2.c 4f742e99ed1bea5c14692f627bdb59a146f30504
 F src/test3.c a7d011c51d6b2e2a73c43983d5c2b731d69c74d7
 F src/test4.c c2c0f5dc907f1346f5d4b65eb5799f11eb9e4071
 F src/test5.c 3a6a5717a149d7ca2e6d14f5be72cf7555d54dc4
-F src/test6.c 5d6286568b12ec6c813cb30d2a14de8229f8e388
+F src/test6.c de2dbcd67401f00bfa0affc044ba671aa62384a5
 F src/test7.c a9d509d0e9ad214b4772696f49f6e61be26213d1
 F src/test8.c e6a543c8b248efe120ae33a6859fcd55dcf46a96
 F src/test9.c b46c8fe02ac7cca1a7316436d8d38d50c66f4b2f
@@ -146,7 +146,7 @@ F src/test_btree.c c1308ba0b88ab577fa56c9e493a09829dfcded9c
 F src/test_config.c f0b911bb615d93a192647e76910dce65cbbcf3ad
 F src/test_hexio.c 82916f918687502658f02533b519c38cb180db6d
 F src/test_loadext.c 22065d601a18878e5542191001f0eaa5d77c0ed8
-F src/test_malloc.c 9d5fb38bc0647ba9376d8d954be5b5aa01e12c80
+F src/test_malloc.c 5f5566bb799e72cb328df8933ef9fdb9d90d270e
 F src/test_md5.c 34599caee5b1c73dcf86ca31f55846fab8c19ef7
 F src/test_schema.c 12c9de7661d6294eec2d57afbb52e2af1128084f
 F src/test_server.c 319f6b1a99bab5f7149387442243d6e65a8ab4eb
@@ -160,12 +160,12 @@ F src/vacuum.c 318ccae7c4e3ddf241aeaee4d2611bfe1949a373
 F src/vdbe.c 9d4d00589c174aad9a616f1615464ddddebba0ec
 F src/vdbe.h 001c5b257567c1d3de7feb2203aac71d0d7b16a3
 F src/vdbeInt.h 39fb069ce04137545ca0bc790f80ddc64a8c99d9
-F src/vdbeapi.c 81cb7f018e56c20b40365f005ff69e1af9ea9494
-F src/vdbeaux.c 8b41802973560274c15acdc1ac1d4147c110e8d7
+F src/vdbeapi.c bdd0aea216744482dd1b7fab56de18ba5b6fbdf4
+F src/vdbeaux.c b040c3787ea1c32ba025b1c5822553469abe4efa
 F src/vdbeblob.c d12ed95dac0992e1e372d079d76af047cc42f7c7
 F src/vdbefifo.c 334c838c8f42d61a94813d136019ee566b5dc2f6
 F src/vdbemem.c 896fa3f8df9d2661eb15c7ce361857741b447268
-F src/vtab.c 6a7ce44edf7ad824d7e9307394121fe943bb419c
+F src/vtab.c 72e5347cca4d55e55e180015f4dc78736f852e14
 F src/where.c 2776a0caf8cbbfd6ec79cfb1cd9bc25074055e5e
 F tclinstaller.tcl 4356d9d94d2b5ed5e68f9f0c80c4df3048dd7617
 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
@@ -238,7 +238,7 @@ F test/delete3.test 555e84a00a99230b7d049d477a324a631126a6ab
 F test/descidx1.test 2177c4ad55edcf56ad5f4c6490f307d7774e8a10
 F test/descidx2.test eb3a2882ec58aa6e1e8131d9bb54436e5b4a3ce2
 F test/descidx3.test 3a55b8d73bc3e9ad084e0da7fec781cf0d2a0356
-F test/diskfull.test a91fa95a8729b71fdac4738a49755f70b48c61f3
+F test/diskfull.test 34ef53e88372c5b5e488ad1581514559a224c2b1
 F test/distinctagg.test 2b89d1c5220d966a30ba4b40430338669301188b
 F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea
 F test/enc2.test 45710bacfa9df29720bc84c067dfdf8c8ddfb797
@@ -561,7 +561,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
 F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
-P 6eb2d74a8cfce322930f05c97d4ec255f3711efb
-R 6c3888d041c9e4f3c4ea7193ec7eeec0
-U shess
-Z 0c8d40ad377805b9a794c415d7962113
+P 76f1e18ebc25d692f122784e87d202992c4cfed2
+R 72f6a976f09cdaf5e13abeade770ec1c
+U drh
+Z 8bcbe7ef9d6a537a157463bef713e3c1
index 8d4de48a20d418978da5b94e19345e332f9ee2a9..b2535dadeb367a0dc23428515568fa4ee76746e2 100644 (file)
@@ -1 +1 @@
-76f1e18ebc25d692f122784e87d202992c4cfed2
\ No newline at end of file
+3a68fcddfa9184e4b310ce0a21312c54b9462ec8
\ No newline at end of file
index bb740a74f7f14a80c0533c1a558c36e52805db73..a3d48809ddb2cde44b462c1ff6f4f27f7073d772 100644 (file)
@@ -9,7 +9,7 @@
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
-** $Id: btree.c,v 1.410 2007/08/23 02:47:53 drh Exp $
+** $Id: btree.c,v 1.411 2007/08/24 03:51:33 drh Exp $
 **
 ** This file implements a external (disk-based) database using BTrees.
 ** See the header comment on "btreeInt.h" for additional information.
@@ -1102,13 +1102,6 @@ int sqlite3BtreeOpen(
   int nReserve;
   unsigned char zDbHeader[100];
 
-  if( pSqlite ){
-    pVfs = pSqlite->pVfs;
-  }else{
-    pVfs = sqlite3_vfs_find(0);
-  }
-  assert( sqlite3BtreeMutexHeld(pSqlite->mutex) );
-
   /* Set the variable isMemdb to true for an in-memory database, or 
   ** false for a file-based database. This symbol is only required if
   ** either of the shared-data or autovacuum features are compiled 
@@ -1122,6 +1115,13 @@ int sqlite3BtreeOpen(
   #endif
 #endif
 
+  if( pSqlite ){
+    pVfs = pSqlite->pVfs;
+  }else{
+    pVfs = sqlite3_vfs_find(0);
+  }
+  assert( sqlite3BtreeMutexHeld(pSqlite->mutex) );
+
   p = sqlite3MallocZero(sizeof(Btree));
   if( !p ){
     return SQLITE_NOMEM;
index a807f35253a465177853e422877cbdf3f23210b0..50f5f4a837a85c8e640063cfcddd781da1a7631c 100644 (file)
@@ -16,7 +16,7 @@
 ** sqlite3RegisterDateTimeFunctions() found at the bottom of the file.
 ** All other code has file scope.
 **
-** $Id: date.c,v 1.71 2007/08/21 19:33:56 drh Exp $
+** $Id: date.c,v 1.72 2007/08/24 03:51:33 drh Exp $
 **
 ** SQLite processes all times and dates as Julian Day numbers.  The
 ** dates and times are stored as the number of days since noon
@@ -426,7 +426,7 @@ static double localtimeOffset(DateTime *p){
 #else
   {
     struct tm *pTm;
-    sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_GLOBAL));
+    sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
     pTm = localtime(&t);
     y.Y = pTm->tm_year + 1900;
     y.M = pTm->tm_mon + 1;
@@ -434,7 +434,7 @@ static double localtimeOffset(DateTime *p){
     y.h = pTm->tm_hour;
     y.m = pTm->tm_min;
     y.s = pTm->tm_sec;
-    sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_GLOBAL));
+    sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
   }
 #endif
   y.validYMD = 1;
index b08aca1705078a5b5b2ad22cc4a63a13f80e3803..7200532308bb4a60efb8e9d6f08e65b5adf046d8 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.396 2007/08/22 20:18:22 drh Exp $
+** $Id: main.c,v 1.397 2007/08/24 03:51:34 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -945,15 +945,16 @@ static int openDatabase(
   if( db==0 ) goto opendb_out;
   db->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_RECURSIVE);
   if( db->mutex==0 ){
-    db->mallocFailed = 1;
+    sqlite3_free(db);
+    db = 0;
     goto opendb_out;
   }
   sqlite3_mutex_enter(db->mutex);
   db->pVfs = sqlite3_vfs_find(zVfs);
   db->errMask = 0xff;
   db->priorNewRowid = 0;
-  db->magic = SQLITE_MAGIC_BUSY;
   db->nDb = 2;
+  db->magic = SQLITE_MAGIC_BUSY;
   db->aDb = db->aDbStatic;
   db->autoCommit = 1;
   db->flags |= SQLITE_ShortColNames
@@ -1076,7 +1077,7 @@ static int openDatabase(
 #endif
 
 opendb_out:
-  if( db ){
+  if( db && db->mutex ){
     sqlite3_mutex_leave(db->mutex);
   }
   if( SQLITE_NOMEM==(rc = sqlite3_errcode(db)) ){
index 62fa2d2fabb7ea2233feed190ceaa6affef8ab35..bd86636e9c573abbedb44a7602000a151a3e6121 100644 (file)
@@ -12,7 +12,7 @@
 ** Memory allocation functions used throughout sqlite.
 **
 **
-** $Id: malloc.c,v 1.10 2007/08/22 20:18:22 drh Exp $
+** $Id: malloc.c,v 1.11 2007/08/24 03:51:34 drh Exp $
 */
 #include "sqliteInt.h"
 #include <stdarg.h>
@@ -25,8 +25,8 @@
 */
 static void softHeapLimitEnforcer(
   void *NotUsed, 
-  sqlite3_uint64 inUse,
-  unsigned int allocSize
+  sqlite3_int64 inUse,
+  int allocSize
 ){
   sqlite3_release_memory(allocSize);
 }
index 5a533005dfd8b2497fe4b80e399ae16746db7de6..abaafe1ec9dc7f78c3cfbb7be504199d6b8f5895 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.7 2007/08/22 20:18:22 drh Exp $
+** $Id: mem1.c,v 1.8 2007/08/24 03:51:34 drh Exp $
 */
 
 /*
@@ -51,8 +51,8 @@ static struct {
   ** issued.  The alarmBusy variable is set to prevent recursive
   ** callbacks.
   */
-  sqlite3_uint64 alarmThreshold;
-  void (*alarmCallback)(void*, sqlite3_uint64, unsigned);
+  sqlite3_int64 alarmThreshold;
+  void (*alarmCallback)(void*, sqlite3_int64,int);
   void *alarmArg;
   int alarmBusy;
   
@@ -64,22 +64,18 @@ static struct {
   /*
   ** Current allocation and high-water mark.
   */
-  sqlite3_uint64 nowUsed;
-  sqlite3_uint64 mxUsed;
+  sqlite3_int64 nowUsed;
+  sqlite3_int64 mxUsed;
   
  
-} mem = {  /* This variable holds all of the local data */
-   ((sqlite3_uint64)1)<<63,    /* alarmThreshold */
-   /* Everything else is initialized to zero */
-};
-
+} mem;
 
 
 /*
 ** Return the amount of memory currently checked out.
 */
-sqlite3_uint64 sqlite3_memory_used(void){
-  sqlite3_uint64 n;
+sqlite3_int64 sqlite3_memory_used(void){
+  sqlite3_int64 n;
   if( mem.mutex==0 ){
     mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
   }
@@ -94,8 +90,8 @@ sqlite3_uint64 sqlite3_memory_used(void){
 ** checked out since either the beginning of this process
 ** or since the most recent reset.
 */
-sqlite3_uint64 sqlite3_memory_highwater(int resetFlag){
-  sqlite3_uint64 n;
+sqlite3_int64 sqlite3_memory_highwater(int resetFlag){
+  sqlite3_int64 n;
   if( mem.mutex==0 ){
     mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
   }
@@ -112,9 +108,9 @@ sqlite3_uint64 sqlite3_memory_highwater(int resetFlag){
 ** Change the alarm callback
 */
 int sqlite3_memory_alarm(
-  void(*xCallback)(void *pArg, sqlite3_uint64 used, unsigned int N),
+  void(*xCallback)(void *pArg, sqlite3_int64 used,int N),
   void *pArg,
-  sqlite3_uint64 iThreshold
+  sqlite3_int64 iThreshold
 ){
   if( mem.mutex==0 ){
     mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
@@ -130,9 +126,9 @@ int sqlite3_memory_alarm(
 /*
 ** Trigger the alarm 
 */
-static void sqlite3MemsysAlarm(unsigned nByte){
-  void (*xCallback)(void*,sqlite3_uint64,unsigned);
-  sqlite3_uint64 nowUsed;
+static void sqlite3MemsysAlarm(int nByte){
+  void (*xCallback)(void*,sqlite3_int64,int);
+  sqlite3_int64 nowUsed;
   void *pArg;
   if( mem.alarmCallback==0 || mem.alarmBusy  ) return;
   mem.alarmBusy = 1;
@@ -149,7 +145,7 @@ static void sqlite3MemsysAlarm(unsigned nByte){
 ** Allocate nBytes of memory
 */
 void *sqlite3_malloc(int nBytes){
-  sqlite3_uint64 *p;
+  sqlite3_int64 *p;
   if( nBytes<=0 ){
     return 0;
   }
@@ -157,7 +153,7 @@ void *sqlite3_malloc(int nBytes){
     mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
   }
   sqlite3_mutex_enter(mem.mutex);
-  if( mem.nowUsed+nBytes>=mem.alarmThreshold ){
+  if( mem.alarmCallback!=0 && mem.nowUsed+nBytes>=mem.alarmThreshold ){
     sqlite3MemsysAlarm(nBytes);
   }
   p = malloc(nBytes+8);
@@ -181,15 +177,15 @@ void *sqlite3_malloc(int nBytes){
 ** Free memory.
 */
 void sqlite3_free(void *pPrior){
-  sqlite3_uint64 *p;
-  unsigned nByte;
+  sqlite3_int64 *p;
+  int nByte;
   if( pPrior==0 ){
     return;
   }
   assert( mem.mutex!=0 );
   p = pPrior;
   p--;
-  nByte = (unsigned int)*p;
+  nByte = (int)*p;
   sqlite3_mutex_enter(mem.mutex);
   mem.nowUsed -= nByte;
   free(p);
@@ -200,8 +196,8 @@ void sqlite3_free(void *pPrior){
 ** Change the size of an existing memory allocation
 */
 void *sqlite3_realloc(void *pPrior, int nBytes){
-  unsigned nOld;
-  sqlite3_uint64 *p;
+  int nOld;
+  sqlite3_int64 *p;
   if( pPrior==0 ){
     return sqlite3_malloc(nBytes);
   }
@@ -211,7 +207,7 @@ void *sqlite3_realloc(void *pPrior, int nBytes){
   }
   p = pPrior;
   p--;
-  nOld = (unsigned int)p[0];
+  nOld = (int)p[0];
   assert( mem.mutex!=0 );
   sqlite3_mutex_enter(mem.mutex);
   if( mem.nowUsed+nBytes-nOld>=mem.alarmThreshold ){
index 4b3c4f58f810921461ecbb25c3f737d71f1fbb19..c48927915952c2ecb49a76b4c42d0f13a38d3525 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains the C functions that implement a memory
 ** allocation subsystem for use by SQLite.  
 **
-** $Id: mem2.c,v 1.8 2007/08/23 02:47:53 drh Exp $
+** $Id: mem2.c,v 1.9 2007/08/24 03:51:34 drh Exp $
 */
 
 /*
 */
 struct MemBlockHdr {
   struct MemBlockHdr *pNext, *pPrev;  /* Linked list of all unfreed memory */
-  unsigned int iSize;                 /* Size of this allocation */
-  unsigned char nBacktrace;           /* Number of backtraces on this alloc */
-  unsigned char nBacktraceSlots;      /* Available backtrace slots */
-  unsigned short nTitle;              /* Bytes of title; includes '\0' */
-  unsigned int iForeGuard;            /* Guard word for sanity */
+  int iSize;                          /* Size of this allocation */
+  char nBacktrace;                    /* Number of backtraces on this alloc */
+  char nBacktraceSlots;               /* Available backtrace slots */
+  short nTitle;                       /* Bytes of title; includes '\0' */
+  int iForeGuard;                     /* Guard word for sanity */
 };
 
 /*
@@ -98,8 +98,8 @@ static struct {
   ** issued.  The alarmBusy variable is set to prevent recursive
   ** callbacks.
   */
-  sqlite3_uint64 alarmThreshold;
-  void (*alarmCallback)(void*, sqlite3_uint64, unsigned);
+  sqlite3_int64 alarmThreshold;
+  void (*alarmCallback)(void*, sqlite3_int64, int);
   void *alarmArg;
   int alarmBusy;
   
@@ -111,8 +111,8 @@ static struct {
   /*
   ** Current allocation and high-water mark.
   */
-  sqlite3_uint64 nowUsed;
-  sqlite3_uint64 mxUsed;
+  sqlite3_int64 nowUsed;
+  sqlite3_int64 mxUsed;
   
   /*
   ** Head and tail of a linked list of all outstanding allocations
@@ -147,18 +147,14 @@ static struct {
   int disallow; /* Do not allow memory allocation */
   
   
-} mem = {  /* This variable holds all of the local data */
-   ((sqlite3_uint64)1)<<63,    /* alarmThreshold */
-   /* Everything else is initialized to zero */
-};
-
+} mem;
 
 
 /*
 ** Return the amount of memory currently checked out.
 */
-sqlite3_uint64 sqlite3_memory_used(void){
-  sqlite3_uint64 n;
+sqlite3_int64 sqlite3_memory_used(void){
+  sqlite3_int64 n;
   if( mem.mutex==0 ){
     mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
   }
@@ -173,8 +169,8 @@ sqlite3_uint64 sqlite3_memory_used(void){
 ** checked out since either the beginning of this process
 ** or since the most recent reset.
 */
-sqlite3_uint64 sqlite3_memory_highwater(int resetFlag){
-  sqlite3_uint64 n;
+sqlite3_int64 sqlite3_memory_highwater(int resetFlag){
+  sqlite3_int64 n;
   if( mem.mutex==0 ){
     mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
   }
@@ -191,9 +187,9 @@ sqlite3_uint64 sqlite3_memory_highwater(int resetFlag){
 ** Change the alarm callback
 */
 int sqlite3_memory_alarm(
-  void(*xCallback)(void *pArg, sqlite3_uint64 used, unsigned int N),
+  void(*xCallback)(void *pArg, sqlite3_int64 used, int N),
   void *pArg,
-  sqlite3_uint64 iThreshold
+  sqlite3_int64 iThreshold
 ){
   if( mem.mutex==0 ){
     mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
@@ -209,9 +205,9 @@ int sqlite3_memory_alarm(
 /*
 ** Trigger the alarm 
 */
-static void sqlite3MemsysAlarm(unsigned nByte){
-  void (*xCallback)(void*,sqlite3_uint64,unsigned);
-  sqlite3_uint64 nowUsed;
+static void sqlite3MemsysAlarm(int nByte){
+  void (*xCallback)(void*,sqlite3_int64,int);
+  sqlite3_int64 nowUsed;
   void *pArg;
   if( mem.alarmCallback==0 || mem.alarmBusy  ) return;
   mem.alarmBusy = 1;
@@ -232,14 +228,14 @@ static void sqlite3MemsysAlarm(unsigned nByte){
 */
 static struct MemBlockHdr *sqlite3MemsysGetHeader(void *pAllocation){
   struct MemBlockHdr *p;
-  unsigned int *pInt;
+  int *pInt;
 
   p = (struct MemBlockHdr*)pAllocation;
   p--;
   assert( p->iForeGuard==FOREGUARD );
   assert( (p->iSize & 3)==0 );
-  pInt = (unsigned int*)pAllocation;
-  assert( pInt[p->iSize/sizeof(unsigned int)]==REARGUARD );
+  pInt = (int*)pAllocation;
+  assert( pInt[p->iSize/sizeof(int)]==REARGUARD );
   return p;
 }
 
@@ -260,9 +256,9 @@ void *sqlite3_malloc(int nByte){
   struct MemBlockHdr *pHdr;
   void **pBt;
   char *z;
-  unsigned int *pInt;
+  int *pInt;
   void *p;
-  unsigned int totalSize;
+  int totalSize;
 
   if( nByte<=0 ){
     return 0;
@@ -272,11 +268,11 @@ void *sqlite3_malloc(int nByte){
   }
   sqlite3_mutex_enter(mem.mutex);
   assert( mem.disallow==0 );
-  if( mem.nowUsed+nByte>=mem.alarmThreshold ){
+  if( mem.alarmCallback!=0 && mem.nowUsed+nByte>=mem.alarmThreshold ){
     sqlite3MemsysAlarm(nByte);
   }
   nByte = (nByte+3)&~3;
-  totalSize = nByte + sizeof(*pHdr) + sizeof(unsigned int) +
+  totalSize = nByte + sizeof(*pHdr) + sizeof(int) +
                mem.nBacktrace*sizeof(void*) + mem.nTitle;
   if( mem.iFail>0 ){
     if( mem.iFail==1 ){
@@ -323,8 +319,8 @@ void *sqlite3_malloc(int nByte){
       memcpy(z, mem.zTitle, mem.nTitle);
     }
     pHdr->iSize = nByte;
-    pInt = (unsigned int *)&pHdr[1];
-    pInt[nByte/sizeof(unsigned int)] = REARGUARD;
+    pInt = (int*)&pHdr[1];
+    pInt[nByte/sizeof(int)] = REARGUARD;
     memset(pInt, 0x65, nByte);
     mem.nowUsed += nByte;
     if( mem.nowUsed>mem.mxUsed ){
@@ -369,7 +365,7 @@ void sqlite3_free(void *pPrior){
   z = (char*)pBt;
   z -= pHdr->nTitle;
   memset(z, 0x2b, sizeof(void*)*pHdr->nBacktraceSlots + sizeof(*pHdr) +
-                  pHdr->iSize + sizeof(unsigned int) + pHdr->nTitle);
+                  pHdr->iSize + sizeof(int) + pHdr->nTitle);
   free(z);
   sqlite3_mutex_leave(mem.mutex);  
 }
@@ -488,15 +484,6 @@ int sqlite3_memdebug_fail(int iFail, int iRepeat){
   return n;
 }
 
-/*
-** This routine returns the number of successful mallocs remaining until
-** the next simulated malloc failure.  -1 is returned if no simulated
-** failure is currently scheduled.
-*/
-int sqlite3_memdebug_pending(void){
-  return mem.iFail-1;
-}
-
 /*
 ** The following two routines are used to assert that no memory
 ** allocations occur between one call and the next.  The use of
index 3ba530e77a0740070b7ed88599726cb05cf97d47..c0649c349ac88b10cb0d648db543275674d421af 100644 (file)
--- a/src/os.c
+++ b/src/os.c
@@ -110,40 +110,40 @@ int sqlite3OsOpen(
   int flags, 
   int *pFlagsOut
 ){
-  return pVfs->xOpen(pVfs->pAppData, zPath, pFile, flags, pFlagsOut);
+  return pVfs->xOpen(pVfs, zPath, pFile, flags, pFlagsOut);
 }
 int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
-  return pVfs->xDelete(pVfs->pAppData, zPath, dirSync);
+  return pVfs->xDelete(pVfs, zPath, dirSync);
 }
 int sqlite3OsAccess(sqlite3_vfs *pVfs, const char *zPath, int flags){
-  return pVfs->xAccess(pVfs->pAppData, zPath, flags);
+  return pVfs->xAccess(pVfs, zPath, flags);
 }
 int sqlite3OsGetTempName(sqlite3_vfs *pVfs, char *zBufOut){
-  return pVfs->xGetTempName(pVfs->pAppData, zBufOut);
+  return pVfs->xGetTempName(pVfs, zBufOut);
 }
 int sqlite3OsFullPathname(sqlite3_vfs *pVfs, const char *zPath, char *zPathOut){
-  return pVfs->xFullPathname(pVfs->pAppData, zPath, zPathOut);
+  return pVfs->xFullPathname(pVfs, zPath, zPathOut);
 }
 void *sqlite3OsDlOpen(sqlite3_vfs *pVfs, const char *zPath){
-  return pVfs->xDlOpen(pVfs->pAppData, zPath);
+  return pVfs->xDlOpen(pVfs, zPath);
 }
 void sqlite3OsDlError(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
-  pVfs->xDlError(pVfs->pAppData, nByte, zBufOut);
+  pVfs->xDlError(pVfs, nByte, zBufOut);
 }
 void *sqlite3OsDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){
-  return pVfs->xDlSym(pHandle, zSymbol);
+  return pVfs->xDlSym(pVfs, pHandle, zSymbol);
 }
 void sqlite3OsDlClose(sqlite3_vfs *pVfs, void *pHandle){
-  pVfs->xDlClose(pHandle);
+  pVfs->xDlClose(pVfs, pHandle);
 }
 int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
-  return pVfs->xRandomness(pVfs->pAppData, nByte, zBufOut);
+  return pVfs->xRandomness(pVfs, nByte, zBufOut);
 }
 int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){
-  return pVfs->xSleep(pVfs->pAppData, nMicro);
+  return pVfs->xSleep(pVfs, nMicro);
 }
 int sqlite3OsCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
-  return pVfs->xCurrentTime(pVfs->pAppData, pTimeOut);
+  return pVfs->xCurrentTime(pVfs, pTimeOut);
 }
 
 int sqlite3OsOpenMalloc(
@@ -175,15 +175,12 @@ int sqlite3OsCloseFree(sqlite3_file *pFile){
   return rc;
 }
 
-/* 
-** Default vfs implementation. Defined by the various os_X.c implementations.
-*/
-extern sqlite3_vfs sqlite3DefaultVfs;
-
 /*
-** The list of all registered VFS implementations.
+** The list of all registered VFS implementations.  This list is
+** initialized to the single VFS returned by sqlite3OsDefaultVfs()
+** upon the first call to sqlite3_vfs_find().
 */
-static sqlite3_vfs *vfsList = &sqlite3DefaultVfs;
+static sqlite3_vfs *vfsList = 0;
 
 /*
 ** Locate a VFS by name.  If no name is given, simply return the
@@ -192,7 +189,12 @@ static sqlite3_vfs *vfsList = &sqlite3DefaultVfs;
 sqlite3_vfs *sqlite3_vfs_find(const char *zVfs){
   sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
   sqlite3_vfs *pVfs;
+  static int isInit = 0;
   sqlite3_mutex_enter(mutex);
+  if( !isInit ){
+    vfsList = sqlite3OsDefaultVfs();
+    isInit = 1;
+  }
   for(pVfs = vfsList; pVfs; pVfs=pVfs->pNext){
     if( zVfs==0 ) break;
     if( strcmp(zVfs, pVfs->zName)==0 ) break;
@@ -217,7 +219,7 @@ int sqlite3_vfs_release(sqlite3_vfs *pVfs){
   sqlite3_mutex_enter(mutex);
   assert( pVfs->nRef>0 );
   pVfs->nRef--;
-  if( pVfs->nRef==0 ){
+  if( pVfs->nRef==0 && pVfs->vfsMutex ){
     sqlite3_mutex_free(pVfs->vfsMutex);
     pVfs->vfsMutex = 0;
   }
index 0f6c782c2e05655ecd8c6504a407952dbc131799..e5c8e7bc6a42142deb742f94d89e4283f286d57c 100644 (file)
--- a/src/os.h
+++ b/src/os.h
 ** If sqlite is being embedded in another program, you may wish to change the
 ** prefix to reflect your program's name, so that if your program exits
 ** prematurely, old temporary files can be easily identified. This can be done
-** using -DTEMP_FILE_PREFIX=myprefix_ on the compiler command line.
+** using -DSQLITE_TEMP_FILE_PREFIX=myprefix_ on the compiler command line.
 **
 ** 2006-10-31:  The default prefix used to be "sqlite_".  But then
 ** Mcafee started using SQLite in their anti-virus product and it
 ** enough to know that calling the developer will not help get rid
 ** of the file.
 */
-#ifndef TEMP_FILE_PREFIX
-# define TEMP_FILE_PREFIX "etilqs_"
+#ifndef SQLITE_TEMP_FILE_PREFIX
+# define SQLITE_TEMP_FILE_PREFIX "etilqs_"
 #endif
 
 /*
@@ -273,4 +273,18 @@ int sqlite3OsCloseFree(sqlite3_file *);
   int sqlite3OsLockState(sqlite3_file *id);
 #endif
 
+/*
+** Each OS-specific backend defines an instance of the following
+** structure for returning a pointer to its sqlite3_vfs.  If OS_OTHER
+** is defined (meaning that the application-defined OS interface layer
+** is used) then there is no default VFS.   The application must
+** register one or more VFS structures using sqlite3_vfs_register()
+** before attempting to use SQLite.
+*/
+#if OS_UNIX || OS_WIN || OS_OS2
+sqlite3_vfs *sqlite3OsDefaultVfs(void);
+#else
+# define sqlite3OsDefaultVfs(X) 0
+#endif
+
 #endif /* _SQLITE_OS_H_ */
index eb7a66b64fdccea947b76e282e7084c9cdf1a144..4287e23513be7c543bed9569efbf20899b4bcc2a 100644 (file)
@@ -108,13 +108,6 @@ struct unixFile {
 */
 #include "os_common.h"
 
-/*
-** Do not include any of the File I/O interface procedures if the
-** SQLITE_OMIT_DISKIO macro is defined (indicating that the database
-** will be in-memory only)
-*/
-#ifndef SQLITE_OMIT_DISKIO
-
 /*
 ** Define various macros that are missing from some systems.
 */
@@ -2300,12 +2293,6 @@ static int fillInUnixFile(
 }
 #endif /* SQLITE_ENABLE_LOCKING_STYLE */
 
-#endif /* SQLITE_OMIT_DISKIO */
-/***************************************************************************
-** Everything above deals with file I/O.  Everything that follows deals
-** with other miscellanous aspects of the operating system interface
-****************************************************************************/
-
 /*
 ** Open a file descriptor to the directory containing file zFilename.
 ** If successful, *pFd is set to the opened file descriptor and
@@ -2321,8 +2308,7 @@ static int openDirectory(const char *zFilename, int *pFd){
   int fd;
   char zDirname[MAX_PATHNAME+1];
 
-  strncpy(zDirname, zFilename, MAX_PATHNAME);
-  zDirname[MAX_PATHNAME-1] = '\0';
+  sqlite3_snprintf(MAX_PATHNAME, zDirname, "%s", zFilename);
   for(ii=strlen(zDirname); ii>=0 && zDirname[ii]!='/'; ii--);
   if( ii>0 ){
     zDirname[ii] = '\0';
@@ -2361,7 +2347,7 @@ static int openDirectory(const char *zFilename, int *pFd){
 ** OpenExclusive().
 */
 static int unixOpen(
-  void *pNotUsed
+  sqlite3_vfs *pVfs
   const char *zPath, 
   sqlite3_file *pFile,
   int flags,
@@ -2414,7 +2400,7 @@ static int unixOpen(
     /* 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);
+    return unixOpen(pVfs, zPath, pFile, flags, pOutFlags);
   }
   if( fd<0 ){
     return SQLITE_CANTOPEN;
@@ -2441,7 +2427,7 @@ static int unixOpen(
 ** Delete the file at zPath. If the dirSync argument is true, fsync()
 ** the directory after deleting the file.
 */
-static int unixDelete(void *pNotUsed, const char *zPath, int dirSync){
+static int unixDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
   int rc = SQLITE_OK;
   SimulateIOError(return SQLITE_IOERR_DELETE);
   unlink(zPath);
@@ -2468,7 +2454,7 @@ static int unixDelete(void *pNotUsed, const char *zPath, int dirSync){
 **
 ** Otherwise return 0.
 */
-static int unixAccess(void *pNotUsed, const char *zPath, int flags){
+static int unixAccess(sqlite3_vfs *pVfs, const char *zPath, int flags){
   int amode;
   switch( flags ){
     case SQLITE_ACCESS_EXISTS:
@@ -2488,10 +2474,11 @@ static int unixAccess(void *pNotUsed, const char *zPath, int flags){
 }
 
 /*
-** Create a temporary file name in zBuf.  zBuf must be big enough to
-** hold at least MAX_PATHNAME characters.
+** Create a temporary file name in zBuf.  zBuf must be allocated
+** by the calling process and must be big enough to hold at least
+** pVfs->mxPathname bytes.
 */
-static int unixGetTempName(void *pNotUsed, char *zBuf){
+static int unixGetTempName(sqlite3_vfs *pVfs, char *zBuf){
   static const char *azDirs[] = {
      0,
      "/var/tmp",
@@ -2516,7 +2503,8 @@ static int unixGetTempName(void *pNotUsed, char *zBuf){
     break;
   }
   do{
-    sqlite3_snprintf(MAX_PATHNAME-17, zBuf, "%s/"TEMP_FILE_PREFIX, zDir);
+    assert( pVfs->mxPathname==MAX_PATHNAME );
+    sqlite3_snprintf(MAX_PATHNAME-17, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX, zDir);
     j = strlen(zBuf);
     sqlite3Randomness(15, &zBuf[j]);
     for(i=0; i<15; i++, j++){
@@ -2537,18 +2525,18 @@ static int unixGetTempName(void *pNotUsed, char *zBuf){
 ** (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){
+static int unixFullPathname(sqlite3_vfs *pVfs, const char *zPath, char *zOut){
+  assert( pVfs->mxPathname==MAX_PATHNAME );
   zOut[MAX_PATHNAME-1] = '\0';
   if( zPath[0]=='/' ){
-    strncpy(zOut, zPath, MAX_PATHNAME-1);
+    sqlite3_snprintf(MAX_PATHNAME, zOut, "%s", zPath);
   }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);
+    sqlite3_snprintf(MAX_PATHNAME-nCwd, &zOut[nCwd], "/%s", zPath);
   }
   return SQLITE_OK;
 
@@ -2586,25 +2574,24 @@ static int unixFullPathname(void *pNotUsed, const char *zPath, char *zOut){
 ** within the shared library, and closing the shared library.
 */
 #include <dlfcn.h>
-static void *unixDlOpen(void *pNotUsed, const char *zFilename){
+static void *unixDlOpen(sqlite3_vfs *pVfs, const char *zFilename){
   return dlopen(zFilename, RTLD_NOW | RTLD_GLOBAL);
 }
-static void unixDlError(void *pNotUsed, int nBuf, char *zBufOut){
+static void unixDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
   char *zErr;
   enterMutex();
   zErr = dlerror();
   if( zErr ){
-    strncpy(zBufOut, zErr, nBuf-1);
-    zBufOut[nBuf-1] = '\0';
+    sqlite3_snprintf(nBuf, zBufOut, "%s", zErr);
   }else if(nBuf>0) {
     zBufOut[0] = '\0';
   }
   leaveMutex();
 }
-void *unixDlSym(void *pHandle, const char *zSymbol){
+void *unixDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){
   return dlsym(pHandle, zSymbol);
 }
-void unixDlClose(void *pHandle){
+void unixDlClose(sqlite3_vfs *pVfs, void *pHandle){
   dlclose(pHandle);
 }
 #else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
@@ -2617,7 +2604,7 @@ void unixDlClose(void *pHandle){
 /*
 ** Write nBuf bytes of random data to the supplied buffer zBuf.
 */
-static int unixRandomness(void *pNotUsed, int nBuf, char *zBuf){
+static int unixRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
 
   assert(nBuf>=(sizeof(time_t)+sizeof(int)));
 
@@ -2662,7 +2649,7 @@ static int unixRandomness(void *pNotUsed, int nBuf, char *zBuf){
 ** might be greater than or equal to the argument, but not less
 ** than the argument.
 */
-static int unixSleep(void *pNotUsed, int microseconds){
+static int unixSleep(sqlite3_vfs *pVfs, int microseconds){
 #if defined(HAVE_USLEEP) && HAVE_USLEEP
   usleep(microseconds);
   return microseconds;
@@ -2686,7 +2673,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.
 */
-static int unixCurrentTime(void *pNotUsed, double *prNow){
+static int unixCurrentTime(sqlite3_vfs *pVfs, double *prNow){
 #ifdef NO_GETTOD
   time_t t;
   time(&t);
@@ -2704,29 +2691,38 @@ static int unixCurrentTime(void *pNotUsed, double *prNow){
   return 0;
 }
 
-
-sqlite3_vfs sqlite3DefaultVfs = {
-  1,                  /* iVersion */
-  sizeof(unixFile),   /* szOsFile */
-  MAX_PATHNAME,       /* mxPathname */
-  0,                  /* nRef */
-  0,                  /* vfsMutex */
-  0,                  /* pNext */
-  "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 */
-};
+/*
+** Return a pointer to the sqlite3DefaultVfs structure.   We use
+** a function rather than give the structure global scope because
+** some compilers (MSVC) do not allow forward declarations of
+** initialized structures.
+*/
+sqlite3_vfs *sqlite3OsDefaultVfs(void){
+  static sqlite3_vfs unixVfs = {
+    1,                  /* iVersion */
+    sizeof(unixFile),   /* szOsFile */
+    MAX_PATHNAME,       /* mxPathname */
+    0,                  /* nRef */
+    0,                  /* vfsMutex */
+    0,                  /* pNext */
+    "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 */
+  };
+  
+  return &unixVfs;
+}
  
 #endif /* OS_UNIX */
index 66bf4f6b60f823d1f998817f46c4a8c8aa443f68..6b6496d85afd347133c6fe6940677250c72ef690 100644 (file)
@@ -58,12 +58,12 @@ typedef struct winceLock {
 #endif
 
 /*
-** The winFile structure is a subclass of OsFile specific to the win32
+** The winFile structure is a subclass of sqlite3_file* specific to the win32
 ** portability layer.
 */
 typedef struct winFile winFile;
 struct winFile {
-  IoMethod const *pMethod;/* Must be first */
+  const sqlite3_io_methods *pMethod;/* Must be first */
   HANDLE h;               /* Handle for accessing the file */
   unsigned char locktype; /* Type of lock currently held on this file */
   short sharedLockByte;   /* Randomly chosen byte used as a shared lock */
@@ -77,13 +77,6 @@ struct winFile {
 };
 
 
-/*
-** Do not include any of the File I/O interface procedures if the
-** SQLITE_OMIT_DISKIO macro is defined (indicating that there database
-** will be in-memory only)
-*/
-#ifndef SQLITE_OMIT_DISKIO
-
 /*
 ** The following variable is (normally) set once and never changes
 ** thereafter.  It records whether the operating system is Win95
@@ -96,7 +89,11 @@ struct winFile {
 ** In order to facilitate testing on a WinNT system, the test fixture
 ** can manually set this value to 1 to emulate Win98 behavior.
 */
+#ifdef SQLITE_TEST
 int sqlite3_os_type = 0;
+#else
+static int sqlite3_os_type = 0;
+#endif
 
 /*
 ** Return true (non-zero) if we are running under WinNT, Win2K, WinXP,
@@ -126,20 +123,20 @@ int sqlite3_os_type = 0;
 /*
 ** Convert a UTF-8 string to microsoft unicode (UTF-16?). 
 **
-** Space to hold the returned string is obtained from sqliteMalloc.
+** Space to hold the returned string is obtained from sqlite3_malloc.
 */
 static WCHAR *utf8ToUnicode(const char *zFilename){
   int nChar;
   WCHAR *zWideFilename;
 
   nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
-  zWideFilename = sqliteMalloc( nChar*sizeof(zWideFilename[0]) );
+  zWideFilename = sqlite3_malloc( nChar*sizeof(zWideFilename[0]) );
   if( zWideFilename==0 ){
     return 0;
   }
   nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, nChar);
   if( nChar==0 ){
-    sqliteFree(zWideFilename);
+    sqlite3_free(zWideFilename);
     zWideFilename = 0;
   }
   return zWideFilename;
@@ -147,21 +144,21 @@ static WCHAR *utf8ToUnicode(const char *zFilename){
 
 /*
 ** Convert microsoft unicode to UTF-8.  Space to hold the returned string is
-** obtained from sqliteMalloc().
+** obtained from sqlite3_malloc().
 */
 static char *unicodeToUtf8(const WCHAR *zWideFilename){
   int nByte;
   char *zFilename;
 
   nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0);
-  zFilename = sqliteMalloc( nByte );
+  zFilename = sqlite3_malloc( nByte );
   if( zFilename==0 ){
     return 0;
   }
   nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte,
                               0, 0);
   if( nByte == 0 ){
-    sqliteFree(zFilename);
+    sqlite3_free(zFilename);
     zFilename = 0;
   }
   return zFilename;
@@ -172,7 +169,7 @@ static char *unicodeToUtf8(const WCHAR *zWideFilename){
 ** current codepage settings for file apis.
 ** 
 ** Space to hold the returned string is obtained
-** from sqliteMalloc.
+** from sqlite3_malloc.
 */
 static WCHAR *mbcsToUnicode(const char *zFilename){
   int nByte;
@@ -180,13 +177,13 @@ static WCHAR *mbcsToUnicode(const char *zFilename){
   int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
 
   nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, NULL,0)*sizeof(WCHAR);
-  zMbcsFilename = sqliteMalloc( nByte*sizeof(zMbcsFilename[0]) );
+  zMbcsFilename = sqlite3_malloc( nByte*sizeof(zMbcsFilename[0]) );
   if( zMbcsFilename==0 ){
     return 0;
   }
   nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename, nByte);
   if( nByte==0 ){
-    sqliteFree(zMbcsFilename);
+    sqlite3_free(zMbcsFilename);
     zMbcsFilename = 0;
   }
   return zMbcsFilename;
@@ -197,7 +194,7 @@ static WCHAR *mbcsToUnicode(const char *zFilename){
 ** user's Ansi codepage.
 **
 ** Space to hold the returned string is obtained from
-** sqliteMalloc().
+** sqlite3_malloc().
 */
 static char *unicodeToMbcs(const WCHAR *zWideFilename){
   int nByte;
@@ -205,14 +202,14 @@ static char *unicodeToMbcs(const WCHAR *zWideFilename){
   int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
 
   nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0);
-  zFilename = sqliteMalloc( nByte );
+  zFilename = sqlite3_malloc( nByte );
   if( zFilename==0 ){
     return 0;
   }
   nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, zFilename, nByte,
                               0, 0);
   if( nByte == 0 ){
-    sqliteFree(zFilename);
+    sqlite3_free(zFilename);
     zFilename = 0;
   }
   return zFilename;
@@ -220,7 +217,7 @@ static char *unicodeToMbcs(const WCHAR *zWideFilename){
 
 /*
 ** Convert multibyte character string to UTF-8.  Space to hold the
-** returned string is obtained from sqliteMalloc().
+** returned string is obtained from sqlite3_malloc().
 */
 static char *mbcsToUtf8(const char *zFilename){
   char *zFilenameUtf8;
@@ -231,13 +228,13 @@ static char *mbcsToUtf8(const char *zFilename){
     return 0;
   }
   zFilenameUtf8 = unicodeToUtf8(zTmpWide);
-  sqliteFree(zTmpWide);
+  sqlite3_free(zTmpWide);
   return zFilenameUtf8;
 }
 
 /*
 ** Convert UTF-8 to multibyte character string.  Space to hold the 
-** returned string is obtained from sqliteMalloc().
+** returned string is obtained from sqlite3_malloc().
 */
 static char *utf8ToMbcs(const char *zFilename){
   char *zFilenameMbcs;
@@ -248,7 +245,7 @@ static char *utf8ToMbcs(const char *zFilename){
     return 0;
   }
   zFilenameMbcs = unicodeToMbcs(zTmpWide);
-  sqliteFree(zTmpWide);
+  sqlite3_free(zTmpWide);
   return zFilenameMbcs;
 }
 
@@ -328,7 +325,7 @@ static BOOL winceCreateLock(const char *zFilename, winFile *pFile){
   /* Create/open the named mutex */
   pFile->hMutex = CreateMutexW(NULL, FALSE, zName);
   if (!pFile->hMutex){
-    sqliteFree(zName);
+    sqlite3_free(zName);
     return FALSE;
   }
 
@@ -350,7 +347,7 @@ static BOOL winceCreateLock(const char *zFilename, winFile *pFile){
     bInit = FALSE;
   }
 
-  sqliteFree(zName);
+  sqlite3_free(zName);
 
   /* If we succeeded in making the shared memory handle, map it. */
   if (pFile->hShared){
@@ -409,7 +406,7 @@ static void winceDestroyLock(winFile *pFile){
 
     if( pFile->zDeleteOnClose ){
       DeleteFileW(pFile->zDeleteOnClose);
-      sqliteFree(pFile->zDeleteOnClose);
+      sqlite3_free(pFile->zDeleteOnClose);
       pFile->zDeleteOnClose = 0;
     }
 
@@ -564,400 +561,10 @@ static BOOL winceLockFileEx(
 *****************************************************************************/
 #endif /* OS_WINCE */
 
-/*
-** Convert a UTF-8 filename into whatever form the underlying
-** operating system wants filenames in.  Space to hold the result
-** is obtained from sqliteMalloc and must be freed by the calling
-** function.
-*/
-static void *convertUtf8Filename(const char *zFilename){
-  void *zConverted = 0;
-  if( isNT() ){
-    zConverted = utf8ToUnicode(zFilename);
-  }else{
-    zConverted = utf8ToMbcs(zFilename);
-  }
-  /* caller will handle out of memory */
-  return zConverted;
-}
-
-/*
-** Delete the named file.
-**
-** Note that windows does not allow a file to be deleted if some other
-** process has it open.  Sometimes a virus scanner or indexing program
-** will open a journal file shortly after it is created in order to do
-** whatever it is it does.  While this other process is holding the
-** file open, we will be unable to delete it.  To work around this
-** problem, we delay 100 milliseconds and try to delete again.  Up
-** to MX_DELETION_ATTEMPTs deletion attempts are run before giving
-** up and returning an error.
-*/
-#define MX_DELETION_ATTEMPTS 3
-int sqlite3WinDelete(const char *zFilename){
-  int cnt = 0;
-  int rc;
-  void *zConverted = convertUtf8Filename(zFilename);
-  if( zConverted==0 ){
-    return SQLITE_NOMEM;
-  }
-  SimulateIOError(return SQLITE_IOERR_DELETE);
-  if( isNT() ){
-    do{
-      rc = DeleteFileW(zConverted);
-    }while( rc==0 && GetFileAttributesW(zConverted)!=0xffffffff 
-            && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) );
-  }else{
-#if OS_WINCE
-    return SQLITE_NOMEM;
-#else
-    do{
-      rc = DeleteFileA(zConverted);
-    }while( rc==0 && GetFileAttributesA(zConverted)!=0xffffffff
-            && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) );
-#endif
-  }
-  sqliteFree(zConverted);
-  OSTRACE2("DELETE \"%s\"\n", zFilename);
-  return rc!=0 ? SQLITE_OK : SQLITE_IOERR;
-}
-
-/*
-** Return TRUE if the named file exists.
-*/
-int sqlite3WinFileExists(const char *zFilename){
-  int exists = 0;
-  void *zConverted = convertUtf8Filename(zFilename);
-  if( zConverted==0 ){
-    return SQLITE_NOMEM;
-  }
-  if( isNT() ){
-    exists = GetFileAttributesW((WCHAR*)zConverted) != 0xffffffff;
-  }else{
-#if OS_WINCE
-    return SQLITE_NOMEM;
-#else
-    exists = GetFileAttributesA((char*)zConverted) != 0xffffffff;
-#endif
-  }
-  sqliteFree(zConverted);
-  return exists;
-}
-
-/* Forward declaration */
-static int allocateWinFile(winFile *pInit, OsFile **pId);
-
-/*
-** Attempt to open a file for both reading and writing.  If that
-** fails, try opening it read-only.  If the file does not exist,
-** try to create it.
-**
-** On success, a handle for the open file is written to *id
-** and *pReadonly is set to 0 if the file was opened for reading and
-** writing or 1 if the file was opened read-only.  The function returns
-** SQLITE_OK.
-**
-** On failure, the function returns SQLITE_CANTOPEN and leaves
-** *id and *pReadonly unchanged.
-*/
-int sqlite3WinOpenReadWrite(
-  const char *zFilename,
-  OsFile **pId,
-  int *pReadonly
-){
-  winFile f;
-  HANDLE h;
-  void *zConverted = convertUtf8Filename(zFilename);
-  if( zConverted==0 ){
-    return SQLITE_NOMEM;
-  }
-  assert( *pId==0 );
-
-  if( isNT() ){
-    h = CreateFileW((WCHAR*)zConverted,
-       GENERIC_READ | GENERIC_WRITE,
-       FILE_SHARE_READ | FILE_SHARE_WRITE,
-       NULL,
-       OPEN_ALWAYS,
-       FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
-       NULL
-    );
-    if( h==INVALID_HANDLE_VALUE ){
-      h = CreateFileW((WCHAR*)zConverted,
-         GENERIC_READ,
-         FILE_SHARE_READ | FILE_SHARE_WRITE,
-         NULL,
-         OPEN_ALWAYS,
-         FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
-         NULL
-      );
-      if( h==INVALID_HANDLE_VALUE ){
-        sqliteFree(zConverted);
-        return SQLITE_CANTOPEN;
-      }
-      *pReadonly = 1;
-    }else{
-      *pReadonly = 0;
-    }
-#if OS_WINCE
-    if (!winceCreateLock(zFilename, &f)){
-      CloseHandle(h);
-      sqliteFree(zConverted);
-      return SQLITE_CANTOPEN;
-    }
-#endif
-  }else{
-#if OS_WINCE
-    return SQLITE_NOMEM;
-#else
-    h = CreateFileA((char*)zConverted,
-       GENERIC_READ | GENERIC_WRITE,
-       FILE_SHARE_READ | FILE_SHARE_WRITE,
-       NULL,
-       OPEN_ALWAYS,
-       FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
-       NULL
-    );
-    if( h==INVALID_HANDLE_VALUE ){
-      h = CreateFileA((char*)zConverted,
-         GENERIC_READ,
-         FILE_SHARE_READ | FILE_SHARE_WRITE,
-         NULL,
-         OPEN_ALWAYS,
-         FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
-         NULL
-      );
-      if( h==INVALID_HANDLE_VALUE ){
-        sqliteFree(zConverted);
-        return SQLITE_CANTOPEN;
-      }
-      *pReadonly = 1;
-    }else{
-      *pReadonly = 0;
-    }
-#endif /* OS_WINCE */
-  }
-
-  sqliteFree(zConverted);
-
-  f.h = h;
-#if OS_WINCE
-  f.zDeleteOnClose = 0;
-#endif
-  OSTRACE3("OPEN R/W %d \"%s\"\n", h, zFilename);
-  return allocateWinFile(&f, pId);
-}
-
-
-/*
-** Attempt to open a new file for exclusive access by this process.
-** The file will be opened for both reading and writing.  To avoid
-** a potential security problem, we do not allow the file to have
-** previously existed.  Nor do we allow the file to be a symbolic
-** link.
-**
-** If delFlag is true, then make arrangements to automatically delete
-** the file when it is closed.
-**
-** On success, write the file handle into *id and return SQLITE_OK.
-**
-** On failure, return SQLITE_CANTOPEN.
-**
-** Sometimes if we have just deleted a prior journal file, windows
-** will fail to open a new one because there is a "pending delete".
-** To work around this bug, we pause for 100 milliseconds and attempt
-** a second open after the first one fails.  The whole operation only
-** fails if both open attempts are unsuccessful.
-*/
-int sqlite3WinOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){
-  winFile f;
-  HANDLE h;
-  DWORD fileflags;
-  void *zConverted = convertUtf8Filename(zFilename);
-  if( zConverted==0 ){
-    return SQLITE_NOMEM;
-  }
-  assert( *pId == 0 );
-  fileflags = FILE_FLAG_RANDOM_ACCESS;
-#if !OS_WINCE
-  if( delFlag ){
-    fileflags |= FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE;
-  }
-#endif
-  if( isNT() ){
-    int cnt = 0;
-    do{
-      h = CreateFileW((WCHAR*)zConverted,
-         GENERIC_READ | GENERIC_WRITE,
-         0,
-         NULL,
-         CREATE_ALWAYS,
-         fileflags,
-         NULL
-      );
-    }while( h==INVALID_HANDLE_VALUE && cnt++ < 2 && (Sleep(100), 1) );
-  }else{
-#if OS_WINCE
-    return SQLITE_NOMEM;
-#else
-    int cnt = 0;
-    do{
-      h = CreateFileA((char*)zConverted,
-        GENERIC_READ | GENERIC_WRITE,
-        0,
-        NULL,
-        CREATE_ALWAYS,
-        fileflags,
-        NULL
-      );
-    }while( h==INVALID_HANDLE_VALUE && cnt++ < 2 && (Sleep(100), 1) );
-#endif /* OS_WINCE */
-  }
-#if OS_WINCE
-  if( delFlag && h!=INVALID_HANDLE_VALUE ){
-    f.zDeleteOnClose = zConverted;
-    zConverted = 0;
-  }
-  f.hMutex = NULL;
-#endif
-  sqliteFree(zConverted);
-  if( h==INVALID_HANDLE_VALUE ){
-    return SQLITE_CANTOPEN;
-  }
-  f.h = h;
-  OSTRACE3("OPEN EX %d \"%s\"\n", h, zFilename);
-  return allocateWinFile(&f, pId);
-}
-
-/*
-** Attempt to open a new file for read-only access.
-**
-** On success, write the file handle into *id and return SQLITE_OK.
-**
-** On failure, return SQLITE_CANTOPEN.
-*/
-int sqlite3WinOpenReadOnly(const char *zFilename, OsFile **pId){
-  winFile f;
-  HANDLE h;
-  void *zConverted = convertUtf8Filename(zFilename);
-  if( zConverted==0 ){
-    return SQLITE_NOMEM;
-  }
-  assert( *pId==0 );
-  if( isNT() ){
-    h = CreateFileW((WCHAR*)zConverted,
-       GENERIC_READ,
-       0,
-       NULL,
-       OPEN_EXISTING,
-       FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
-       NULL
-    );
-  }else{
-#if OS_WINCE
-    return SQLITE_NOMEM;
-#else
-    h = CreateFileA((char*)zConverted,
-       GENERIC_READ,
-       0,
-       NULL,
-       OPEN_EXISTING,
-       FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
-       NULL
-    );
-#endif
-  }
-  sqliteFree(zConverted);
-  if( h==INVALID_HANDLE_VALUE ){
-    return SQLITE_CANTOPEN;
-  }
-  f.h = h;
-#if OS_WINCE
-  f.zDeleteOnClose = 0;
-  f.hMutex = NULL;
-#endif
-  OSTRACE3("OPEN RO %d \"%s\"\n", h, zFilename);
-  return allocateWinFile(&f, pId);
-}
-
-/*
-** Attempt to open a file descriptor for the directory that contains a
-** file.  This file descriptor can be used to fsync() the directory
-** in order to make sure the creation of a new file is actually written
-** to disk.
-**
-** This routine is only meaningful for Unix.  It is a no-op under
-** windows since windows does not support hard links.
-**
-** On success, a handle for a previously open file is at *id is
-** updated with the new directory file descriptor and SQLITE_OK is
-** returned.
-**
-** On failure, the function returns SQLITE_CANTOPEN and leaves
-** *id unchanged.
-*/
-static int winOpenDirectory(
-  OsFile *id,
-  const char *zDirname
-){
-  return SQLITE_OK;
-}
-
-/*
-** Create a temporary file name in zBuf.  zBuf must be big enough to
-** hold at least SQLITE_TEMPNAME_SIZE characters.
-*/
-int sqlite3WinTempFileName(char *zBuf){
-  static char zChars[] =
-    "abcdefghijklmnopqrstuvwxyz"
-    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-    "0123456789";
-  int i, j;
-  char zTempPath[SQLITE_TEMPNAME_SIZE];
-  if( sqlite3_temp_directory ){
-    strncpy(zTempPath, sqlite3_temp_directory, SQLITE_TEMPNAME_SIZE-30);
-    zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0;
-  }else if( isNT() ){
-    char *zMulti;
-    WCHAR zWidePath[SQLITE_TEMPNAME_SIZE];
-    GetTempPathW(SQLITE_TEMPNAME_SIZE-30, zWidePath);
-    zMulti = unicodeToUtf8(zWidePath);
-    if( zMulti ){
-      strncpy(zTempPath, zMulti, SQLITE_TEMPNAME_SIZE-30);
-      zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0;
-      sqliteFree(zMulti);
-    }else{
-      return SQLITE_NOMEM;
-    }
-  }else{
-    char *zUtf8;
-    char zMbcsPath[SQLITE_TEMPNAME_SIZE];
-    GetTempPathA(SQLITE_TEMPNAME_SIZE-30, zMbcsPath);
-    zUtf8 = mbcsToUtf8(zMbcsPath);
-    if( zUtf8 ){
-      strncpy(zTempPath, zUtf8, SQLITE_TEMPNAME_SIZE-30);
-      zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0;
-      sqliteFree(zUtf8);
-    }else{
-      return SQLITE_NOMEM;
-    }
-  }
-  for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}
-  zTempPath[i] = 0;
-  for(;;){
-    sqlite3_snprintf(SQLITE_TEMPNAME_SIZE, zBuf,
-                     "%s\\"TEMP_FILE_PREFIX, zTempPath);
-    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;
-    if( !sqlite3OsFileExists(zBuf) ) break;
-  }
-  OSTRACE2("TEMP FILENAME: %s\n", zBuf);
-  return SQLITE_OK; 
-}
+/*****************************************************************************
+** The next group of routines implement the I/O methods specified
+** by the sqlite3_io_methods object.
+******************************************************************************/
 
 /*
 ** Close a file.
@@ -970,36 +577,51 @@ int sqlite3WinTempFileName(char *zBuf){
 ** giving up and returning an error.
 */
 #define MX_CLOSE_ATTEMPT 3
-static int winClose(OsFile **pId){
-  winFile *pFile;
-  int rc = 1;
-  if( pId && (pFile = (winFile*)*pId)!=0 ){
-    int rc, cnt = 0;
-    OSTRACE2("CLOSE %d\n", pFile->h);
-    do{
-      rc = CloseHandle(pFile->h);
-    }while( rc==0 && cnt++ < MX_CLOSE_ATTEMPT && (Sleep(100), 1) );
+static int winClose(sqlite3_file *id){
+  int rc, cnt = 0;
+  winFile *pFile = (winFile*)id;
+  OSTRACE2("CLOSE %d\n", pFile->h);
+  do{
+    rc = CloseHandle(pFile->h);
+  }while( rc==0 && cnt++ < MX_CLOSE_ATTEMPT && (Sleep(100), 1) );
 #if OS_WINCE
-    winceDestroyLock(pFile);
+  winceDestroyLock(pFile);
 #endif
-    OpenCounter(-1);
-    sqliteFree(pFile);
-    *pId = 0;
-  }
+  OpenCounter(-1);
   return rc ? SQLITE_OK : SQLITE_IOERR;
 }
 
+/*
+** Some microsoft compilers lack this definition.
+*/
+#ifndef INVALID_SET_FILE_POINTER
+# define INVALID_SET_FILE_POINTER ((DWORD)-1)
+#endif
+
 /*
 ** Read data from a file into a buffer.  Return SQLITE_OK if all
 ** bytes were read successfully and SQLITE_IOERR if anything goes
 ** wrong.
 */
-static int winRead(OsFile *id, void *pBuf, int amt){
+static int winRead(
+  sqlite3_file *id,          /* File to read from */
+  void *pBuf,                /* Write content into this buffer */
+  int amt,                   /* Number of bytes to read */
+  sqlite3_int64 offset       /* Begin reading at this offset */
+){
+  LONG upperBits = (offset>>32) & 0x7fffffff;
+  LONG lowerBits = offset & 0xffffffff;
+  DWORD rc;
   DWORD got;
+  winFile *pFile = (winFile*)id;
   assert( id!=0 );
   SimulateIOError(return SQLITE_IOERR_READ);
-  OSTRACE3("READ %d lock=%d\n", ((winFile*)id)->h, ((winFile*)id)->locktype);
-  if( !ReadFile(((winFile*)id)->h, pBuf, amt, &got, 0) ){
+  OSTRACE3("READ %d lock=%d\n", pFile->h, pFile->locktype);
+  rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
+  if( rc==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR ){
+    return SQLITE_FULL;
+  }
+  if( !ReadFile(pFile->h, pBuf, amt, &got, 0) ){
     return SQLITE_IOERR_READ;
   }
   if( got==(DWORD)amt ){
@@ -1014,16 +636,31 @@ static int winRead(OsFile *id, void *pBuf, int amt){
 ** Write data from a buffer into a file.  Return SQLITE_OK on success
 ** or some other error code on failure.
 */
-static int winWrite(OsFile *id, const void *pBuf, int amt){
-  int rc = 0;
+static int winWrite(
+  sqlite3_file *id,         /* File to write into */
+  const void *pBuf,         /* The bytes to be written */
+  int amt,                  /* Number of bytes to write */
+  sqlite3_int64 offset      /* Offset into the file to begin writing at */
+){
+  LONG upperBits = (offset>>32) & 0x7fffffff;
+  LONG lowerBits = offset & 0xffffffff;
+  DWORD rc;
   DWORD wrote;
+  winFile *pFile = (winFile*)id;
   assert( id!=0 );
-  SimulateIOError(return SQLITE_IOERR_READ);
+  SimulateIOError(return SQLITE_IOERR_WRITE);
   SimulateDiskfullError(return SQLITE_FULL);
-  OSTRACE3("WRITE %d lock=%d\n", ((winFile*)id)->h, ((winFile*)id)->locktype);
+  OSTRACE3("WRITE %d lock=%d\n", pFile->h, pFile->locktype);
+  rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
+  if( rc==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR ){
+    return SQLITE_FULL;
+  }
   assert( amt>0 );
-  while( amt>0 && (rc = WriteFile(((winFile*)id)->h, pBuf, amt, &wrote, 0))!=0
-         && wrote>0 ){
+  while(
+     amt>0
+     && (rc = WriteFile(pFile->h, pBuf, amt, &wrote, 0))!=0
+     && wrote>0
+  ){
     amt -= wrote;
     pBuf = &((char*)pBuf)[wrote];
   }
@@ -1034,75 +671,41 @@ static int winWrite(OsFile *id, const void *pBuf, int amt){
 }
 
 /*
-** Some microsoft compilers lack this definition.
+** Truncate an open file to a specified size
 */
-#ifndef INVALID_SET_FILE_POINTER
-# define INVALID_SET_FILE_POINTER ((DWORD)-1)
-#endif
-
-/*
-** Move the read/write pointer in a file.
-*/
-static int winSeek(OsFile *id, i64 offset){
-  LONG upperBits = offset>>32;
-  LONG lowerBits = offset & 0xffffffff;
-  DWORD rc;
-  assert( id!=0 );
-#ifdef SQLITE_TEST
-  if( offset ) SimulateDiskfullError(return SQLITE_FULL);
-#endif
-  rc = SetFilePointer(((winFile*)id)->h, lowerBits, &upperBits, FILE_BEGIN);
-  OSTRACE3("SEEK %d %lld\n", ((winFile*)id)->h, offset);
-  if( rc==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR ){
-    return SQLITE_FULL;
-  }
+static int winTruncate(sqlite3_file *id, i64 nByte){
+  LONG upperBits = (nByte>>32) & 0x7fffffff;
+  LONG lowerBits = nByte & 0xffffffff;
+  winFile *pFile = (winFile*)id;
+  OSTRACE3("TRUNCATE %d %lld\n", pFile->h, nByte);
+  SimulateIOError(return SQLITE_IOERR_TRUNCATE);
+  SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
+  SetEndOfFile(pFile->h);
   return SQLITE_OK;
 }
 
 /*
 ** Make sure all writes to a particular file are committed to disk.
 */
-static int winSync(OsFile *id, int dataOnly){
-  assert( id!=0 );
-  OSTRACE3("SYNC %d lock=%d\n", ((winFile*)id)->h, ((winFile*)id)->locktype);
-  if( FlushFileBuffers(((winFile*)id)->h) ){
+static int winSync(sqlite3_file *id, int flags){
+  winFile *pFile = (winFile*)id;
+  OSTRACE3("SYNC %d lock=%d\n", pFile->h, pFile->locktype);
+  if( FlushFileBuffers(pFile->h) ){
     return SQLITE_OK;
   }else{
     return SQLITE_IOERR;
   }
 }
 
-/*
-** Sync the directory zDirname. This is a no-op on operating systems other
-** than UNIX.
-*/
-int sqlite3WinSyncDirectory(const char *zDirname){
-  SimulateIOError(return SQLITE_IOERR_READ);
-  return SQLITE_OK;
-}
-
-/*
-** Truncate an open file to a specified size
-*/
-static int winTruncate(OsFile *id, i64 nByte){
-  LONG upperBits = nByte>>32;
-  assert( id!=0 );
-  OSTRACE3("TRUNCATE %d %lld\n", ((winFile*)id)->h, nByte);
-  SimulateIOError(return SQLITE_IOERR_TRUNCATE);
-  SetFilePointer(((winFile*)id)->h, nByte, &upperBits, FILE_BEGIN);
-  SetEndOfFile(((winFile*)id)->h);
-  return SQLITE_OK;
-}
-
 /*
 ** Determine the current size of a file in bytes
 */
-static int winFileSize(OsFile *id, i64 *pSize){
+static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){
+  winFile *pFile = (winFile*)id;
   DWORD upperBits, lowerBits;
-  assert( id!=0 );
   SimulateIOError(return SQLITE_IOERR_FSTAT);
-  lowerBits = GetFileSize(((winFile*)id)->h, &upperBits);
-  *pSize = (((i64)upperBits)<<32) + lowerBits;
+  lowerBits = GetFileSize(pFile->h, &upperBits);
+  *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits;
   return SQLITE_OK;
 }
 
@@ -1118,19 +721,20 @@ static int winFileSize(OsFile *id, i64 *pSize){
 ** Different API routines are called depending on whether or not this
 ** is Win95 or WinNT.
 */
-static int getReadLock(winFile *id){
+static int getReadLock(winFile *pFile){
   int res;
   if( isNT() ){
     OVERLAPPED ovlp;
     ovlp.Offset = SHARED_FIRST;
     ovlp.OffsetHigh = 0;
     ovlp.hEvent = 0;
-    res = LockFileEx(id->h, LOCKFILE_FAIL_IMMEDIATELY, 0, SHARED_SIZE,0,&ovlp);
+    res = LockFileEx(pFile->h, LOCKFILE_FAIL_IMMEDIATELY,
+                     0, SHARED_SIZE, 0, &ovlp);
   }else{
     int lk;
     sqlite3Randomness(sizeof(lk), &lk);
-    id->sharedLockByte = (lk & 0x7fffffff)%(SHARED_SIZE - 1);
-    res = LockFile(id->h, SHARED_FIRST+id->sharedLockByte, 0, 1, 0);
+    pFile->sharedLockByte = (lk & 0x7fffffff)%(SHARED_SIZE - 1);
+    res = LockFile(pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0);
   }
   return res;
 }
@@ -1148,39 +752,6 @@ static int unlockReadLock(winFile *pFile){
   return res;
 }
 
-#ifndef SQLITE_OMIT_PAGER_PRAGMAS
-/*
-** Check that a given pathname is a directory and is writable 
-**
-*/
-int sqlite3WinIsDirWritable(char *zDirname){
-  int fileAttr;
-  void *zConverted;
-  if( zDirname==0 ) return 0;
-  if( !isNT() && strlen(zDirname)>MAX_PATH ) return 0;
-
-  zConverted = convertUtf8Filename(zDirname);
-  if( zConverted==0 ){
-    return SQLITE_NOMEM;
-  }
-  if( isNT() ){
-    fileAttr = GetFileAttributesW((WCHAR*)zConverted);
-  }else{
-#if OS_WINCE
-    return 0;
-#else
-    fileAttr = GetFileAttributesA((char*)zConverted);
-#endif
-  }
-  sqliteFree(zConverted);
-  if( fileAttr == 0xffffffff ) return 0;
-  if( (fileAttr & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY ){
-    return 0;
-  }
-  return 1;
-}
-#endif /* SQLITE_OMIT_PAGER_PRAGMAS */
-
 /*
 ** Lock the file with the lock specified by parameter locktype - one
 ** of the following:
@@ -1207,10 +778,10 @@ int sqlite3WinIsDirWritable(char *zDirname){
 ** It is not possible to lower the locking level one step at a time.  You
 ** must go straight to locking level 0.
 */
-static int winLock(OsFile *id, int locktype){
+static int winLock(sqlite3_file *id, int locktype){
   int rc = SQLITE_OK;    /* Return code from subroutines */
   int res = 1;           /* Result of a windows lock call */
-  int newLocktype;       /* Set id->locktype to this value before exiting */
+  int newLocktype;       /* Set pFile->locktype to this value before exiting */
   int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */
   winFile *pFile = (winFile*)id;
 
@@ -1319,7 +890,7 @@ static int winLock(OsFile *id, int locktype){
 ** file by this or any other process. If such a lock is held, return
 ** non-zero, otherwise zero.
 */
-static int winCheckReservedLock(OsFile *id){
+static int winCheckReservedLock(sqlite3_file *id){
   int rc;
   winFile *pFile = (winFile*)id;
   assert( pFile!=0 );
@@ -1348,10 +919,10 @@ static int winCheckReservedLock(OsFile *id){
 ** is NO_LOCK.  If the second argument is SHARED_LOCK then this routine
 ** might return SQLITE_IOERR;
 */
-static int winUnlock(OsFile *id, int locktype){
+static int winUnlock(sqlite3_file *id, int locktype){
   int type;
-  int rc = SQLITE_OK;
   winFile *pFile = (winFile*)id;
+  int rc = SQLITE_OK;
   assert( pFile!=0 );
   assert( locktype<=SHARED_LOCK );
   OSTRACE5("UNLOCK %d to %d was %d(%d)\n", pFile->h, locktype,
@@ -1379,75 +950,19 @@ static int winUnlock(OsFile *id, int locktype){
 }
 
 /*
-** 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.
+** Currently unimplemented
 */
-char *sqlite3WinFullPathname(const char *zRelative){
-  char *zFull;
-#if defined(__CYGWIN__)
-  int nByte;
-  nByte = strlen(zRelative) + MAX_PATH + 1001;
-  zFull = sqliteMalloc( nByte );
-  if( zFull==0 ) return 0;
-  if( cygwin_conv_to_full_win32_path(zRelative, zFull) ) return 0;
-#elif OS_WINCE
-  /* WinCE has no concept of a relative pathname, or so I am told. */
-  zFull = sqliteStrDup(zRelative);
-#else
-  int nByte;
-  void *zConverted;
-  zConverted = convertUtf8Filename(zRelative);
-  if( isNT() ){
-    WCHAR *zTemp;
-    nByte = GetFullPathNameW((WCHAR*)zConverted, 0, 0, 0) + 3;
-    zTemp = sqliteMalloc( nByte*sizeof(zTemp[0]) );
-    if( zTemp==0 ){
-      sqliteFree(zConverted);
-      return 0;
-    }
-    GetFullPathNameW((WCHAR*)zConverted, nByte, zTemp, 0);
-    sqliteFree(zConverted);
-    zFull = unicodeToUtf8(zTemp);
-    sqliteFree(zTemp);
-  }else{
-    char *zTemp;
-    nByte = GetFullPathNameA((char*)zConverted, 0, 0, 0) + 3;
-    zTemp = sqliteMalloc( nByte*sizeof(zTemp[0]) );
-    if( zTemp==0 ){
-      sqliteFree(zConverted);
-      return 0;
-    }
-    GetFullPathNameA((char*)zConverted, nByte, zTemp, 0);
-    sqliteFree(zConverted);
-    zFull = mbcsToUtf8(zTemp);
-    sqliteFree(zTemp);
-  }
-#endif
-  return zFull;
-}
-
-/*
-** The fullSync option is meaningless on windows.   This is a no-op.
-*/
-static void winSetFullSync(OsFile *id, int v){
-  return;
-}
-
-/*
-** Return the underlying file handle for an OsFile
-*/
-static int winFileHandle(OsFile *id){
-  return (int)((winFile*)id)->h;
+static int winBreakLock(sqlite3_file *id){
+  return SQLITE_ERROR;
 }
 
 /*
 ** Return an integer that indices the type of lock currently held
 ** by this handle.  (Used for testing and analysis only.)
 */
-static int winLockState(OsFile *id){
-  return ((winFile*)id)->locktype;
+static int winLockState(sqlite3_file *id){
+  winFile *pFile = (winFile*)id;
+  return pFile->locktype;
 }
 
 /*
@@ -1460,71 +975,378 @@ static int winLockState(OsFile *id){
 ** a database and it's journal file) that the sector size will be the
 ** same for both.
 */
-static int winSectorSize(OsFile *id){
+static int winSectorSize(sqlite3_file *id){
   return SQLITE_DEFAULT_SECTOR_SIZE;
 }
 
 /*
-** This vector defines all the methods that can operate on an OsFile
-** for win32.
+** Return a vector of device characteristics.
 */
-static const IoMethod sqlite3WinIoMethod = {
+static int winDeviceCharacteristics(sqlite3_file *id){
+  return 0;
+}
+
+/*
+** This vector defines all the methods that can operate on an
+** sqlite3_file for win32.
+*/
+static const sqlite3_io_methods winIoMethod = {
+  1,                        /* iVersion */
   winClose,
-  winOpenDirectory,
   winRead,
   winWrite,
-  winSeek,
   winTruncate,
   winSync,
-  winSetFullSync,
-  winFileHandle,
   winFileSize,
   winLock,
   winUnlock,
-  winLockState,
   winCheckReservedLock,
+  winBreakLock,
+  winLockState,
   winSectorSize,
+  winDeviceCharacteristics
 };
 
+/***************************************************************************
+** Here ends the I/O methods that form the sqlite3_io_methods object.
+**
+** The next block of code implements the VFS methods.
+****************************************************************************/
+
 /*
-** Allocate memory for an OsFile.  Initialize the new OsFile
-** to the value given in pInit and return a pointer to the new
-** OsFile.  If we run out of memory, close the file and return NULL.
+** Convert a UTF-8 filename into whatever form the underlying
+** operating system wants filenames in.  Space to hold the result
+** is obtained from sqlite3_malloc and must be freed by the calling
+** function.
 */
-static int allocateWinFile(winFile *pInit, OsFile **pId){
-  winFile *pNew;
-  pNew = sqliteMalloc( sizeof(*pNew) );
-  if( pNew==0 ){
-    CloseHandle(pInit->h);
+static void *convertUtf8Filename(const char *zFilename){
+  void *zConverted = 0;
+  if( isNT() ){
+    zConverted = utf8ToUnicode(zFilename);
+  }else{
+    zConverted = utf8ToMbcs(zFilename);
+  }
+  /* caller will handle out of memory */
+  return zConverted;
+}
+
+/*
+** Open a file.
+*/
+static int winOpen(
+  sqlite3_vfs *pVfs,        /* Not used */
+  const char *zName,        /* Name of the file (UTF-8) */
+  sqlite3_file *id,         /* Write the SQLite file handle here */
+  int flags,                /* Open mode flags */
+  int *pOutFlags            /* Status return flags */
+){
+  HANDLE h;
+  DWORD dwDesiredAccess;
+  DWORD dwShareMode;
+  DWORD dwCreationDisposition;
+  DWORD dwFlagsAndAttributes = 0;
+  winFile *pFile = (winFile*)id;
+  void *zConverted = convertUtf8Filename(zName);
+  if( zConverted==0 ){
+    return SQLITE_NOMEM;
+  }
+
+  if( flags & SQLITE_OPEN_READWRITE ){
+    dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
+  }else{
+    dwDesiredAccess = GENERIC_READ;
+  }
+  if( flags & SQLITE_OPEN_CREATE ){
+    dwCreationDisposition = OPEN_ALWAYS;
+  }else{
+    dwCreationDisposition = OPEN_EXISTING;
+  }
+  if( flags & SQLITE_OPEN_MAIN_DB ){
+    dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
+  }else{
+    dwShareMode = 0;
+  }
+  if( flags & (SQLITE_OPEN_TEMP_DB | SQLITE_OPEN_TEMP_JOURNAL
+                    | SQLITE_OPEN_SUBJOURNAL) ){
+    dwFlagsAndAttributes = FILE_ATTRIBUTE_TEMPORARY
+                               | FILE_ATTRIBUTE_HIDDEN
+                               | FILE_FLAG_DELETE_ON_CLOSE;
+  }else{
+    dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
+  }
+  if( flags & (SQLITE_OPEN_MAIN_DB | SQLITE_OPEN_TEMP_DB) ){
+    dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
+  }else{
+    dwFlagsAndAttributes |= FILE_FLAG_SEQUENTIAL_SCAN;
+  }
+  if( isNT() ){
+    h = CreateFileW((WCHAR*)zConverted,
+       dwDesiredAccess,
+       dwShareMode,
+       NULL,
+       dwCreationDisposition,
+       dwFlagsAndAttributes,
+       NULL
+    );
+  }else{
+#if OS_WINCE
+    return SQLITE_NOMEM;
+#else
+    h = CreateFileA((char*)zConverted,
+       dwDesiredAccess,
+       dwShareMode,
+       NULL,
+       dwCreationDisposition,
+       dwFlagsAndAttributes,
+       NULL
+    );
+#endif
+  }
+  if( h==INVALID_HANDLE_VALUE ){
+    if( flags & SQLITE_OPEN_READWRITE ){
+      sqlite3_free(zConverted);
+      return winOpen(0, zName, id, 
+             ((flags|SQLITE_OPEN_READONLY)&~SQLITE_OPEN_READWRITE), pOutFlags);
+    }else{
+      return SQLITE_CANTOPEN;
+    }
+  }
+  if( pOutFlags ){
+    if( flags & SQLITE_OPEN_READWRITE ){
+      *pOutFlags = SQLITE_OPEN_READWRITE;
+    }else{
+      *pOutFlags = SQLITE_OPEN_READONLY;
+    }
+  }
+  memset(pFile, 0, sizeof(*pFile));
+  pFile->pMethod = &winIoMethod;
+  pFile->h = h;
 #if OS_WINCE
-    sqliteFree(pInit->zDeleteOnClose);
+  if( (flags & (SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB)) ==
+               (SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB)
+       && !winceCreateLock(zFilename, &f)
+  ){
+    CloseHandle(h);
+    sqlite3_free(zConverted);
+    return SQLITE_CANTOPEN;
+  }
+  if( dwFlagsAndAttributes & FILE_FLAG_DELETEONCLOSE ){
+    pFile->zDeleteOnClose = zConverted;
+  }else
 #endif
-    *pId = 0;
+  {
+    sqlite3_free(zConverted);
+  }
+  return SQLITE_OK;
+}
+
+/*
+** Delete the named file.
+**
+** Note that windows does not allow a file to be deleted if some other
+** process has it open.  Sometimes a virus scanner or indexing program
+** will open a journal file shortly after it is created in order to do
+** whatever it is it does.  While this other process is holding the
+** file open, we will be unable to delete it.  To work around this
+** problem, we delay 100 milliseconds and try to delete again.  Up
+** to MX_DELETION_ATTEMPTs deletion attempts are run before giving
+** up and returning an error.
+*/
+#define MX_DELETION_ATTEMPTS 3
+static int winDelete(
+  sqlite3_vfs *pVfs,          /* Not used on win32 */
+  const char *zFilename,      /* Name of file to delete */
+  int syncDir                 /* Not used on win32 */
+){
+  int cnt = 0;
+  int rc;
+  void *zConverted = convertUtf8Filename(zFilename);
+  if( zConverted==0 ){
     return SQLITE_NOMEM;
+  }
+  SimulateIOError(return SQLITE_IOERR_DELETE);
+  if( isNT() ){
+    do{
+      rc = DeleteFileW(zConverted);
+    }while( rc==0 && GetFileAttributesW(zConverted)!=0xffffffff 
+            && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) );
   }else{
-    *pNew = *pInit;
-    pNew->pMethod = &sqlite3WinIoMethod;
-    pNew->locktype = NO_LOCK;
-    pNew->sharedLockByte = 0;
-    *pId = (OsFile*)pNew;
-    OpenCounter(+1);
-    return SQLITE_OK;
+#if OS_WINCE
+    return SQLITE_NOMEM;
+#else
+    do{
+      rc = DeleteFileA(zConverted);
+    }while( rc==0 && GetFileAttributesA(zConverted)!=0xffffffff
+            && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) );
+#endif
   }
+  sqlite3_free(zConverted);
+  OSTRACE2("DELETE \"%s\"\n", zFilename);
+  return rc!=0 ? SQLITE_OK : SQLITE_IOERR;
 }
 
+/*
+** Check the existance and status of a file.
+*/
+static int winAccess(
+  sqlite3_vfs *pVfs,         /* Not used on win32 */
+  const char *zFilename,     /* Name of file to check */
+  int flags                  /* Type of test to make on this file */
+){
+  DWORD attr;
+  int rc;
+  void *zConverted = convertUtf8Filename(zFilename);
+  if( zConverted==0 ){
+    return SQLITE_NOMEM;
+  }
+  if( isNT() ){
+    attr = GetFileAttributesW((WCHAR*)zConverted);
+  }else{
+#if OS_WINCE
+    return SQLITE_NOMEM;
+#else
+    attr = GetFileAttributesA((char*)zConverted);
+#endif
+  }
+  sqlite3_free(zConverted);
+  switch( flags ){
+    case SQLITE_ACCESS_EXISTS:
+      rc = attr!=0xffffffff;
+      break;
+    case SQLITE_ACCESS_READWRITE:
+      rc = (attr & FILE_ATTRIBUTE_READONLY)==0;
+      break;
+    case SQLITE_ACCESS_READONLY:
+      rc = (attr!=0xffffffff) && ((attr & FILE_ATTRIBUTE_READONLY)==1);
+      break;
+    default:
+      assert(!"Invalid flags argument");
+  }
+  return rc;
+}
 
-#endif /* SQLITE_OMIT_DISKIO */
-/***************************************************************************
-** Everything above deals with file I/O.  Everything that follows deals
-** with other miscellanous aspects of the operating system interface
-****************************************************************************/
 
-#if !defined(SQLITE_OMIT_LOAD_EXTENSION)
+/*
+** Create a temporary file name in zBuf.  zBuf must be big enough to
+** hold at pVfs->mxPathname characters.
+*/
+static int winGetTempName(sqlite3_vfs *pVfs, char *zBuf){
+  static char zChars[] =
+    "abcdefghijklmnopqrstuvwxyz"
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+    "0123456789";
+  int i, j;
+  char zTempPath[MAX_PATH+1];
+  if( sqlite3_temp_directory ){
+    sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory);
+  }else if( isNT() ){
+    char *zMulti;
+    WCHAR zWidePath[MAX_PATH];
+    GetTempPathW(MAX_PATH-30, zWidePath);
+    zMulti = unicodeToUtf8(zWidePath);
+    if( zMulti ){
+      sqlite3_snprintf(MAX_PATH-30, zTempPath, "%z", zMulti);
+    }else{
+      return SQLITE_NOMEM;
+    }
+  }else{
+    char *zUtf8;
+    char zMbcsPath[MAX_PATH];
+    GetTempPathA(MAX_PATH-30, zMbcsPath);
+    zUtf8 = mbcsToUtf8(zMbcsPath);
+    if( zUtf8 ){
+      sqlite3_snprintf(MAX_PATH-30, zTempPath, "%z", zUtf8);
+    }else{
+      return SQLITE_NOMEM;
+    }
+  }
+  for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}
+  zTempPath[i] = 0;
+  for(;;){
+    sqlite3_snprintf(pVfs->mxPathname-30, zBuf,
+                     "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath);
+    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;
+    if( !sqlite3OsAccess(pVfs, zBuf, SQLITE_ACCESS_EXISTS) ) break;
+  }
+  OSTRACE2("TEMP FILENAME: %s\n", zBuf);
+  return SQLITE_OK; 
+}
+
+/*
+** Turn a relative pathname into a full pathname.  Write the full
+** pathname into zOut[].  zOut[] will be at least pVfs->mxPathname
+** bytes in size.
+*/
+static int winFullPathname(
+  sqlite3_vfs *pVfs,          
+  const char *zRelative,
+  char *zFull
+){
+
+#if defined(__CYGWIN__)
+  cygwin_conv_to_full_win32_path(zRelative, zFull);
+  return SQLITE_OK
+#endif
+
+#if OS_WINCE
+  /* WinCE has no concept of a relative pathname, or so I am told. */
+  sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zRelative);
+#endif
+
+#if !OS_WINCE && !defined(__CYGWIN__)
+  int nByte;
+  void *zConverted;
+  char *zOut;
+  zConverted = convertUtf8Filename(zRelative);
+  if( isNT() ){
+    WCHAR *zTemp;
+    nByte = GetFullPathNameW((WCHAR*)zConverted, 0, 0, 0) + 3;
+    zTemp = sqlite3_malloc( nByte*sizeof(zTemp[0]) );
+    if( zTemp==0 ){
+      sqlite3_free(zConverted);
+      return SQLITE_NOMEM;
+    }
+    GetFullPathNameW((WCHAR*)zConverted, nByte, zTemp, 0);
+    sqlite3_free(zConverted);
+    zOut = unicodeToUtf8(zTemp);
+    sqlite3_free(zTemp);
+  }else{
+    char *zTemp;
+    nByte = GetFullPathNameA((char*)zConverted, 0, 0, 0) + 3;
+    zTemp = sqlite3_malloc( nByte*sizeof(zTemp[0]) );
+    if( zTemp==0 ){
+      sqlite3_free(zConverted);
+      return SQLITE_NOMEM;
+    }
+    GetFullPathNameA((char*)zConverted, nByte, zTemp, 0);
+    sqlite3_free(zConverted);
+    zOut = mbcsToUtf8(zTemp);
+    sqlite3_free(zTemp);
+  }
+  if( zOut ){
+    sqlite3_snprintf(pVfs->mxPathname, zFull, "%z", zOut);
+    return SQLITE_OK;
+  }else{
+    return SQLITE_NOMEM;
+  }
+#endif
+}
+
+#ifndef SQLITE_OMIT_LOAD_EXTENSION
 /*
 ** Interfaces for opening a shared library, finding entry points
 ** within the shared library, and closing the shared library.
 */
-void *sqlite3WinDlopen(const char *zFilename){
+/*
+** Interfaces for opening a shared library, finding entry points
+** within the shared library, and closing the shared library.
+*/
+static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){
   HANDLE h;
   void *zConverted = convertUtf8Filename(zFilename);
   if( zConverted==0 ){
@@ -1539,11 +1361,21 @@ void *sqlite3WinDlopen(const char *zFilename){
     h = LoadLibraryA((char*)zConverted);
 #endif
   }
-  sqliteFree(zConverted);
+  sqlite3_free(zConverted);
   return (void*)h;
-  
 }
-void *sqlite3WinDlsym(void *pHandle, const char *zSymbol){
+static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
+  FormatMessage(
+    FORMAT_MESSAGE_FROM_SYSTEM,
+    NULL,
+    GetLastError(),
+    0,
+    zBufOut,
+    nBuf-1,
+    0
+  );
+}
+void *winDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){
 #if OS_WINCE
   /* The GetProcAddressA() routine is only available on wince. */
   return GetProcAddressA((HANDLE)pHandle, zSymbol);
@@ -1553,104 +1385,38 @@ void *sqlite3WinDlsym(void *pHandle, const char *zSymbol){
   return GetProcAddress((HANDLE)pHandle, zSymbol);
 #endif
 }
-int sqlite3WinDlclose(void *pHandle){
-  return FreeLibrary((HANDLE)pHandle);
-}
-#endif /* !SQLITE_OMIT_LOAD_EXTENSION */
-
-/*
-** 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 sqlite3WinRandomSeed(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
-  ** uninitialized space in zBuf - but valgrind errors tend to worry
-  ** some users.  Rather than argue, it seems easier just to initialize
-  ** the whole array and silence valgrind, even if that means less randomness
-  ** in the random seed.
-  **
-  ** When testing, initializing zBuf[] to zero is all we do.  That means
-  ** that we always use the same random number sequence.* This makes the
-  ** tests repeatable.
-  */
-  memset(zBuf, 0, 256);
-  GetSystemTime((LPSYSTEMTIME)zBuf);
-  return SQLITE_OK;
+void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
+  FreeLibrary((HANDLE)pHandle);
 }
+#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
+  #define winDlOpen  0
+  #define winDlError 0
+  #define winDlSym   0
+  #define winDlClose 0
+#endif
 
-/*
-** Sleep for a little while.  Return the amount of time slept.
-*/
-int sqlite3WinSleep(int ms){
-  Sleep(ms);
-  return ms;
-}
 
 /*
-** Static variables used for thread synchronization
+** Write up to nBuf bytes of randomness into zBuf.
 */
-static int inMutex = 0;
-#ifdef SQLITE_W32_THREADS
-  static DWORD mutexOwner;
-  static CRITICAL_SECTION cs;
-#endif
-
-/*
-** The following pair of routines 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.
-**
-** Version 3.3.1 and earlier used a simple mutex.  Beginning with
-** version 3.3.2, a recursive mutex is required.
-*/
-void sqlite3WinEnterMutex(){
-#ifdef SQLITE_W32_THREADS
-  static int isInit = 0;
-  while( !isInit ){
-    static long lock = 0;
-    if( InterlockedIncrement(&lock)==1 ){
-      InitializeCriticalSection(&cs);
-      isInit = 1;
-    }else{
-      Sleep(1);
-    }
+static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
+  if( sizeof(LPSYSTEMTIME)>=nBuf ){
+    GetSystemTime((LPSYSTEMTIME)zBuf);
+    return sizeof(LPSYSTEMTIME);
+  }else{
+    return 0;
   }
-  EnterCriticalSection(&cs);
-  mutexOwner = GetCurrentThreadId();
-#endif
-  inMutex++;
-}
-void sqlite3WinLeaveMutex(){
-  assert( inMutex );
-  inMutex--;
-#ifdef SQLITE_W32_THREADS
-  assert( mutexOwner==GetCurrentThreadId() );
-  LeaveCriticalSection(&cs);
-#endif
 }
 
+
 /*
-** Return TRUE if the mutex is currently held.
-**
-** If the thisThreadOnly parameter is true, return true if and only if the
-** calling thread holds the mutex.  If the parameter is false, return
-** true if any thread holds the mutex.
+** Sleep for a little while.  Return the amount of time slept.
 */
-int sqlite3WinInMutex(int thisThreadOnly){
-#ifdef SQLITE_W32_THREADS
-  return inMutex>0 && (thisThreadOnly==0 || mutexOwner==GetCurrentThreadId());
-#else
-  return inMutex>0;
-#endif
+static int winSleep(sqlite3_vfs *pVfs, int microsec){
+  Sleep((microsec+999)/1000);
+  return ((microsec+999)/1000)*1000;
 }
 
-
 /*
 ** The following variable, if set to a non-zero value, becomes the result
 ** returned from sqlite3OsCurrentTime().  This is used for testing.
@@ -1664,7 +1430,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 sqlite3WinCurrentTime(double *prNow){
+int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){
   FILETIME ft;
   /* FILETIME structure is a 64-bit value representing the number of 
      100-nanosecond intervals since January 1, 1601 (= JD 2305813.5). 
@@ -1687,71 +1453,39 @@ int sqlite3WinCurrentTime(double *prNow){
   return 0;
 }
 
-/*
-** Remember the number of thread-specific-data blocks allocated.
-** Use this to verify that we are not leaking thread-specific-data.
-** Ticket #1601
-*/
-#ifdef SQLITE_TEST
-int sqlite3_tsd_count = 0;
-# define TSD_COUNTER_INCR InterlockedIncrement(&sqlite3_tsd_count)
-# define TSD_COUNTER_DECR InterlockedDecrement(&sqlite3_tsd_count)
-#else
-# define TSD_COUNTER_INCR  /* no-op */
-# define TSD_COUNTER_DECR  /* no-op */
-#endif
-
-
 
 /*
-** If called with allocateFlag>1, then return a pointer to thread
-** specific data for the current thread.  Allocate and zero the
-** thread-specific data if it does not already exist necessary.
-**
-** If called with allocateFlag==0, then check the current thread
-** specific data.  Return it if it exists.  If it does not exist,
-** then return NULL.
-**
-** If called with allocateFlag<0, check to see if the thread specific
-** data is allocated and is all zero.  If it is then deallocate it.
-** Return a pointer to the thread specific data or NULL if it is
-** unallocated or gets deallocated.
+** Return a pointer to the sqlite3DefaultVfs structure.   We use
+** a function rather than give the structure global scope because
+** some compilers (MSVC) do not allow forward declarations of
+** initialized structures.
 */
-ThreadData *sqlite3WinThreadSpecificData(int allocateFlag){
-  static int key;
-  static int keyInit = 0;
-  static const ThreadData zeroData = {0};
-  ThreadData *pTsd;
-
-  if( !keyInit ){
-    sqlite3OsEnterMutex();
-    if( !keyInit ){
-      key = TlsAlloc();
-      if( key==0xffffffff ){
-        sqlite3OsLeaveMutex();
-        return 0;
-      }
-      keyInit = 1;
-    }
-    sqlite3OsLeaveMutex();
-  }
-  pTsd = TlsGetValue(key);
-  if( allocateFlag>0 ){
-    if( !pTsd ){
-      pTsd = sqlite3OsMalloc( sizeof(zeroData) );
-      if( pTsd ){
-        *pTsd = zeroData;
-        TlsSetValue(key, pTsd);
-        TSD_COUNTER_INCR;
-      }
-    }
-  }else if( pTsd!=0 && allocateFlag<0 
-              && memcmp(pTsd, &zeroData, sizeof(ThreadData))==0 ){
-    sqlite3OsFree(pTsd);
-    TlsSetValue(key, 0);
-    TSD_COUNTER_DECR;
-    pTsd = 0;
-  }
-  return pTsd;
+sqlite3_vfs *sqlite3OsDefaultVfs(void){
+  static sqlite3_vfs winVfs = {
+    1,                 /* iVersion */
+    sizeof(winFile),   /* szOsFile */
+    MAX_PATH,          /* mxPathname */
+    0,                 /* nRef */
+    0,                 /* vfsMutex */
+    0,                 /* pNext */
+    "win32",           /* zName */
+    0,                 /* pAppData */
+  
+    winOpen,           /* xOpen */
+    winDelete,         /* xDelete */
+    winAccess,         /* xAccess */
+    winGetTempName,    /* xGetTempName */
+    winFullPathname,   /* xFullPathname */
+    winDlOpen,         /* xDlOpen */
+    winDlError,        /* xDlError */
+    winDlSym,          /* xDlSym */
+    winDlClose,        /* xDlClose */
+    winRandomness,     /* xRandomness */
+    winSleep,          /* xSleep */
+    winCurrentTime     /* xCurrentTime */
+  };
+  
+  return &winVfs;
 }
+
 #endif /* OS_WIN */
index 504bfcbf1b0795c61044cbebee43fba706e61256..2c5c9cab6ca7f210824f722a7f1aeeed0b4505ce 100644 (file)
@@ -18,7 +18,7 @@
 ** file simultaneously, or one process from reading the database while
 ** another is writing.
 **
-** @(#) $Id: pager.c,v 1.371 2007/08/23 14:48:24 danielk1977 Exp $
+** @(#) $Id: pager.c,v 1.372 2007/08/24 03:51:34 drh Exp $
 */
 #ifndef SQLITE_OMIT_DISKIO
 #include "sqliteInt.h"
@@ -1873,7 +1873,6 @@ int sqlite3PagerOpen(
 ){
   u8 *pPtr;
   Pager *pPager = 0;
-  char *zFullPathname = 0;
   int rc = SQLITE_OK;
   int i;
   int tempFile = 0;
@@ -1905,8 +1904,7 @@ int sqlite3PagerOpen(
   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).
+  /* Open the pager file.
   */
   if( zFilename && zFilename[0] ){
 #ifndef SQLITE_OMIT_MEMORYDB
@@ -1942,9 +1940,9 @@ int sqlite3PagerOpen(
     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 
+  /* If an error occured in either of the blocks above.
+  ** 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 || !pPager->pTmpSpace ){
@@ -1953,8 +1951,8 @@ int sqlite3PagerOpen(
     return ((rc==SQLITE_OK)?SQLITE_NOMEM:rc);
   }
 
-  PAGERTRACE3("OPEN %d %s\n", FILEHANDLEID(pPager->fd), zFullPathname);
-  IOTRACE(("OPEN %p %s\n", pPager, zFullPathname))
+  PAGERTRACE3("OPEN %d %s\n", FILEHANDLEID(pPager->fd), pPager->zFilename);
+  IOTRACE(("OPEN %p %s\n", pPager, pPager->zFilename))
 
   /* Fill in Pager.zDirectory[] */
   memcpy(pPager->zDirectory, pPager->zFilename, pVfs->mxPathname);
@@ -2682,6 +2680,7 @@ static PgHdr *sort_pagelist(PgHdr *pIn){
 */
 static int pager_write_pagelist(PgHdr *pList){
   Pager *pPager;
+  PgHdr *p;
   int rc;
 
   if( pList==0 ) return SQLITE_OK;
@@ -2709,6 +2708,10 @@ static int pager_write_pagelist(PgHdr *pList){
   }
 
   pList = sort_pagelist(pList);
+  for(p=pList; p; p=p->pDirty){
+    assert( p->dirty );
+    p->dirty = 0;
+  }
   while( pList ){
 
     /* If the file has not yet been opened, open it now. */
@@ -2718,7 +2721,6 @@ static int pager_write_pagelist(PgHdr *pList){
       if( rc ) return rc;
     }
 
-    assert( pList->dirty );
     /* If there are dirty pages in the page cache with page numbers greater
     ** than Pager.dbSize, this means sqlite3PagerTruncate() was called to
     ** make the file smaller (presumably by auto-vacuum code). Do not write
@@ -2743,7 +2745,6 @@ static int pager_write_pagelist(PgHdr *pList){
     }
 #endif
     if( rc ) return rc;
-    pList->dirty = 0;
 #ifdef SQLITE_CHECK_PAGES
     pList->pageHash = pager_pagehash(pList);
 #endif
@@ -2846,6 +2847,7 @@ static int pager_recycle(Pager *pPager, int syncOk, PgHdr **ppPg){
     pPg->dirty = 1;
     pPg->pDirty = 0;
     rc = pager_write_pagelist( pPg );
+    pPg->dirty = 0;
     if( rc!=SQLITE_OK ){
       return rc;
     }
@@ -3698,11 +3700,14 @@ static void makeClean(PgHdr *pPg){
   if( pPg->dirty ){
     pPg->dirty = 0;
     if( pPg->pDirty ){
+      assert( pPg->pDirty->pPrevDirty==pPg );
       pPg->pDirty->pPrevDirty = pPg->pPrevDirty;
     }
     if( pPg->pPrevDirty ){
+      assert( pPg->pPrevDirty->pDirty==pPg );
       pPg->pPrevDirty->pDirty = pPg->pDirty;
     }else{
+      assert( pPg->pPager->pDirty==pPg );
       pPg->pPager->pDirty = pPg->pDirty;
     }
   }
@@ -4263,7 +4268,11 @@ int sqlite3PagerCommitPhaseOne(Pager *pPager, const char *zMaster, Pgno nTrunc){
     /* Write all dirty pages to the database file */
     pPg = pager_get_all_dirty_pages(pPager);
     rc = pager_write_pagelist(pPg);
-    if( rc!=SQLITE_OK ) goto sync_exit;
+    if( rc!=SQLITE_OK ){
+      while( pPg && !pPg->dirty ){ pPg = pPg->pDirty; }
+      pPager->pDirty = pPg;
+      goto sync_exit;
+    }
     pPager->pDirty = 0;
 
     /* Sync the database file. */
index ece53b7fd49797d6a6a3036ae425836abdbe4c48..37390a5f00cf3f6d86b8cdee4f619bc5688bc1f3 100644 (file)
@@ -113,7 +113,7 @@ static const et_info fmtinfo[] = {
   {  'd', 10, 1, etRADIX,      0,  0 },
   {  's',  0, 4, etSTRING,     0,  0 },
   {  'g',  0, 1, etGENERIC,    30, 0 },
-  {  'z',  0, 6, etDYNSTRING,  0,  0 },
+  {  'z',  0, 4, etDYNSTRING,  0,  0 },
   {  'q',  0, 4, etSQLESCAPE,  0,  0 },
   {  'Q',  0, 4, etSQLESCAPE2, 0,  0 },
   {  'w',  0, 4, etSQLESCAPE3, 0,  0 },
index b6b56686e8b37cb17b035ce2b3352ceb1a1bf0a0..bd813a222bfbc3040e1bceaa2bcd12b69fc14dfe 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.238 2007/08/23 02:47:53 drh Exp $
+** @(#) $Id: sqlite.h.in,v 1.239 2007/08/24 03:51:34 drh Exp $
 */
 #ifndef _SQLITE3_H_
 #define _SQLITE3_H_
@@ -339,10 +339,10 @@ int sqlite3_exec(
 #define SQLITE_OPEN_EXCLUSIVE        0x00000010
 #define SQLITE_OPEN_MAIN_DB          0x00000100
 #define SQLITE_OPEN_TEMP_DB          0x00000200
-#define SQLITE_OPEN_MAIN_JOURNAL     0x00000300
-#define SQLITE_OPEN_TEMP_JOURNAL     0x00000400
-#define SQLITE_OPEN_SUBJOURNAL       0x00000500
-#define SQLITE_OPEN_MASTER_JOURNAL   0x00000600
+#define SQLITE_OPEN_MAIN_JOURNAL     0x00000400
+#define SQLITE_OPEN_TEMP_JOURNAL     0x00000800
+#define SQLITE_OPEN_SUBJOURNAL       0x00001000
+#define SQLITE_OPEN_MASTER_JOURNAL   0x00002000
 
 /*
 ** CAPI3REF: Device Characteristics
@@ -424,7 +424,7 @@ int sqlite3_exec(
 */
 typedef struct sqlite3_file sqlite3_file;
 struct sqlite3_file {
-  struct sqlite3_io_methods *pMethods;  /* Methods against the open file */
+  const struct sqlite3_io_methods *pMethods;  /* Methods for an open file */
 };
 
 /*
@@ -552,10 +552,10 @@ typedef struct sqlite3_mutex sqlite3_mutex;
 ** nRef transitions from 1 to 0.
 **
 ** Registered vfs modules are kept on a linked list formed by
-** the pNext and pPrev pointers.  The [sqlite3_register_vfs()]
+** the pNext pointer.  The [sqlite3_register_vfs()]
 ** and [sqlite3_unregister_vfs()] interfaces manage this list
-** in a thread-safe way.  The [sqlite3_acquire_vfs()] searches the
-** list.
+** in a thread-safe way.  The [sqlite3_find_vfs()] interface
+** searches the list.
 **
 ** The zName field holds the name of the VFS module.  The name must
 ** be unique across all VFS modules.
@@ -644,19 +644,19 @@ struct sqlite3_vfs {
   sqlite3_vfs *pNext;      /* Next registered VFS */
   const char *zName;       /* Name of this virtual file system */
   void *pAppData;          /* Application context */
-  int (*xOpen)(void *pAppData, const char *zName, sqlite3_file*,
+  int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*,
                int flags, int *pOutFlags);
-  int (*xDelete)(void *pAppData, const char *zName, int syncDir);
-  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, const char *zFilename);
-  void (*xDlError)(void *pAppData, int nByte, char *zErrMsg);
-  void *(*xDlSym)(void*, const char *zSymbol);
-  void (*xDlClose)(void*);
-  int (*xRandomness)(void *pAppData, int nByte, char *zOut);
-  int (*xSleep)(void *pAppData, int microseconds);
-  int (*xCurrentTime)(void *pAppData, double*);
+  int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir);
+  int (*xAccess)(sqlite3_vfs*, const char *zName, int flags);
+  int (*xGetTempName)(sqlite3_vfs*, char *zOut);
+  int (*xFullPathname)(sqlite3_vfs*, const char *zName, char *zOut);
+  void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename);
+  void (*xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg);
+  void *(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol);
+  void (*xDlClose)(sqlite3_vfs*, void*);
+  int (*xRandomness)(sqlite3_vfs*, int nByte, char *zOut);
+  int (*xSleep)(sqlite3_vfs*, int microseconds);
+  int (*xCurrentTime)(sqlite3_vfs*, double*);
   /* New fields may be appended in figure versions.  The iVersion
   ** value will increment whenever this happens. */
 };
@@ -997,7 +997,7 @@ void sqlite3_free_table(char **result);
 ** These routines all implement some additional formatting
 ** options that are useful for constructing SQL statements.
 ** All of the usual printf formatting options apply.  In addition, there
-** is are "%q" and "%Q" options.
+** is are "%q", "%Q", and "%z" options.
 **
 ** The %q option works like %s in that it substitutes a null-terminated
 ** string from the argument list.  But %q also doubles every '\'' character.
@@ -1050,6 +1050,10 @@ void sqlite3_free_table(char **result);
 **
 ** The code above will render a correct SQL statement in the zSQL
 ** variable even if the zText variable is a NULL pointer.
+**
+** The "%z" formatting option works exactly like "%s" with the
+** addition that after the string has been read and copied into
+** the result, [sqlite3_free()] is called on the input string.
 */
 char *sqlite3_mprintf(const char*,...);
 char *sqlite3_vmprintf(const char*, va_list);
@@ -1092,8 +1096,8 @@ void sqlite3_free(void*);
 ** are provided by the default memory subsystem for diagnostic
 ** purposes.
 */
-sqlite3_uint64 sqlite3_memory_used(void);
-sqlite3_uint64 sqlite3_memory_highwater(int resetFlag);
+sqlite3_int64 sqlite3_memory_used(void);
+sqlite3_int64 sqlite3_memory_highwater(int resetFlag);
 
 /*
 ** CAPI3REF: Memory Allocation Alarms
@@ -1124,9 +1128,9 @@ sqlite3_uint64 sqlite3_memory_highwater(int resetFlag);
 ** [sqlite3_soft_heap_limit()] module.
 */
 int sqlite3_memory_alarm(
-  void(*xCallback)(void *pArg, sqlite3_uint64 used, unsigned int N),
+  void(*xCallback)(void *pArg, sqlite3_int64 used, int N),
   void *pArg,
-  sqlite3_uint64 iThreshold
+  sqlite3_int64 iThreshold
 );
 
 
index 902a1efa3f3faeac57952dfd75dd533a074357f0..90bdba1f9bc74abf600f8265c80c7dda5f644dcd 100644 (file)
@@ -678,7 +678,7 @@ static int crashParamsObjCmd(
 ){
   int iDelay;
   const char *zCrashFile;
-  int nCrashFile;
+  int nCrashFile, iDc, iSectorSize;
 
   static sqlite3_vfs crashVfs = {
     1,                  /* iVersion */
@@ -704,6 +704,7 @@ static int crashParamsObjCmd(
     cfCurrentTime         /* xCurrentTime */
   };
 
+
   if( crashVfs.pAppData==0 ){
     sqlite3_vfs *pOriginalVfs = sqlite3_vfs_find(0);
     crashVfs.xDlError = pOriginalVfs->xDlError;
@@ -717,8 +718,8 @@ static int crashParamsObjCmd(
     sqlite3_vfs_register(&crashVfs, 1);
   }
 
-  int iDc = -1;
-  int iSectorSize = -1;
+  iDc = -1;
+  iSectorSize = -1;
 
   if( objc<3 ){
     Tcl_WrongNumArgs(interp, 1, objv, "?OPTIONS? DELAY CRASHFILE");
index 3952882295e0ca43e58a06ebe879026117b360ca..d09f3e8993b49285a333920a10f80259af91df1f 100644 (file)
@@ -13,7 +13,7 @@
 ** This file contains code used to implement test interfaces to the
 ** memory allocation subsystem.
 **
-** $Id: test_malloc.c,v 1.4 2007/08/23 02:47:53 drh Exp $
+** $Id: test_malloc.c,v 1.5 2007/08/24 03:51:34 drh Exp $
 */
 #include "sqliteInt.h"
 #include "tcl.h"
@@ -287,25 +287,6 @@ static int test_memdebug_fail(
 }
 
 
-/*
-** Usage:    sqlite3_memdebug_pending
-**
-** Return the number of successful mallocs remaining before the
-** next simulated failure.  Return -1 if no simulated failure is
-** currently scheduled.
-*/
-static int test_memdebug_pending(
-  void * clientData,
-  Tcl_Interp *interp,
-  int objc,
-  Tcl_Obj *CONST objv[]
-){
-  extern int sqlite3_memdebug_pending(void);
-  Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_memdebug_pending()));
-  return TCL_OK;
-}
-
-
 /*
 ** Usage:    sqlite3_memdebug_settitle TITLE
 **
@@ -354,7 +335,6 @@ int Sqlitetest_malloc_Init(Tcl_Interp *interp){
      { "sqlite3_memdebug_backtrace", test_memdebug_backtrace       },
      { "sqlite3_memdebug_dump",      test_memdebug_dump            },
      { "sqlite3_memdebug_fail",      test_memdebug_fail            },
-     { "sqlite3_memdebug_pending",   test_memdebug_pending         },
      { "sqlite3_memdebug_settitle",  test_memdebug_settitle        },
   };
   int i;
index fc7fc73f56a1a46e4aa3c71804466de2441fe874..1ad103e821ca658fff71618d3ea7f7ab02231611 100644 (file)
@@ -702,9 +702,9 @@ static const void *columnName(
     n = sqlite3_column_count(pStmt);
     if( N<n && N>=0 ){
       N += useType*n;
+      sqlite3_mutex_enter(p->db->mutex);
       ret = xFunc(&p->aColName[N]);
 
-#if 0
       /* A malloc may have failed inside of the xFunc() call. If this
       ** is the case, clear the mallocFailed flag and return NULL.
       */
@@ -712,7 +712,7 @@ static const void *columnName(
         p->db->mallocFailed = 0;
         ret = 0;
       }
-#endif
+      sqlite3_mutex_leave(p->db->mutex);
     }
   }
   return ret;
index ff93ac52984fa3384b8029c0f76b6d28880503a9..b133f44e21fbf561d7c8369c71c2fd1c02d45da5 100644 (file)
@@ -1007,7 +1007,6 @@ static void Cleanup(Vdbe *p){
 void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){
   Mem *pColName;
   int n;
-  sqlite3 *db = p->db;
 
   releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
   sqlite3_free(p->aColName);
@@ -1017,7 +1016,7 @@ void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){
   if( p->aColName==0 ) return;
   while( n-- > 0 ){
     pColName->flags = MEM_Null;
-    pColName->db = db;
+    pColName->db = p->db;
     pColName++;
   }
 }
index 09793aef7524a5fc033386aaec022a5f3c7d5434..70d7efc17e7e7afee741acac89992e48faef82a2 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** This file contains code used to help implement virtual tables.
 **
-** $Id: vtab.c,v 1.53 2007/08/23 02:47:53 drh Exp $
+** $Id: vtab.c,v 1.54 2007/08/24 03:51:34 drh Exp $
 */
 #ifndef SQLITE_OMIT_VIRTUALTABLE
 #include "sqliteInt.h"
@@ -24,10 +24,11 @@ static int createModule(
   void (*xDestroy)(void *)        /* Module destructor function */
 ) {
   int rc, nName;
+  Module *pMod;
 
   sqlite3_mutex_enter(db->mutex);
   nName = strlen(zName);
-  Module *pMod = (Module *)sqlite3DbMallocRaw(db, sizeof(Module) + nName + 1);
+  pMod = (Module *)sqlite3DbMallocRaw(db, sizeof(Module) + nName + 1);
   if( pMod ){
     char *zCopy = (char *)(&pMod[1]);
     memcpy(zCopy, zName, nName+1);
index d81a5e72f3a026abe683451e15d9836cbbfdc183..0983fecde346b907e26002c9d229cc6ff865894f 100644 (file)
@@ -12,7 +12,7 @@
 # focus of this file is testing for correct handling of disk full
 # errors.
 # 
-# $Id: diskfull.test,v 1.6 2007/04/05 17:15:53 danielk1977 Exp $
+# $Id: diskfull.test,v 1.7 2007/08/24 03:51:34 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -113,4 +113,3 @@ do_diskfull_test diskfull-2 VACUUM
 # }
 
 finish_test
-