]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Changes to crash-test io backend (test6.c) so that it works with the sqlite3_vfs...
authordanielk1977 <danielk1977@noemail.net>
Mon, 20 Aug 2007 14:23:44 +0000 (14:23 +0000)
committerdanielk1977 <danielk1977@noemail.net>
Mon, 20 Aug 2007 14:23:44 +0000 (14:23 +0000)
FossilOrigin-Name: 40f66ada815fa1043d24c9cd6d898e1797e7044a

manifest
manifest.uuid
src/os.c
src/os.h
src/os_unix.c
src/sqliteInt.h
src/test2.c
src/test6.c
src/vdbeaux.c
test/crash.test
test/tester.tcl

index 50b04ea25224d655433f653e52990cfcdc2f1e7a..eb0dda6375b664c8e759138bb30597ee8963ea73 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Bug\sfix\sin\sBTree\sshared\scache\slocking\scode.\s(CVS\s4246)
-D 2007-08-20T13:14:29
+C Changes\sto\scrash-test\sio\sbackend\s(test6.c)\sso\sthat\sit\sworks\swith\sthe\ssqlite3_vfs\sinterface.\s(CVS\s4247)
+D 2007-08-20T14:23:44
 F Makefile.in 0c0e53720f658c7a551046442dd7afba0b72bfbe
 F Makefile.linux-gcc 65241babba6faf1152bf86574477baab19190499
 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@@ -91,14 +91,14 @@ F src/md5.c c5fdfa5c2593eaee2e32a5ce6c6927c986eaf217
 F src/mem1.c 30bf8be3846f92fdf88c490c5e5378512383bcbe
 F src/mem2.c 661ca7ebf6e4b964fecc95d24e8c89dbcfc9dfea
 F src/mutex.c 67b2efd36a1e67a7dc7b7fa852fd69953462c943
-F src/os.c f08ddf81e0e66e4196a3e0b13d4330c1400783c1
-F src/os.h 447a22462d4cc5e570269451122767e8cd27097d
+F src/os.c 68c46a16bcd47aa3f9418a01dc2812b1ff2c4c17
+F src/os.h da098cad985b4849fefdd6a96d671b332008aa55
 F src/os_common.h a5c446d3b93f09f369d13bf217de4bed3437dd1c
 F src/os_os2.c cba4e96fadb949076c717108fe0599d1a3c2e446
 F src/os_os2.h e5f17dd69333632bbc3112881ea407c37d245eb3
 F src/os_test.c 49833426101f99aee4bb5f6a44b7c4b2029fda1c
 F src/os_test.h 903c93554c23d88f34f667f1979e4a1cee792af3
-F src/os_unix.c dc726e5fa18f114c4a7e0a0205af0ea898b85374
+F src/os_unix.c 7ff8ad09e8e8b6b32e8b5441dc7b9b6b93126e2b
 F src/os_unix.h 5768d56d28240d3fe4537fac08cc85e4fb52279e
 F src/os_win.c d868d5f9e95ec9c1b9e2a30c54c996053db6dddd
 F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
@@ -114,16 +114,16 @@ F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
 F src/shell.c ac29402b538515fa4697282387be9c1205e6e9eb
 F src/sqlite.h.in a0baef0f4c969a4eb9dfc9096bf527ca543485e5
 F src/sqlite3ext.h 647a6b8a8f76ff6c9611e4a071531d8e63ff2d6b
-F src/sqliteInt.h 442a6861cf3f535f410acad19a55b2fbca2564a7
+F src/sqliteInt.h 8932f2a2f855e5ce566ab3805002f074eb56ae11
 F src/sqliteLimit.h f14609c27636ebc217c9603ade26dbdd7d0f6afa
 F src/table.c c725e47f6f3092b9a7b569fc58e408e2173ee008
 F src/tclsqlite.c 0606c4f31711492eb4d7480a981eebb80914f3d9
 F src/test1.c a226ab03048491aa6c5d43d26097df96bdb162e7
-F src/test2.c 8dc9775a8419cd2238bbfdea3023f7325e227f92
+F src/test2.c 016380989929fd41bdf790058b1f2fd698f8af28
 F src/test3.c b87e8fcce45e1d3153aae9f04236076b7707a714
 F src/test4.c d22cb3ab4f9fdfd0a595b70d5328cee923b7322c
 F src/test5.c 7bc8a87c2b6fd076ec2ca9972946e71a367883ad
-F src/test6.c 80990810f64ee96ba27cda5c09624bff383caa60
+F src/test6.c d67117b2c1df9b07889f3f3779ecc9ec2663fd1e
 F src/test7.c 91d914c2c2b2806157213f41f4185ad3a4970c07
 F src/test8.c 719c284607c1e91a893f5425df1e92b74c859aef
 F src/test9.c c0f38f7795cc51d37db6c63874d90f40f10d0f0e
@@ -148,7 +148,7 @@ F src/vdbe.c b5cd895a0516466daacc564da332589a903e2eb0
 F src/vdbe.h 001c5b257567c1d3de7feb2203aac71d0d7b16a3
 F src/vdbeInt.h 8e360d326328e7a66100f468697edf9cfb4567dc
 F src/vdbeapi.c ddfe341249929b89c47a0ff77f8043ef0987612b
-F src/vdbeaux.c 93724b681d2ff57f4dfca9e5a08fab7b6126d15d
+F src/vdbeaux.c d2e8a63e9aea8527c79ae523036cc8f762b267a2
 F src/vdbeblob.c cf9ee3c7d9977cbd896f8b118da4fb4268637f4f
 F src/vdbefifo.c 334c838c8f42d61a94813d136019ee566b5dc2f6
 F src/vdbemem.c 019952d44066a24aef70ca8c284cfd2d1073c398
@@ -212,7 +212,7 @@ F test/conflict.test ac40064d46c4c259cf6c216d30aa5bcc26e7eea2
 F test/corrupt.test 18c7a995b1af76a8c8600b996257f2c7b7bff083
 F test/corrupt2.test 572f8df0303d0ce63ddad5c5c9101a83a345ae46
 F test/corrupt3.test 263e8bb04e2728df832fddf6973cf54c91db0c32
-F test/crash.test 0ba9b7927aaf2f3273e822883b5792a183ac73f0
+F test/crash.test 24020168cc42977a4dd83ff78d2b5eb6577715db
 F test/crash2.test 423c6ec404d15b7d7d0e40aef0a26740cce6075f
 F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2
 F test/createtab.test b562aba1a65be49935fc43a04e90766e39231804
@@ -382,7 +382,7 @@ F test/table.test dbdfd06aef054ad5aed8e57a782137d57d5c5528
 F test/tableapi.test 036575a98dcce7c92e9f39056839bbad8a715412
 F test/tclsqlite.test 593f3b30221e85786965d9e5670ae4f96b4e4159
 F test/temptable.test c36f3e5a94507abb64f7ba23deeb4e1a8a8c3821
-F test/tester.tcl 2169504ebe6066f7044a161468102aa5096a05cd
+F test/tester.tcl 7907d791de322547e496a28b50de41b564d3a5fc
 F test/thread1.test 776c9e459b75ba905193b351926ac4019b049f35
 F test/thread2.test 6d7b30102d600f51b4055ee3a5a19228799049fb
 F test/threadtest1.c 6029d9c5567db28e6dc908a0c63099c3ba6c383b
@@ -529,7 +529,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
 F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
-P b27f022fb924709f1c5e4642d5d59cab942e826d
-R ee810a3824b25c07a2182b7d0dedc3f5
-U drh
-Z 6c13724b198dff1360ddd718c375cb8a
+P 399d3e755253a7b4604a62b9f171e0f1154134e2
+R 11c9693db5cee2a6ec7dbd494d6d3816
+U danielk1977
+Z caa76f353403fee76761d1f63fcb3a63
index b9a8e486e101f69dcca3547681cde8b1fc02122c..cdeee9aa7338e753bb3d6604938b48661fe12336 100644 (file)
@@ -1 +1 @@
-399d3e755253a7b4604a62b9f171e0f1154134e2
\ No newline at end of file
+40f66ada815fa1043d24c9cd6d898e1797e7044a
\ No newline at end of file
index f7aedd7361416fa4437797893cc3dd74483c85ef..73f067bbcf8247ee404d523f3711f810ef539c3b 100644 (file)
--- a/src/os.c
+++ b/src/os.c
@@ -57,7 +57,7 @@ int sqlite3OsCheckReservedLock(sqlite3_file *id){
 }
 int sqlite3OsSectorSize(sqlite3_file *id){
   int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize;
-  return xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE;
+  return (xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE);
 }
 int sqlite3OsDeviceCharacteristics(sqlite3_file *id){
   return id->pMethods->xDeviceCharacteristics(id);
@@ -81,6 +81,9 @@ int sqlite3OsOpen(
   int flags, 
   int *pFlagsOut
 ){
+#if defined(SQLITE_TEST) && !defined(SQLITE_OMIT_DISKIO)
+  return sqlite3CrashFileOpen(pVfs, zPath, pFile, flags, pFlagsOut);
+#endif
   return pVfs->xOpen(pVfs->pAppData, zPath, pFile, flags, pFlagsOut);
 }
 int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
@@ -121,13 +124,14 @@ int sqlite3OsOpenMalloc(
   sqlite3_vfs *pVfs, 
   const char *zFile, 
   sqlite3_file **ppFile, 
-  int flags
+  int flags,
+  int *pOutFlags
 ){
   int rc = SQLITE_NOMEM;
   sqlite3_file *pFile;
   pFile = (sqlite3_file *)sqlite3_malloc(pVfs->szOsFile);
   if( pFile ){
-    rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, 0);
+    rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags);
     if( rc!=SQLITE_OK ){
       sqlite3_free(pFile);
     }else{
index fadf1c821abc36816a6f8bf82c0001717f293fee..7dfcda6dba690c3efe742d7b0ae68feb097a3ed7 100644 (file)
--- a/src/os.h
+++ b/src/os.h
@@ -259,7 +259,7 @@ int sqlite3OsCurrentTime(sqlite3_vfs *, double*);
 ** Convenience functions for opening and closing files using 
 ** sqlite3_malloc() to obtain space for the file-handle structure.
 */
-int sqlite3OsOpenMalloc(sqlite3_vfs *, const char *, sqlite3_file **, int); 
+int sqlite3OsOpenMalloc(sqlite3_vfs *, const char *, sqlite3_file **, int,int*);
 int sqlite3OsCloseFree(sqlite3_file *);
 
 #if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
index f1575562ed6620aa71f06a1dfc9a5109b7073eb3..828bbfd6288c30a5c0b0aa52e5fbcb2ce4ec14e9 100644 (file)
 typedef struct unixFile unixFile;
 struct unixFile {
   sqlite3_io_methods const *pMethod;  /* Always the first entry */
+#ifdef SQLITE_TEST
+  /* In test mode, increase the size of this structure a bit so that 
+  ** it is larger than the struct CrashFile defined in test6.c.
+  */
+  char aPadding[32];
+#endif
   struct openCnt *pOpen;    /* Info about all open fd's on this inode */
   struct lockInfo *pLock;   /* Info about locks on this inode */
 #ifdef SQLITE_ENABLE_LOCKING_STYLE
@@ -96,32 +102,11 @@ struct unixFile {
   unsigned char locktype;   /* The type of lock held on this fd */
   unsigned char isOpen;     /* True if needs to be closed */
   int dirfd;                /* File descriptor for the directory */
-  i64 offset;               /* Seek offset */
 #ifdef SQLITE_UNIX_THREADS
   pthread_t tid;            /* The thread that "owns" this unixFile */
 #endif
 };
 
-
-/*
-** Provide the ability to override some OS-layer functions during
-** testing.  This is used to simulate OS crashes to verify that 
-** commits are atomic even in the event of an OS crash.
-*/
-#ifdef SQLITE_CRASH_TEST
-  extern int sqlite3CrashTestEnable;
-  int sqlite3CrashFileWrap(sqlite3_file *, const char *, sqlite3_file **);
-  static int CRASH_TEST_OVERRIDE(const char *zFile, sqlite3_file **pId, int rc){
-    if( rc==SQLITE_OK && sqlite3CrashTestEnable ){
-      rc = sqlite3CrashFileWrap(*pId, zFile, pId); 
-    }
-    return rc;
-  }
-#else
-# define CRASH_TEST_OVERRIDE(A,B,C) C
-#endif
-
-
 /*
 ** Include code that is common to all os_*.c files
 */
@@ -819,7 +804,7 @@ static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){
   got = read(id->h, pBuf, cnt);
 #endif
   TIMER_END;
-  OSTRACE5("READ    %-3d %5d %7lld %d\n", id->h, got, id->offset, TIMER_ELAPSED);
+  OSTRACE5("READ    %-3d %5d %7lld %d\n", id->h, got, offset, TIMER_ELAPSED);
   return got;
 }
 
index 7ae793c6022f6d6556717ba484b3fa0a2e9a1fe1..a3899c572bcf3ba14e870f696f2ac294aa940213 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.591 2007/08/17 15:53:37 danielk1977 Exp $
+** @(#) $Id: sqliteInt.h,v 1.592 2007/08/20 14:23:44 danielk1977 Exp $
 */
 #ifndef _SQLITEINT_H_
 #define _SQLITEINT_H_
@@ -1850,6 +1850,7 @@ void sqlite3InvalidFunction(sqlite3_context*,int,sqlite3_value**);
 int sqlite3Reprepare(Vdbe*);
 void sqlite3ExprListCheckLength(Parse*, ExprList*, int, const char*);
 CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *);
+int sqlite3CrashFileOpen(sqlite3_vfs*, const char*, sqlite3_file*, int,int*);
 
 #if SQLITE_MAX_EXPR_DEPTH>0
   void sqlite3ExprSetHeight(Expr *);
index d6dfa75df58cd4f19753bae80d26385c11ad8967..c819ee3ea0f0205cabd4c4b3f4724199e402c147 100644 (file)
@@ -13,7 +13,7 @@
 ** is not included in the SQLite library.  It is used for automated
 ** testing of the SQLite library.
 **
-** $Id: test2.c,v 1.47 2007/08/18 10:59:21 danielk1977 Exp $
+** $Id: test2.c,v 1.48 2007/08/20 14:23:44 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -542,7 +542,7 @@ static int fake_big_file(
 
   pVfs = sqlite3_find_vfs(0);
   rc = sqlite3OsOpenMalloc(pVfs, argv[2], &fd, 
-      (SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB)
+      (SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB), 0
   );
   if( rc ){
     Tcl_AppendResult(interp, "open failed: ", errorName(rc), 0);
index cc02b5f31538a5bc8c96e31b3a0ef638dac339ab..66b0128468b902771d7bf5be5ddc211d6916eedd 100644 (file)
@@ -126,10 +126,16 @@ struct CrashFile {
   const sqlite3_io_methods *pMethod;   /* Must be first */
   sqlite3_file *pRealFile;             /* Underlying "real" file handle */
   char *zName;
+
+  /* Cache of the entire file. */
+  int iSize;                           /* Size of file in bytes */
+  int nData;                           /* Size of buffer allocated at zData */
+  u8 *zData;                           /* Buffer containing file contents */
 };
 
 struct CrashGlobal {
   WriteBuffer *pWriteList;     /* Head of write-list */
+  WriteBuffer *pWriteListEnd;  /* End of write-list */
 
   int iSectorSize;             /* Value of simulated sector size */
   int iDeviceCharacteristics;  /* Value of simulated device characteristics */
@@ -138,12 +144,12 @@ struct CrashGlobal {
   char zCrashFile[500];        /* Crash during an xSync() on this file */ 
 };
 
-static CrashGlobal g = {0, SQLITE_DEFAULT_SECTOR_SIZE, 0, 0};
+static CrashGlobal g = {0, 0, SQLITE_DEFAULT_SECTOR_SIZE, 0, 0};
 
 /*
 ** Set this global variable to 1 to enable crash testing.
 */
-int sqlite3CrashTestEnable = 0;
+static int sqlite3CrashTestEnable = 0;
 
 /*
 ** Flush the write-list as if xSync() had been called on file handle
@@ -152,6 +158,7 @@ int sqlite3CrashTestEnable = 0;
 static int writeListSync(CrashFile *pFile, int isCrash){
   int rc = SQLITE_OK;
   int iDc = g.iDeviceCharacteristics;
+  i64 iSize;
 
   WriteBuffer *pWrite;
   WriteBuffer **ppPtr;
@@ -168,8 +175,11 @@ static int writeListSync(CrashFile *pFile, int isCrash){
     }
   }
 
+  sqlite3OsFileSize((sqlite3_file *)pFile, &iSize);
+
   ppPtr = &g.pWriteList;
   for(pWrite=*ppPtr; rc==SQLITE_OK && pWrite; pWrite=*ppPtr){
+    sqlite3_file *pRealFile = pWrite->pFile->pRealFile;
 
     /* (eAction==1)      -> write block out normally,
     ** (eAction==2)      -> do nothing,
@@ -200,10 +210,10 @@ static int writeListSync(CrashFile *pFile, int isCrash){
       case 1: {               /* Write out correctly */
         if( pWrite->zBuf ){
           rc = sqlite3OsWrite(
-              pFile->pRealFile, pWrite->zBuf, pWrite->nBuf, pWrite->iOffset
+              pRealFile, pWrite->zBuf, pWrite->nBuf, pWrite->iOffset
           );
         }else{
-          rc = sqlite3OsTruncate(pFile->pRealFile, pWrite->iOffset);
+          rc = sqlite3OsTruncate(pRealFile, pWrite->iOffset);
         }
         *ppPtr = pWrite->pNext;
         sqlite3_free(pWrite);
@@ -215,8 +225,10 @@ static int writeListSync(CrashFile *pFile, int isCrash){
       }
       case 3: {               /* Trash sectors */
         u8 *zGarbage;
-        sqlite3_int64 iFirst = (pWrite->iOffset%g.iSectorSize);
-        sqlite3_int64 iLast = (pWrite->iOffset+pWrite->nBuf-1)%g.iSectorSize;
+        int iFirst = (pWrite->iOffset/g.iSectorSize);
+        int iLast = (pWrite->iOffset+pWrite->nBuf-1)/g.iSectorSize;
+
+        assert(pWrite->zBuf);
 
         zGarbage = sqlite3_malloc(g.iSectorSize);
         if( zGarbage ){
@@ -224,7 +236,7 @@ static int writeListSync(CrashFile *pFile, int isCrash){
           for(i=iFirst; rc==SQLITE_OK && i<=iLast; i++){
             sqlite3Randomness(g.iSectorSize, zGarbage); 
             rc = sqlite3OsWrite(
-              pFile->pRealFile, zGarbage, g.iSectorSize, i*g.iSectorSize
+              pRealFile, zGarbage, g.iSectorSize, i*g.iSectorSize
             );
           }
           sqlite3_free(zGarbage);
@@ -247,6 +259,9 @@ static int writeListSync(CrashFile *pFile, int isCrash){
     exit(-1);
   }
 
+  for(pWrite=g.pWriteList; pWrite && pWrite->pNext; pWrite=pWrite->pNext);
+  g.pWriteListEnd = pWrite;
+
   return rc;
 }
 
@@ -273,12 +288,12 @@ static int writeListAppend(
   }
 
   if( g.pWriteList ){
-    WriteBuffer *pEnd;
-    for(pEnd=g.pWriteList; pEnd->pNext; pEnd=pEnd->pNext);
-    pEnd->pNext = pNew;
+    assert(g.pWriteListEnd);
+    g.pWriteListEnd->pNext = pNew;
   }else{
     g.pWriteList = pNew;
   }
+  g.pWriteListEnd = pNew;
   
   return SQLITE_OK;
 }
@@ -289,7 +304,7 @@ static int writeListAppend(
 static int cfClose(sqlite3_file *pFile){
   CrashFile *pCrash = (CrashFile *)pFile;
   writeListSync(pCrash, 0);
-  sqlite3OsClose(&pCrash->pRealFile);
+  sqlite3OsCloseFree(pCrash->pRealFile);
   return SQLITE_OK;
 }
 
@@ -304,63 +319,15 @@ static int cfRead(
 ){
   CrashFile *pCrash = (CrashFile *)pFile;
   sqlite3_int64 iSize;
-  int rc;
   WriteBuffer *pWrite;
 
   /* Check the file-size to see if this is a short-read */
-  rc = sqlite3OsFileSize(pFile, &iSize);
-  if( rc!=SQLITE_OK ){
-    return rc;
-  }
-  if( iSize<(iOfst+iAmt) ){
+  if( pCrash->iSize<(iOfst+iAmt) ){
     return SQLITE_IOERR_SHORT_READ;
   }
 
-  /* Zero the output buffer */
-  memset(zBuf, 0, iAmt);
-
-  /* Read some data from the real file */
-  rc = sqlite3OsFileSize(pCrash->pRealFile, &iSize);
-  if( rc==SQLITE_OK && iSize>iOfst ){
-    int nRead = iAmt;
-    if( iSize<(iOfst+iAmt) ){
-      nRead = iSize - iOfst;
-    }
-    rc = sqlite3OsRead(pCrash->pRealFile, zBuf, nRead, iOfst);
-  }
-
-  /* Fill in the buffer by traversing the write-list */
-  for(pWrite=g.pWriteList; rc==SQLITE_OK && pWrite; pWrite=pWrite->pNext){
-    if( pWrite->pFile==pCrash ){
-      int iWriteOffset;
-      int nWriteBuf;
-      u8 *zWriteBuf;
-
-      iWriteOffset = pWrite->iOffset - iOfst;
-      nWriteBuf = pWrite->nBuf;
-      zWriteBuf = pWrite->zBuf;
-      if( iWriteOffset<0 ){
-        nWriteBuf += iWriteOffset;
-        zWriteBuf -= iWriteOffset;
-        iWriteOffset = 0;
-      }
-      if( (iWriteOffset+nWriteBuf)>iAmt ){
-        nWriteBuf = iAmt - iWriteOffset;
-      }
-      
-      if( pWrite->zBuf && nWriteBuf>0){
-        /* Copy data to the buffer */
-        memcpy(&((u8 *)zBuf)[iWriteOffset], zWriteBuf, nWriteBuf);
-      }
-
-      if( pWrite->zBuf==0 && iWriteOffset<iAmt ){
-        /* Zero part of the buffer to simulate a truncate */
-        memset(&((u8 *)zBuf)[iWriteOffset], 0, iAmt-iWriteOffset);
-      }
-    }
-  }
-
-  return rc;
+  memcpy(zBuf, &pCrash->zData[iOfst], iAmt);
+  return SQLITE_OK;
 }
 
 /*
@@ -372,6 +339,22 @@ static int cfWrite(
   int iAmt, 
   sqlite_int64 iOfst
 ){
+  CrashFile *pCrash = (CrashFile *)pFile;
+  if( iAmt+iOfst>pCrash->iSize ){
+    pCrash->iSize = iAmt+iOfst;
+  }
+  while( pCrash->iSize>pCrash->nData ){
+    char *zNew;
+    int nNew = (pCrash->nData*2) + 4096;
+    zNew = (char *)sqlite3_realloc(pCrash->zData, nNew);
+    if( !zNew ){
+      return SQLITE_NOMEM;
+    }
+    memset(&zNew[pCrash->nData], 0, nNew-pCrash->nData);
+    pCrash->nData = nNew;
+    pCrash->zData = zNew;
+  }
+  memcpy(&pCrash->zData[iOfst], zBuf, iAmt);
   return writeListAppend(pFile, iOfst, zBuf, iAmt);
 }
 
@@ -379,6 +362,11 @@ static int cfWrite(
 ** Truncate a crash-file.
 */
 static int cfTruncate(sqlite3_file *pFile, sqlite_int64 size){
+  CrashFile *pCrash = (CrashFile *)pFile;
+  assert(size>=0);
+  if( pCrash->iSize>size ){
+    pCrash->iSize = size;
+  }
   return writeListAppend(pFile, size, 0, 0);
 }
 
@@ -389,10 +377,18 @@ static int cfSync(sqlite3_file *pFile, int flags){
   CrashFile *pCrash = (CrashFile *)pFile;
   int isCrash = 0;
 
-  if( 0==strcmp(pCrash->zName, g.zCrashFile) ){
-    if( (--g.iCrash==0) ){
-      isCrash = 1;
-    }
+  const char *zName = pCrash->zName;
+  const char *zCrashFile = g.zCrashFile;
+  int nName = strlen(zName);
+  int nCrashFile = strlen(zCrashFile);
+
+  if( nCrashFile>0 && zCrashFile[nCrashFile-1]=='*' ){
+    nCrashFile--;
+    if( nName>nCrashFile ) nName = nCrashFile;
+  }
+
+  if( nName==nCrashFile && 0==memcmp(zName, zCrashFile, nName) ){
+    if( (--g.iCrash)==0 ) isCrash = 1;
   }
 
   return writeListSync(pCrash, isCrash);
@@ -403,23 +399,7 @@ static int cfSync(sqlite3_file *pFile, int flags){
 */
 static int cfFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
   CrashFile *pCrash = (CrashFile *)pFile;
-  WriteBuffer *pWrite;
-  int rc;
-  sqlite_int64 iSize;
-
-  rc = sqlite3OsFileSize(pCrash->pRealFile, &iSize);
-  if( rc!=SQLITE_OK ){
-    return rc;
-  }
-
-  for(pWrite=g.pWriteList; pWrite; pWrite=pWrite->pNext){
-    sqlite_int64 iEnd = pWrite->nBuf+pWrite->iOffset;
-    if( pWrite->pFile==pCrash && (pWrite->zBuf==0 || iEnd>iSize) ){
-      iSize = iEnd;
-    }
-  }
-  *pSize = iSize;
-
+  *pSize = (i64)pCrash->iSize;
   return SQLITE_OK;
 }
 
@@ -435,6 +415,9 @@ static int cfUnlock(sqlite3_file *pFile, int eLock){
 static int cfCheckReservedLock(sqlite3_file *pFile){
   return sqlite3OsCheckReservedLock(((CrashFile *)pFile)->pRealFile);
 }
+static int cfLockState(sqlite3_file *pFile){
+  return sqlite3OsLockState(((CrashFile *)pFile)->pRealFile);
+}
 static int cfBreakLock(sqlite3_file *pFile){
   return sqlite3OsBreakLock(((CrashFile *)pFile)->pRealFile);
 }
@@ -463,6 +446,7 @@ static const sqlite3_io_methods CrashFileVtab = {
   cfUnlock,                     /* xUnlock */
   cfCheckReservedLock,          /* xCheckReservedLock */
   cfBreakLock,                  /* xBreakLock */
+  cfLockState,                  /* xLockState */
   cfSectorSize,                 /* xSectorSize */
   cfDeviceCharacteristics       /* xDeviceCharacteristics */
 };
@@ -470,6 +454,12 @@ static const sqlite3_io_methods CrashFileVtab = {
 /*
 ** Open a crash-file file handle. The vfs pVfs is used to open
 ** the underlying real file.
+**
+** The caller will have allocated pVfs->szOsFile bytes of space
+** at pFile. This file uses this space for the CrashFile structure
+** and allocates space for the "real" file structure using 
+** sqlite3_malloc(). The assumption here is (pVfs->szOsFile) is
+** equal or greater than sizeof(CrashFile).
 */
 int sqlite3CrashFileOpen(
   sqlite3_vfs *pVfs,
@@ -478,48 +468,42 @@ int sqlite3CrashFileOpen(
   int flags,
   int *pOutFlags
 ){
-  CrashFile *pWrapper = (CrashFile *)pFile;
-  int rc = SQLITE_NOMEM;
-  sqlite3_file *pReal;
-  pReal = (sqlite3_file *)sqlite3_malloc(pVfs->szOsFile);
-  if( pReal ){
-    pWrapper->pMethod = &CrashFileVtab;
-    pWrapper->zName = (char *)zName;
-    rc = pVfs->xOpen(pVfs->pAppData, zName, pReal, flags, pOutFlags);
+  int rc;
+  if( sqlite3CrashTestEnable ){
+    CrashFile *pWrapper = (CrashFile *)pFile;
+    sqlite3_file *pReal;
+    assert(pVfs->szOsFile>=sizeof(CrashFile));
+    memset(pWrapper, 0, sizeof(CrashFile));
+    sqlite3CrashTestEnable = 0;
+    rc = sqlite3OsOpenMalloc(pVfs, zName, &pReal, flags, pOutFlags);
+    sqlite3CrashTestEnable = 1;
     if( rc==SQLITE_OK ){
-      pWrapper->pRealFile = pFile;
-    }else{
-      sqlite3_free(pReal);
+      i64 iSize;
+      pWrapper->pMethod = &CrashFileVtab;
+      pWrapper->zName = (char *)zName;
+      pWrapper->pRealFile = pReal;
+      rc = sqlite3OsFileSize(pReal, &iSize);
+      pWrapper->iSize = (int)iSize;
+    }
+    if( rc==SQLITE_OK ){
+      pWrapper->nData = (4096 + pWrapper->iSize);
+      pWrapper->zData = (char *)sqlite3_malloc(pWrapper->nData);
+      if( pWrapper->zData ){
+        memset(pWrapper->zData, 0, pWrapper->nData);
+        rc = sqlite3OsRead(pReal, pWrapper->zData, pWrapper->iSize, 0); 
+      }else{
+        rc = SQLITE_NOMEM;
+      }
+    }
+    if( rc!=SQLITE_OK && pWrapper->pMethod ){
+      sqlite3OsClose(pFile);
     }
+  }else{
+    rc = pVfs->xOpen(pVfs->pAppData, zName, pFile, flags, pOutFlags);
   }
   return rc;
 }
 
-int sqlite3CrashFileWrap(
-  sqlite3_file *pFile,
-  const char *zName,
-  sqlite3_file **ppWrapper
-){
-  CrashFile *pWrapper;
-  pWrapper = (CrashFile *)sqlite3_malloc(sizeof(CrashFile)+strlen(zName)+1);
-  if( !pWrapper ){
-    return SQLITE_NOMEM;
-  }
-
-  pWrapper->pMethod = &CrashFileVtab;
-  pWrapper->pRealFile = pFile;
-  pWrapper->zName = (char *)&pWrapper[1];
-  memcpy(pWrapper->zName, zName, strlen(zName)+1);
-
-  *ppWrapper = (sqlite3_file *)pWrapper;
-  return SQLITE_OK;
-}
-
-
-int sqlite3CrashFileSize(){
-  return (int)sizeof(CrashFile);
-}
-
 /*
 ** tclcmd:   sqlite_crashparams ?OPTIONS? DELAY CRASHFILE
 **
@@ -578,10 +562,7 @@ static int crashParamsObjCmd(
     goto error;
   }
 
-  pVfs = sqlite3_find_vfs(0);
-  zCrashFile = sqlite3_malloc(pVfs->mxPathname);
-  sqlite3OsFullPathname(pVfs, Tcl_GetString(objv[objc-1]), zCrashFile);
-  nCrashFile = strlen(zCrashFile);
+  zCrashFile = Tcl_GetStringFromObj(objv[objc-1], &nCrashFile);
   if( nCrashFile>=sizeof(g.zCrashFile) ){
     Tcl_AppendResult(interp, "Filename is too long: \"", zCrashFile, "\"", 0);
     goto error;
@@ -649,12 +630,10 @@ static int crashParamsObjCmd(
   }
   g.iCrash = iDelay;
   memcpy(g.zCrashFile, zCrashFile, nCrashFile+1);
-  sqlite3_free(zCrashFile);
   sqlite3CrashTestEnable = 1;
   return TCL_OK;
 
 error:
-  sqlite3_free(zCrashFile);
   return TCL_ERROR;
 }
 
index ed4994cf7d1d3a8530042ef202b633f600e0f1fa..206fd0fda48a8553b1ddcf528540b831f8bbe08e 100644 (file)
@@ -1153,7 +1153,7 @@ static int vdbeCommit(sqlite3 *db){
     /* Open the master journal. */
     rc = sqlite3OsOpenMalloc(pVfs, zMaster, &pMaster, 
         SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|
-        SQLITE_OPEN_EXCLUSIVE|SQLITE_OPEN_MASTER_JOURNAL
+        SQLITE_OPEN_EXCLUSIVE|SQLITE_OPEN_MASTER_JOURNAL, 0
     );
     if( rc!=SQLITE_OK ){
       sqlite3_free(zMaster);
index a2a83cb39c7ae9e90968e942d8873840f0028bfa..0d58f84a56a0cb2b8b32b8a2a0d7477eaf856ef3 100644 (file)
@@ -17,7 +17,7 @@
 # These routines allow us to simulate the kind of file damage that 
 # occurs after a power failure.
 #
-# $Id: crash.test,v 1.24 2007/05/23 06:25:13 danielk1977 Exp $
+# $Id: crash.test,v 1.25 2007/08/20 14:23:44 danielk1977 Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -28,7 +28,7 @@ ifcapable !crashtest {
 }
 
 set repeats 100
-# set repeats 10
+#set repeats 10
 
 # The following procedure computes a "signature" for table "abc".  If
 # abc changes in any way, the signature should change.  
index f0cd5aa30cbd24465acd113ddbfd78382884ebfb..4b41a20d59ab7b6d1bb729d8fa5984e3e66fbf6b 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements some common TCL routines used for regression
 # testing the SQLite library
 #
-# $Id: tester.tcl,v 1.83 2007/08/16 13:01:45 drh Exp $
+# $Id: tester.tcl,v 1.84 2007/08/20 14:23:44 danielk1977 Exp $
 
 # Make sure tclsqlite3 was compiled correctly.  Abort now with an
 # error message if not.
@@ -359,7 +359,7 @@ proc crashsql {args} {
 
     if     {$n>1 && [string first $z -delay]==0}     {set crashdelay $z2} \
     elseif {$n>1 && [string first $z -file]==0}      {set crashfile $z2}  \
-    elseif {$n>1 && [string first $z -blocksize]==0} {set blocksize $z2}  \
+    elseif {$n>1 && [string first $z -blocksize]==0} {set blocksize "-s $z2" } \
     else   { error "Unrecognized option: $z" }
   }
 
@@ -370,7 +370,7 @@ proc crashsql {args} {
   set cfile [file join [pwd] $crashfile]
 
   set f [open crash.tcl w]
-  puts $f "sqlite3_crashparams $crashdelay $cfile $blocksize"
+  puts $f "sqlite3_crashparams $blocksize $crashdelay $cfile"
   puts $f "set sqlite_pending_byte $::sqlite_pending_byte"
   puts $f "sqlite3 db test.db"