diff --git a/main.mk b/main.mk index def74a45d9..7b9c22e58c 100644 --- a/main.mk +++ b/main.mk @@ -56,7 +56,7 @@ TCCX = $(TCC) $(OPTS) $(THREADSAFE) $(USLEEP) -I. -I$(TOP)/src # LIBOBJ = attach.o auth.o btree.o build.o date.o delete.o \ expr.o func.o hash.o insert.o \ - main.o opcodes.o os_mac.o os_unix.o os_win.o \ + main.o opcodes.o os_mac.o os_unix.o os_win.o os_test.o \ pager.o parse.o pragma.o printf.o random.o \ select.o table.o tclsqlite.o tokenize.o trigger.o \ update.o util.o vacuum.o \ @@ -273,6 +273,9 @@ opcodes.h: $(TOP)/src/vdbe.h os_mac.o: $(TOP)/src/os_mac.c $(HDR) $(TCCX) -c $(TOP)/src/os_mac.c +os_test.o: $(TOP)/src/os_test.c $(HDR) + $(TCCX) -c $(TOP)/src/os_test.c + os_unix.o: $(TOP)/src/os_unix.c $(HDR) $(TCCX) -c $(TOP)/src/os_unix.c @@ -355,6 +358,11 @@ testfixture$(EXE): $(TOP)/src/tclsqlite.c libsqlite3.a $(TESTSRC) $(TESTSRC) $(TOP)/src/tclsqlite.c \ libsqlite3.a $(LIBTCL) $(THREADLIB) +testfixturex: $(TOP)/src/tclsqlite.c libsqlite3.a $(TESTSRC) + $(TCCX) $(TCL_FLAGS) -DOS_TEST=1 -DTCLSH=1 -DSQLITE_TEST=1 -o testfixture$(EXE) \ + $(TESTSRC) $(TOP)/src/tclsqlite.c \ + libsqlite3.a $(LIBTCL) $(THREADLIB) + fulltest: testfixture$(EXE) sqlite3$(EXE) ./testfixture$(EXE) $(TOP)/test/all.test diff --git a/manifest b/manifest index 30b2677f6f..ba89d7e008 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C configure\sfixes\sfor\scygwin\s(line\sendings\sin\sconfigure.ac)\sticket\s#772\s(CVS\s1654) -D 2004-06-21T21:49:58 +C Add\sos_test.c.\sNot\sactivated\syet.\s(CVS\s1655) +D 2004-06-22T11:29:02 F Makefile.in 0a3d7aaefa50717bd550b0cf568a51072c4c103c F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd @@ -17,7 +17,7 @@ F doc/lemon.html f0f682f50210928c07e562621c3b7e8ab912a538 F doc/report1.txt a031aaf37b185e4fa540223cb516d3bccec7eeac F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 F ltmain.sh f6b283068efa69f06eb8aa1fe4bddfdbdeb35826 -F main.mk bede7ee0070ad5b3519d084c1c678b4be145b0c1 +F main.mk 0692293db19dc8206d88abe9c24e11fa22a2ab95 F mkdll.sh 68d34a961a1fdfa15ef27fc4f4740be583112124 F publish.sh 5bc5e493fa1773a3c0d9712182de0f5abd494903 F spec.template a38492f1c1dd349fc24cb0565e08afc53045304b @@ -40,15 +40,17 @@ F src/insert.c d99ffe87e1e1397f4233afcd06841d52d6b17b18 F src/legacy.c ad23746f15f67e34577621b1875f639c94839e1f F src/main.c 5bf387a22ff6e17c8e60d2fbb940e98a78f5d501 F src/md5.c 7ae1c39044b95de2f62e066f47bb1deb880a1070 -F src/os.h 1cb5f0293a30288451fe3c0c73815cf208212ed1 +F src/os.h 2f5ea879b784bc82aac8022a3e8fe00b73c83d67 F src/os_common.h ba1b7306e16e2091718f2c48db0fe6c1d7a31bb8 F src/os_mac.c 3d31e26be1411acfb7961033098631b4f3486fdf F src/os_mac.h 51d2445f47e182ed32d3bd6937f81070c6fd9bd4 -F src/os_unix.c 3d3553d71cbf1430a40985a7581ca27b85723ee1 +F src/os_test.c 616d6845ef7015c31d283ece85e8a7700f7986c7 +F src/os_test.h 6665b2ace17a76ecee68bc463343340d3cd5c1cc +F src/os_unix.c 39e73ed02fc992a6bfc52200ea26704633412cc0 F src/os_unix.h 00c1f82b526ab2fb7ee5ddd555ea4ed68363c93a F src/os_win.c 84549f6cc815237533c5d0eb3697352b03478d96 F src/os_win.h babd4e912967c6b09088cfe38a45e8005a07ba44 -F src/pager.c f42526a134d56f5ee4b4217211dd36b3c8f00963 +F src/pager.c d9d3f577319ebac6670d3f44eca46060b78ee6b2 F src/pager.h bc58d32a9dee464f7268fb68652c130a4216e438 F src/parse.y 097438674976355a10cf177bd97326c548820b86 F src/pragma.c 0750e1c360647dbe0a991f16133b0fe5e42e5039 @@ -57,7 +59,7 @@ F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3 F src/select.c f02a65af34231031896e8442161cb5251e191e75 F src/shell.c 24b641700c9d90f361fcfa4f432c5b4aff704e6d F src/sqlite.h.in a3d593016d1a1a514d7a26c8a353b58caf62e798 -F src/sqliteInt.h b379bc549c9d812090d6c33ff5f229b34346ac0c +F src/sqliteInt.h 0aa0b24208eeb46290baf8b6ae5ca36fed8a58d3 F src/table.c af14284fa36c8d41f6829e3f2819dce07d3e2de2 F src/tclsqlite.c 8d093146332b2f0cbf2a8ebe8597d481619308a3 F src/test1.c ee426e026ad9223483e7a84bb68849fc6e9f542e @@ -75,7 +77,7 @@ F src/vdbe.c 5da73f61016b1874d935b522bab6ca8b5aa15216 F src/vdbe.h 2d87155e31e84bb00cdc48cc1ce6987a3a484250 F src/vdbeInt.h c0740932621a8d4aac20e0c4235ce44eb5e8dce6 F src/vdbeapi.c 8a9421341e09b506a934132c9015f26362ae8c0e -F src/vdbeaux.c bf1f5a48b4d2f4f0ee6e5f00dca491855e81cd02 +F src/vdbeaux.c 9fe01087f2ddc410827b6e124fc423d429e6f5a1 F src/vdbemem.c 9359c53386e070fea9f5403cab0c6f0cfe36496b F src/where.c 6507074d8ce3f78e7a4cd33f667f11e62020553e F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242 @@ -225,7 +227,7 @@ F www/tclsqlite.tcl 19191cf2a1010eaeff74c51d83fd5f5a4d899075 F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9 F www/version3.tcl af528563442e3039928f9018327a18157e53a44f F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4 -P eec48814f470bc90c7a3ffd8a0f0e84af52abb26 -R 1cca28a87c5e2703c0b63b06d79af6d4 -U dougcurrie -Z 29d900fadced81adcdb4a5052258b8f5 +P 819a5973d15bf619182e47abd9b9dca2a560d8ff +R 9995119681c1ca663fd04d3e87f63e78 +U danielk1977 +Z 48006eb9b98a86dcff4611e010a83567 diff --git a/manifest.uuid b/manifest.uuid index 15f5b567c8..592c07de04 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -819a5973d15bf619182e47abd9b9dca2a560d8ff \ No newline at end of file +d16b863849d1aa887fe403e25153b1e9df6b837e \ No newline at end of file diff --git a/src/os.h b/src/os.h index 225c2d8628..fa61b6d980 100644 --- a/src/os.h +++ b/src/os.h @@ -23,7 +23,7 @@ ** N.B. MacOS means Mac Classic (or Carbon). Treat Darwin (OS X) as Unix. ** The MacOS build is designed to use CodeWarrior (tested with v8) */ -#ifndef OS_UNIX +#if !defined(OS_UNIX) && !defined(OS_TEST) # ifndef OS_WIN # ifndef OS_MAC # if defined(__MACOS__) @@ -57,6 +57,9 @@ /* ** Invoke the appropriate operating-system specific header file. */ +#if OS_TEST +# include "os_test.h" +#endif #if OS_UNIX # include "os_unix.h" #endif @@ -154,7 +157,6 @@ int sqlite3OsDelete(const char*); int sqlite3OsFileExists(const char*); -int sqliteOsFileRename(const char*, const char*); int sqlite3OsOpenReadWrite(const char*, OsFile*, int*); int sqlite3OsOpenExclusive(const char*, OsFile*, int); int sqlite3OsOpenReadOnly(const char*, OsFile*); diff --git a/src/os_test.c b/src/os_test.c new file mode 100644 index 0000000000..b6fd755f10 --- /dev/null +++ b/src/os_test.c @@ -0,0 +1,384 @@ +/* +** 2004 May 22 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file contains code that is specific to Unix systems. It is used +** for testing SQLite only. +*/ +#include "os.h" /* Must be first to enable large file support */ +#if OS_TEST /* This file is used for the test backend only */ +#include "sqliteInt.h" + +#define sqlite3OsOpenReadWrite sqlite3RealOpenReadWrite +#define sqlite3OsOpenExclusive sqlite3RealOpenExclusive +#define sqlite3OsOpenReadOnly sqlite3RealOpenReadOnly +#define sqlite3OsOpenDirectory sqlite3RealOpenDirectory +#define sqlite3OsClose sqlite3RealClose +#define sqlite3OsRead sqlite3RealRead +#define sqlite3OsWrite sqlite3RealWrite +#define sqlite3OsSeek sqlite3RealSeek +#define sqlite3OsSync sqlite3RealSync +#define sqlite3OsTruncate sqlite3RealTruncate +#define sqlite3OsFileSize sqlite3RealFileSize +#define sqlite3OsFileModTime sqlite3RealFileModTime +#define sqlite3OsLock sqlite3RealLock +#define sqlite3OsUnlock sqlite3RealUnlock +#define sqlite3OsCheckReservedLock sqlite3RealCheckReservedLock + +#define OsFile OsRealFile +#define OS_UNIX 1 +#include "os_unix.c" +#undef OS_UNIX +#undef OsFile + +#undef sqlite3OsOpenReadWrite +#undef sqlite3OsOpenExclusive +#undef sqlite3OsOpenReadOnly +#undef sqlite3OsOpenDirectory +#undef sqlite3OsClose +#undef sqlite3OsRead +#undef sqlite3OsWrite +#undef sqlite3OsSeek +#undef sqlite3OsSync +#undef sqlite3OsTruncate +#undef sqlite3OsFileSize +#undef sqlite3OsFileModTime +#undef sqlite3OsLock +#undef sqlite3OsUnlock +#undef sqlite3OsCheckReservedLock + +#define BLOCKSIZE 512 +#define BLOCK_OFFSET(x) ((x) * BLOCKSIZE) + + +/* +** The crash-seed. Accessed via functions crashseed() and +** sqlite3SetCrashseed(). +*/ +static int crashseed_var = 0; + +/* +** This function is used to set the value of the 'crash-seed' integer. +** +** If the crash-seed is 0, the default value, then whenever sqlite3OsSync() +** or sqlite3OsClose() is called, the write cache is written to disk before +** the os_unix.c Sync() or Close() function is called. +** +** If the crash-seed is non-zero, then it is used to determine a subset of +** the write-cache to actually write to disk before calling Sync() or +** Close() in os_unix.c. The actual subset of writes selected is not +** significant, except that it is constant for a given value of the +** crash-seed and cache contents. Before returning, exit(-1) is invoked. +*/ +void sqlite3SetCrashseed(int seed){ + sqlite3OsEnterMutex(); + crashseed_var = seed; + sqlite3OsLeaveMutex(); +} + +/* +** Retrieve the current value of the crash-seed. +*/ +static int crashseed(){ + int i; + sqlite3OsEnterMutex(); + i = crashseed_var; + sqlite3OsLeaveMutex(); + return i; +} + +/* +** Initialise the os_test.c specific fields of pFile. +*/ +static void initFile(OsFile *pFile){ + pFile->nMaxWrite = 0; + pFile->nBlk = 0; + pFile->apBlk = 0; +} + +/* +** Return the current seek offset from the start of the file. This +** is unix-only code. +*/ +static off_t osTell(OsFile *pFile){ + return lseek(pFile->fd.h, 0, SEEK_CUR); +} + +/* +** Load block 'blk' into the cache of pFile. +*/ +static int cacheBlock(OsFile *pFile, int blk){ + if( blk>=pFile->nBlk ){ + int n = ((pFile->nBlk * 2) + 100 + blk); + pFile->apBlk = (u8 **)sqliteRealloc(pFile->apBlk, n * sizeof(u8*)); + if( !pFile->apBlk ) return SQLITE_NOMEM; + pFile->nBlk = n; + } + + if( !pFile->apBlk[blk] ){ + off_t filesize; + int rc; + + u8 *p = sqliteMalloc(BLOCKSIZE); + if( !p ) return SQLITE_NOMEM; + pFile->apBlk[blk] = p; + + rc = sqlite3RealFileSize(&pFile->fd, &filesize); + if( rc!=SQLITE_OK ) return rc; + + if( BLOCK_OFFSET(blk)fd, blk*BLOCKSIZE); + if( BLOCK_OFFSET(blk+1)>filesize ){ + len = filesize - BLOCK_OFFSET(blk); + } + if( rc!=SQLITE_OK ) return rc; + rc = sqlite3RealRead(&pFile->fd, p, len); + if( rc!=SQLITE_OK ) return rc; + } + } + + return SQLITE_OK; +} + +/* +** Write the cache of pFile to disk. If crash is non-zero, randomly +** skip blocks when writing. The cache is deleted before returning. +*/ +static int writeCache2(OsFile *pFile, int crash){ + int i; + int nMax = pFile->nMaxWrite; + off_t offset; + int rc = SQLITE_OK; + + offset = osTell(pFile); + for(i=0; inBlk; i++){ + u8 *p = pFile->apBlk[i]; + if( p ){ + int skip = 0; + if( crash ){ + char random; + sqlite3Randomness(1, &random); + if( random & 0x01 ) skip = 1; + } + + if( rc==SQLITE_OK ){ + rc = sqlite3RealSeek(&pFile->fd, BLOCK_OFFSET(i)); + } + if( rc==SQLITE_OK && !skip ){ + int len = BLOCKSIZE; + if( BLOCK_OFFSET(i+1)>nMax ){ + len = nMax-BLOCK_OFFSET(i); + } + rc = sqlite3RealWrite(&pFile->fd, p, len); + } + sqliteFree(p); + } + } + sqliteFree(pFile->apBlk); + pFile->nBlk = 0; + pFile->apBlk = 0; + pFile->nMaxWrite = 0; + + if( rc==SQLITE_OK ){ + rc = sqlite3RealSeek(&pFile->fd, offset); + } + return rc; +} + +/* +** Write the cache to disk. +*/ +static int writeCache(OsFile *pFile){ + if( crashseed() ){ + /* FIX ME: writeCache2() should be called on all open files + ** here. */ + writeCache2(pFile, 1); + exit(-1); + }else{ + return writeCache2(pFile, 0); + } +} + +/* +** Close the file. +*/ +int sqlite3OsClose(OsFile *id){ + if( !id->fd.isOpen ) return SQLITE_OK; + writeCache(id); + sqlite3RealClose(&id->fd); + return SQLITE_OK; +} + +int sqlite3OsRead(OsFile *id, void *pBuf, int amt){ + off_t offset; /* The current offset from the start of the file */ + off_t end; /* The byte just past the last byte read */ + int blk; /* Block number the read starts on */ + int i; + u8 *zCsr; + int rc = SQLITE_OK; + + offset = osTell(id); + end = offset+amt; + blk = (offset/BLOCKSIZE); + + zCsr = (u8 *)pBuf; + for(i=blk; i*BLOCKSIZE end ){ + len = len - (BLOCK_OFFSET(i+1)-end); + } + + if( inBlk && id->apBlk[i]){ + u8 *pBlk = id->apBlk[i]; + memcpy(zCsr, &pBlk[off], len); + }else{ + rc = sqlite3RealSeek(&id->fd, BLOCK_OFFSET(i) + off); + if( rc!=SQLITE_OK ) return rc; + rc = sqlite3RealRead(&id->fd, zCsr, len); + if( rc!=SQLITE_OK ) return rc; + } + + zCsr += len; + } + assert( zCsr==&((u8 *)pBuf)[amt] ); + + rc = sqlite3RealSeek(&id->fd, end); + return rc; +} + +int sqlite3OsWrite(OsFile *id, const void *pBuf, int amt){ + off_t offset; /* The current offset from the start of the file */ + off_t end; /* The byte just past the last byte written */ + int blk; /* Block number the write starts on */ + int i; + const u8 *zCsr; + int rc = SQLITE_OK; + + offset = osTell(id); + end = offset+amt; + blk = (offset/BLOCKSIZE); + + zCsr = (u8 *)pBuf; + for(i=blk; i*BLOCKSIZEapBlk[i]; + assert( pBlk ); + + if( BLOCK_OFFSET(i) < offset ){ + off = offset-BLOCK_OFFSET(i); + } + len = BLOCKSIZE - off; + if( BLOCK_OFFSET(i+1) > end ){ + len = len - (BLOCK_OFFSET(i+1)-end); + } + memcpy(&pBlk[off], zCsr, len); + zCsr += len; + } + if( id->nMaxWritenMaxWrite = end; + } + assert( zCsr==&((u8 *)pBuf)[amt] ); + + rc = sqlite3RealSeek(&id->fd, end); + return rc; +} + +/* +** Sync the file. First flush the write-cache to disk, then call the +** real sync() function. +*/ +int sqlite3OsSync(OsFile *id){ + int rc = writeCache(id); + if( rc!=SQLITE_OK ) return rc; + rc = sqlite3RealSync(&id->fd); + return rc; +} + +/* +** Truncate the file. Set the internal OsFile.nMaxWrite variable to the new +** file size to ensure that nothing in the write-cache past this point +** is written to disk. +*/ +int sqlite3OsTruncate(OsFile *id, off_t nByte){ + id->nMaxWrite = nByte; + return sqlite3RealTruncate(&id->fd, nByte); +} + +/* +** Return the size of the file. If the cache contains a write that extended +** the file, then return this size instead of the on-disk size. +*/ +int sqlite3OsFileSize(OsFile *id, off_t *pSize){ + int rc = sqlite3RealFileSize(&id->fd, pSize); + if( rc==SQLITE_OK && pSize && *pSizenMaxWrite ){ + *pSize = id->nMaxWrite; + } + return rc; +} + +/* +** The three functions used to open files. All that is required is to +** initialise the os_test.c specific fields and then call the corresponding +** os_unix.c function to really open the file. +*/ +int sqlite3OsOpenReadWrite(const char *zFilename, OsFile *id, int *pReadonly){ + initFile(id); + return sqlite3RealOpenReadWrite(zFilename, &id->fd, pReadonly); +} +int sqlite3OsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){ + initFile(id); + return sqlite3RealOpenExclusive(zFilename, &id->fd, delFlag); +} +int sqlite3OsOpenReadOnly(const char *zFilename, OsFile *id){ + initFile(id); + return sqlite3RealOpenReadOnly(zFilename, &id->fd); +} + +/* +** These six function calls are passed straight through to the os_unix.c +** backend. +*/ +int sqlite3OsSeek(OsFile *id, off_t offset){ + return sqlite3RealSeek(&id->fd, offset); +} +int sqlite3OsCheckReservedLock(OsFile *id){ + return sqlite3RealCheckReservedLock(&id->fd); +} +int sqlite3OsLock(OsFile *id, int locktype){ + return sqlite3RealLock(&id->fd, locktype); +} +int sqlite3OsUnlock(OsFile *id, int locktype){ + return sqlite3RealUnlock(&id->fd, locktype); +} +int sqlite3OsFileModTime(OsFile *id, double *prNow){ + return sqlite3RealFileModTime(&id->fd, prNow); +} +int sqlite3OsOpenDirectory(const char *zDirname, OsFile *id){ + return sqlite3RealOpenDirectory(zDirname, &id->fd); +} + +#endif /* OS_TEST */ diff --git a/src/os_test.h b/src/os_test.h new file mode 100644 index 0000000000..bf913eb5cc --- /dev/null +++ b/src/os_test.h @@ -0,0 +1,36 @@ +/* +** 2004 May 22 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +*/ +#ifndef _SQLITE_OS_TEST_H_ +#define _SQLITE_OS_TEST_H_ + +#define OsFile OsRealFile +#define OS_UNIX 1 +#include "os_unix.h" +#undef OS_UNIX +#undef OsFile + +/* Include sqliteInt.h now to get the type u8. */ +#include "sqliteInt.h" + +typedef struct OsFile OsFile; +struct OsFile { + u8 **apBlk; /* Array of blocks that have been written to. */ + int nBlk; /* Size of apBlock. */ + int nMaxWrite; /* Largest offset written to. */ + OsRealFile fd; +}; + +void sqlite3SetCrashseed(int seed); + +#endif /* _SQLITE_OS_UNIX_H_ */ diff --git a/src/os_unix.c b/src/os_unix.c index 8276c9e0b3..e707835f1e 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -512,44 +512,6 @@ int sqlite3OsTempFileName(char *zBuf){ return SQLITE_OK; } -/* -** Close a file. -*/ -int sqlite3OsClose(OsFile *id){ - if( !id->isOpen ) return SQLITE_OK; - sqlite3OsUnlock(id, NO_LOCK); - if( id->dirfd>=0 ) close(id->dirfd); - id->dirfd = -1; - sqlite3OsEnterMutex(); - if( id->pOpen->nLock ){ - /* If there are outstanding locks, do not actually close the file just - ** yet because that would clear those locks. Instead, add the file - ** descriptor to pOpen->aPending. It will be automatically closed when - ** the last lock is cleared. - */ - int *aNew; - struct openCnt *pOpen = id->pOpen; - pOpen->nPending++; - aNew = sqliteRealloc( pOpen->aPending, pOpen->nPending*sizeof(int) ); - if( aNew==0 ){ - /* If a malloc fails, just leak the file descriptor */ - }else{ - pOpen->aPending = aNew; - pOpen->aPending[pOpen->nPending-1] = id->h; - } - }else{ - /* There are no outstanding locks so we can close the file immediately */ - close(id->h); - } - releaseLockInfo(id->pLock); - releaseOpenCnt(id->pOpen); - sqlite3OsLeaveMutex(); - id->isOpen = 0; - TRACE2("CLOSE %-3d\n", id->h); - OpenCounter(-1); - return SQLITE_OK; -} - /* ** Read data from a file into a buffer. Return SQLITE_OK if all ** bytes were read successfully and SQLITE_IOERR if anything goes @@ -943,6 +905,44 @@ int sqlite3OsUnlock(OsFile *id, int locktype){ return SQLITE_OK; } +/* +** Close a file. +*/ +int sqlite3OsClose(OsFile *id){ + if( !id->isOpen ) return SQLITE_OK; + sqlite3OsUnlock(id, NO_LOCK); + if( id->dirfd>=0 ) close(id->dirfd); + id->dirfd = -1; + sqlite3OsEnterMutex(); + if( id->pOpen->nLock ){ + /* If there are outstanding locks, do not actually close the file just + ** yet because that would clear those locks. Instead, add the file + ** descriptor to pOpen->aPending. It will be automatically closed when + ** the last lock is cleared. + */ + int *aNew; + struct openCnt *pOpen = id->pOpen; + pOpen->nPending++; + aNew = sqliteRealloc( pOpen->aPending, pOpen->nPending*sizeof(int) ); + if( aNew==0 ){ + /* If a malloc fails, just leak the file descriptor */ + }else{ + pOpen->aPending = aNew; + pOpen->aPending[pOpen->nPending-1] = id->h; + } + }else{ + /* There are no outstanding locks so we can close the file immediately */ + close(id->h); + } + releaseLockInfo(id->pLock); + releaseOpenCnt(id->pOpen); + sqlite3OsLeaveMutex(); + id->isOpen = 0; + TRACE2("CLOSE %-3d\n", id->h); + OpenCounter(-1); + return SQLITE_OK; +} + /* ** Get information to seed the random number generator. The seed ** is written into the buffer zBuf[256]. The calling function must diff --git a/src/pager.c b/src/pager.c index d3e3863fb0..fb80b7d2d6 100644 --- a/src/pager.c +++ b/src/pager.c @@ -18,7 +18,7 @@ ** file simultaneously, or one process from reading the database while ** another is writing. ** -** @(#) $Id: pager.c,v 1.133 2004/06/21 18:14:47 drh Exp $ +** @(#) $Id: pager.c,v 1.134 2004/06/22 11:29:02 danielk1977 Exp $ */ #include "os.h" /* Must be first to enable large file support */ #include "sqliteInt.h" @@ -2785,7 +2785,11 @@ sync_exit: ** PENDING_LOCK, or EXCLUSIVE_LOCK. */ int sqlite3pager_lockstate(Pager *pPager){ +#ifdef OS_TEST + return pPager->fd.fd.locktype; +#else return pPager->fd.locktype; +#endif } #endif diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 3619855e1c..a2a818f83f 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,8 +11,11 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.297 2004/06/21 07:36:32 danielk1977 Exp $ +** @(#) $Id: sqliteInt.h,v 1.298 2004/06/22 11:29:02 danielk1977 Exp $ */ +#ifndef _SQLITEINT_H_ +#define _SQLITEINT_H_ + #include "config.h" #include "sqlite3.h" #include "hash.h" @@ -1397,3 +1400,5 @@ void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, void(*)(void*)); void sqlite3ValueFree(sqlite3_value*); sqlite3_value *sqlite3ValueNew(); sqlite3_value *sqlite3GetTransientValue(sqlite *db); + +#endif diff --git a/src/vdbeaux.c b/src/vdbeaux.c index a033812f86..38c8974b52 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -675,7 +675,7 @@ void sqlite3VdbeSorterReset(Vdbe *p){ ** Free all resources allociated with AggElem pElem, an element of ** aggregate pAgg. */ -int freeAggElem(AggElem *pElem, Agg *pAgg){ +void freeAggElem(AggElem *pElem, Agg *pAgg){ int i; for(i=0; inMem; i++){ Mem *pMem = &pElem->aMem[i]; @@ -719,7 +719,6 @@ int freeAggElem(AggElem *pElem, Agg *pAgg){ ** for the next round of aggregate processing. */ int sqlite3VdbeAggReset(sqlite *db, Agg *pAgg, KeyInfo *pKeyInfo){ - int i; int rc = 0; BtCursor *pCsr = pAgg->pCsr;