From: drh Date: Tue, 29 Nov 2005 03:13:21 +0000 (+0000) Subject: Make the OsFile structure opaque with its internal structure known only to X-Git-Tag: version-3.6.10~3369 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9cbe635219f7f157766e532ec6dd766841c5661c;p=thirdparty%2Fsqlite.git Make the OsFile structure opaque with its internal structure known only to the appropriate os_*.c implementation. Omit the os_unix.h and os_win.h include files. The crash tests are broken by this patch. (CVS 2791) FossilOrigin-Name: 058f31753871b16b40fe4048e3adcee411e0f87d --- diff --git a/Makefile.in b/Makefile.in index 1d67c30350..3505149f6a 100644 --- a/Makefile.in +++ b/Makefile.in @@ -205,8 +205,6 @@ HDR = \ opcodes.h \ $(TOP)/src/os.h \ $(TOP)/src/os_common.h \ - $(TOP)/src/os_unix.h \ - $(TOP)/src/os_win.h \ $(TOP)/src/sqliteInt.h \ $(TOP)/src/vdbe.h \ parse.h diff --git a/main.mk b/main.mk index e6b6ea9880..c903354dae 100644 --- a/main.mk +++ b/main.mk @@ -147,8 +147,6 @@ HDR = \ opcodes.h \ $(TOP)/src/os.h \ $(TOP)/src/os_common.h \ - $(TOP)/src/os_unix.h \ - $(TOP)/src/os_win.h \ $(TOP)/src/sqliteInt.h \ $(TOP)/src/vdbe.h \ parse.h diff --git a/manifest b/manifest index 4ee323f0aa..40df743861 100644 --- a/manifest +++ b/manifest @@ -1,6 +1,6 @@ -C Replace\sa\scall\sto\ssprintf()\swith\ssqlite3MPrintf()\ssince\son\ssome\sembedded\nplatforms,\ssprintf()\sis\sbusted.\s\sNeed\sto\sgo\sthrough\sand\sdo\ssimilar\sreplacements\nelsewhere\sin\sthe\scode.\s(CVS\s2790) -D 2005-11-28T12:36:36 -F Makefile.in 28a2772cd9e03ba758c2a052813092cdb9da73bf +C Make\sthe\sOsFile\sstructure\sopaque\swith\sits\sinternal\sstructure\sknown\sonly\sto\nthe\sappropriate\sos_*.c\simplementation.\s\sOmit\sthe\sos_unix.h\sand\sos_win.h\ninclude\sfiles.\s\sThe\scrash\stests\sare\sbroken\sby\sthis\spatch.\s(CVS\s2791) +D 2005-11-29T03:13:21 +F Makefile.in eac4c98a32a0eae9d6bb2779ac74bbb5441758d3 F Makefile.linux-gcc aee18d8a05546dcf1888bd4547e442008a49a092 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 F VERSION b818cce180263e590a00ad4509a713892c3eecea @@ -19,7 +19,7 @@ F doc/lemon.html f0f682f50210928c07e562621c3b7e8ab912a538 F doc/report1.txt a031aaf37b185e4fa540223cb516d3bccec7eeac F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 F ltmain.sh f6b283068efa69f06eb8aa1fe4bddfdbdeb35826 -F main.mk 1cf8c00ee4439d3332a2da771fe168ed8420c2d7 +F main.mk 76d9e7bcebea556f0db40811b9273d6b704df88e F mkdll.sh 5ec23622515d5bf8969404e80cfb5e220ddf0512 F mkopcodec.awk bd46ad001c98dfbab07b1713cb8e692fa0e5415d F mkopcodeh.awk 071dbba4eaf56c8d643baf4604a043af35683316 @@ -42,7 +42,7 @@ F src/complete.c 4de937dfdd4c79a501772ab2035b26082f337a79 F src/date.c 7444b0900a28da77e57e3337a636873cff0ae940 F src/delete.c 29dac493f4d83b05f91233b116827c133bcdab72 F src/experimental.c 50c1e3b34f752f4ac10c36f287db095c2b61766d -F src/expr.c b18a7dc6ebff2351abf35ff914465e2341038d34 +F src/expr.c 80ceb8c7d15dd53985831f0b4c660b3c3df796a3 F src/func.c 7d81dccd9c440c6c4e761056333e629192814af0 F src/hash.c 8747cf51d12de46512880dfcf1b68b4e24072863 F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84 @@ -50,15 +50,15 @@ F src/insert.c da031c3ed8e1675fac891990095d277c2ba6e205 F src/legacy.c d58ea507bce885298a2c8c3cbb0f4bff5d47830b F src/main.c 97bb830cdbd378d1f87469618471f52d9d263d09 F src/md5.c 7ae1c39044b95de2f62e066f47bb1deb880a1070 -F src/os.h 70da8a43e03190a981d02bdc7cef1eb9ad1db4ad +F src/os.h a429c3534c1179ce925c120b3ce9b82543a9873a F src/os_common.h d74a11728ad2444b6b695b94c28c06881f049e49 F src/os_test.c 49833426101f99aee4bb5f6a44b7c4b2029fda1c F src/os_test.h 903c93554c23d88f34f667f1979e4a1cee792af3 -F src/os_unix.c 09f174975fe054ed73117ee17c5650f55773fbe3 +F src/os_unix.c 02b6a1c7e7a646da10f41f8ed3364a2a1c33c135 F src/os_unix.h 5768d56d28240d3fe4537fac08cc85e4fb52279e -F src/os_win.c a3762efcc6eebbf8a38d25ff80e0e510ec7afead +F src/os_win.c f18626e44669e12fba9948dd98934ab4b46c343c F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b -F src/pager.c 309d473c01b5e2b355fc3c8adce2a36df16c43a3 +F src/pager.c 18cc5b274a0df28dc9145da522a6e281f80b925f F src/pager.h e7b41ce8e7b5f629d456708b7ad9a8c8ede37140 F src/parse.y e4d57c2fd5cc02f19822ec41f6dc2bfc9bc85609 F src/pragma.c e278b3f722379ab9d630a1569ac05f586f01f4db @@ -71,12 +71,12 @@ F src/sqlite.h.in 8e648e1f386e4509f2f96c09ded7c07b0df0c9a2 F src/sqliteInt.h 4148c9778e350014c2e27b332d7a2ef7278fe62e F src/table.c 486dcfce532685b53b5a2b5da8bba0ded6fb2316 F src/tclsqlite.c a497c3adfd2c85da6a934331ec0041e47884fbcb -F src/test1.c 415c9c4571bf9ecbec3a7bba3c4338efd83fc137 -F src/test2.c 360cfa7fe17a4fe67f6d19699cd6d59fca4ff09f +F src/test1.c c2c307a4cbbf4670f43a7b4b144dce866d1d701f +F src/test2.c 02d639d515ddf99a3bbc00f640d8544ecb925a9b F src/test3.c f4e6a16a602091696619a1171bda25c0e3df49f7 F src/test4.c a8fd681e139e1c61f22a77d07fc3a99cb28fff3f F src/test5.c 64f08b2a50ef371a1bd68ff206829e7b1b9997f5 -F src/test6.c d8501501dbd257b88b3ecfa5c46d5e2ac230e0f9 +F src/test6.c 0543cf075a0cfcc2f83a0810cb2a93d57a7eb602 F src/tokenize.c bdb79702217af49eba44c2a3b4f5fc7bd9ed2917 F src/trigger.c aea0283a3ef729a3e9c8dc5dc1a11c9fcc0a12a7 F src/update.c fec7665138ccf2a2133f11dcd24c1134c6b33526 @@ -87,7 +87,7 @@ F src/vdbe.c 88a85e681522e82e14c8d08adacccbe4e96dd1c9 F src/vdbe.h 8729a4ee16ff9aeab2af9667df3cf300ff978e13 F src/vdbeInt.h 0055c37eccbf3a189fd893a90f8eb6a5fa60c871 F src/vdbeapi.c 85bbe1d0243a89655433d60711b4bd71979b59cd -F src/vdbeaux.c 3dca9c04c07dda17f0cb06b3a552e1e23106232f +F src/vdbeaux.c 09b9bcfed1101b53b433e5d0d7b80943bdf3d1b2 F src/vdbefifo.c 9efb94c8c3f4c979ebd0028219483f88e57584f5 F src/vdbemem.c cd9609c1e7f71ec76d9840c84c3a57ebfa6539cf F src/where.c a9fed5a5b549f5dae1aa95dc9463cd1f35efa0f1 @@ -98,7 +98,7 @@ F test/alter2.test 60ba0a7057dc71ad630a1cc7c487104346849d50 F test/alter3.test d4eecd8dbd008d0e66f1c201fa6dc2edca853c38 F test/altermalloc.test 6e1f404ec021eb2ba6582e3c77b0a35cf206b7af F test/analyze.test 2f55535aa335785db1a2f97d3f3831c16c09f8b0 -F test/attach.test f320e98bcca68d100cab7666a0c9a93ac5f236bd +F test/attach.test dae07fa1554b618b9cc4c7bc349b3bc1a532180e F test/attach2.test 3396c012a39ddf7ba6b528d80bd79554168aa115 F test/attach3.test 63013383adc4380af69779f34f4af19bd49f7cbe F test/attachmalloc.test cdb26c42850f04698377ccec05f5fa89d987837c @@ -323,7 +323,7 @@ F www/tclsqlite.tcl ddcf912ea48695603c8ed7efb29f0812ef8d1b49 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513 -P 7e7cfce0f8ed2a6e04747736a2c68484f447cdfb -R 34f591d26adade3953279102265da94b +P 1b4f2d89bbe833359cefcea580783fd92aa7b8ab +R 167d41b6779a94a69e79f7db1fd9daa9 U drh -Z a721118f67e524e11c01a78c05611f0f +Z 717f7b44d42f5a1bd0daf8e23da32026 diff --git a/manifest.uuid b/manifest.uuid index 77360b68cf..71074c1ab4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1b4f2d89bbe833359cefcea580783fd92aa7b8ab \ No newline at end of file +058f31753871b16b40fe4048e3adcee411e0f87d \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 24def4f39f..50edb902dc 100644 --- a/src/expr.c +++ b/src/expr.c @@ -12,7 +12,7 @@ ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** -** $Id: expr.c,v 1.239 2005/11/28 12:36:36 drh Exp $ +** $Id: expr.c,v 1.240 2005/11/29 03:13:22 drh Exp $ */ #include "sqliteInt.h" #include @@ -1274,17 +1274,16 @@ struct QueryCoder { /* -** Generate code for subqueries and IN operators. +** Generate code for scalar subqueries used as an expression +** and IN operators. Examples: ** -** IN operators comes in two forms: +** (SELECT a FROM b) -- subquery +** EXISTS (SELECT a FROM b) -- EXISTS subquery +** x IN (4,5,11) -- IN operator with list on right-hand side +** x IN (SELECT a FROM b) -- IN operator with subquery on the right ** -** expr IN (exprlist) -** and -** expr IN (SELECT ...) -** -** The first form is handled by creating a set holding the list -** of allowed values. The second form causes the SELECT to generate -** a temporary table. +** The pExpr parameter describes the expression that contains the IN +** operator or subquery. */ #ifndef SQLITE_OMIT_SUBQUERY void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ diff --git a/src/os.h b/src/os.h index 5db9fa4581..412273b5f4 100644 --- a/src/os.h +++ b/src/os.h @@ -43,24 +43,17 @@ #endif /* -** Invoke the appropriate operating-system specific header file. +** The OsFile object describes an open disk file in an OS-dependent way. */ -#if OS_ALT -# include "os_alt.h" -#endif -#if OS_UNIX -# include "os_unix.h" -#endif -#if OS_WIN -# include "os_win.h" -#endif +typedef struct OsFile OsFile; -/* os_other.c and os_other.h are not delivered with SQLite. These files -** are place-holders that can be filled in by third-party developers to -** implement backends to their on proprietary operating systems. +/* +** Define the maximum size of a temporary filename */ -#if OS_OTHER -# include "os_other.h" +#if OS_WIN +# define SQLITE_TEMPNAME_SIZE (MAX_PATH+50) +#else +# define SQLITE_TEMPNAME_SIZE 200 #endif /* If the SET_FULLSYNC macro is not defined above, then make it @@ -179,14 +172,14 @@ extern unsigned int sqlite3_pending_byte; extern struct sqlite3IoVtbl { int (*xDelete)(const char*); int (*xFileExists)(const char*); - int (*xOpenReadWrite)(const char*, OsFile*, int*); - int (*xOpenExclusive)(const char*, OsFile*, int); - int (*xOpenReadOnly)(const char*, OsFile*); + int (*xOpenReadWrite)(const char*, OsFile**, int*); + int (*xOpenExclusive)(const char*, OsFile**, int); + int (*xOpenReadOnly)(const char*, OsFile**); int (*xOpenDirectory)(const char*, OsFile*); int (*xSyncDirectory)(const char*); int (*xTempFileName)(char*); int (*xIsDirWritable)(char*); - int (*xClose)(OsFile*); + int (*xClose)(OsFile**); int (*xRead)(OsFile*, void*, int amt); int (*xWrite)(OsFile*, const void*, int amt); int (*xSeek)(OsFile*, i64 offset); @@ -197,7 +190,9 @@ extern struct sqlite3IoVtbl { int (*xLock)(OsFile*, int); int (*xUnlock)(OsFile*, int); int (*xCheckReservedLock)(OsFile *id); - void (*xCopyOsFile)(OsFile *pDest, OsFile *pSrc); + void (*xSetFullSync)(OsFile *id, int setting); + int (*xFileHandle)(OsFile *id); + int (*xLockState)(OsFile *id); } sqlite3Io; /* The interface for file I/O is above. Other miscellaneous functions diff --git a/src/os_unix.c b/src/os_unix.c index b6ef2081f8..cf85527700 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -15,12 +15,82 @@ #include "sqliteInt.h" #include "os.h" #if OS_UNIX /* This file is used on unix only */ +/* +** These #defines should enable >2GB file support on Posix if the +** underlying operating system supports it. If the OS lacks +** large file support, or if the OS is windows, these should be no-ops. +** +** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch +** on the compiler command line. This is necessary if you are compiling +** on a recent machine (ex: RedHat 7.2) but you want your code to work +** on an older machine (ex: RedHat 6.0). If you compile on RedHat 7.2 +** without this option, LFS is enable. But LFS does not exist in the kernel +** in RedHat 6.0, so the code won't work. Hence, for maximum binary +** portability you should omit LFS. +** +** Similar is true for MacOS. LFS is only supported on MacOS 9 and later. +*/ +#ifndef SQLITE_DISABLE_LFS +# define _LARGE_FILE 1 +# ifndef _FILE_OFFSET_BITS +# define _FILE_OFFSET_BITS 64 +# endif +# define _LARGEFILE_SOURCE 1 +#endif - +/* +** standard include files. +*/ +#include +#include +#include +#include #include #include #include -#include + +/* +** Macros used to determine whether or not to use threads. The +** SQLITE_UNIX_THREADS macro is defined if we are synchronizing for +** Posix threads and SQLITE_W32_THREADS is defined if we are +** synchronizing using Win32 threads. +*/ +#if defined(THREADSAFE) && THREADSAFE +# include +# define SQLITE_UNIX_THREADS 1 +#endif + +/* +** Default permissions when creating a new file +*/ +#ifndef SQLITE_DEFAULT_FILE_PERMISSIONS +# define SQLITE_DEFAULT_FILE_PERMISSIONS 0644 +#endif + + + +/* +** The OsFile structure is a operating-system dependent representation +** of an open file handle. It is defined differently for each architecture. +** +** This is the definition for Unix. +** +** OsFile.locktype takes one of the values SHARED_LOCK, RESERVED_LOCK, +** PENDING_LOCK or EXCLUSIVE_LOCK. +*/ +struct OsFile { + struct openCnt *pOpen; /* Info about all open fd's on this inode */ + struct lockInfo *pLock; /* Info about locks on this inode */ + int h; /* The file descriptor */ + unsigned char locktype; /* The type of lock held on this fd */ + unsigned char isOpen; /* True if needs to be closed */ + unsigned char fullSync; /* Use F_FULLSYNC if available */ + int dirfd; /* File descriptor for the directory */ +#ifdef SQLITE_UNIX_THREADS + pthread_t tid; /* The thread authorized to use this OsFile */ +#endif +}; + /* ** Do not include any of the File I/O interface procedures if the @@ -82,8 +152,8 @@ ** by mistake. */ #if defined(SQLITE_UNIX_THREADS) && !defined(SQLITE_ALLOW_XTHREAD_CONNECTIONS) -# define SET_THREADID(X) X->tid = pthread_self() -# define CHECK_THREADID(X) (!pthread_equal(X->tid, pthread_self())) +# define SET_THREADID(X) (X)->tid = pthread_self() +# define CHECK_THREADID(X) (!pthread_equal((X)->tid, pthread_self())) #else # define SET_THREADID(X) # define CHECK_THREADID(X) 0 @@ -493,6 +563,22 @@ static int unixFileExists(const char *zFilename){ return access(zFilename, 0)==0; } +/* +** 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. +*/ +static OsFile *allocateOsFile(OsFile *pInit){ + OsFile *pNew; + pNew = sqliteMalloc( sizeof(OsFile) ); + if( pNew==0 ){ + close(pInit->h); + }else{ + *pNew = *pInit; + } + return pNew; +} + /* ** Attempt to open a file for both reading and writing. If that ** fails, try opening it read-only. If the file does not exist, @@ -508,23 +594,25 @@ static int unixFileExists(const char *zFilename){ */ static int unixOpenReadWrite( const char *zFilename, - OsFile *id, + OsFile **pId, int *pReadonly ){ int rc; - assert( !id->isOpen ); - id->dirfd = -1; - SET_THREADID(id); - id->h = open(zFilename, O_RDWR|O_CREAT|O_LARGEFILE|O_BINARY, + OsFile f; + + assert( 0==*pId ); + f.dirfd = -1; + SET_THREADID(&f); + f.h = open(zFilename, O_RDWR|O_CREAT|O_LARGEFILE|O_BINARY, SQLITE_DEFAULT_FILE_PERMISSIONS); - if( id->h<0 ){ + if( f.h<0 ){ #ifdef EISDIR if( errno==EISDIR ){ return SQLITE_CANTOPEN; } #endif - id->h = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY); - if( id->h<0 ){ + f.h = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY); + if( f.h<0 ){ return SQLITE_CANTOPEN; } *pReadonly = 1; @@ -532,17 +620,21 @@ static int unixOpenReadWrite( *pReadonly = 0; } sqlite3OsEnterMutex(); - rc = findLockInfo(id->h, &id->pLock, &id->pOpen); + rc = findLockInfo(f.h, &f.pLock, &f.pOpen); sqlite3OsLeaveMutex(); if( rc ){ - close(id->h); + close(f.h); return SQLITE_NOMEM; } - id->locktype = 0; - id->isOpen = 1; - TRACE3("OPEN %-3d %s\n", id->h, zFilename); - OpenCounter(+1); - return SQLITE_OK; + f.locktype = 0; + TRACE3("OPEN %-3d %s\n", f.h, zFilename); + *pId = allocateOsFile(&f); + if( *pId==0 ){ + return SQLITE_NOMEM; + }else{ + OpenCounter(+1); + return SQLITE_OK; + } } @@ -560,36 +652,42 @@ static int unixOpenReadWrite( ** ** On failure, return SQLITE_CANTOPEN. */ -static int unixOpenExclusive(const char *zFilename, OsFile *id, int delFlag){ +static int unixOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){ int rc; - assert( !id->isOpen ); + OsFile f; + + assert( 0==*pId ); if( access(zFilename, 0)==0 ){ return SQLITE_CANTOPEN; } - SET_THREADID(id); - id->dirfd = -1; - id->h = open(zFilename, + SET_THREADID(&f); + f.dirfd = -1; + f.h = open(zFilename, O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW|O_LARGEFILE|O_BINARY, SQLITE_DEFAULT_FILE_PERMISSIONS); - if( id->h<0 ){ + if( f.h<0 ){ return SQLITE_CANTOPEN; } sqlite3OsEnterMutex(); - rc = findLockInfo(id->h, &id->pLock, &id->pOpen); + rc = findLockInfo(f.h, &f.pLock, &f.pOpen); sqlite3OsLeaveMutex(); if( rc ){ - close(id->h); + close(f.h); unlink(zFilename); return SQLITE_NOMEM; } - id->locktype = 0; - id->isOpen = 1; + f.locktype = 0; if( delFlag ){ unlink(zFilename); } - TRACE3("OPEN-EX %-3d %s\n", id->h, zFilename); - OpenCounter(+1); - return SQLITE_OK; + TRACE3("OPEN-EX %-3d %s\n", f.h, zFilename); + *pId = allocateOsFile(&f); + if( *pId==0 ){ + return SQLITE_NOMEM; + }else{ + OpenCounter(+1); + return SQLITE_OK; + } } /* @@ -599,27 +697,33 @@ static int unixOpenExclusive(const char *zFilename, OsFile *id, int delFlag){ ** ** On failure, return SQLITE_CANTOPEN. */ -static int unixOpenReadOnly(const char *zFilename, OsFile *id){ +static int unixOpenReadOnly(const char *zFilename, OsFile **pId){ int rc; - assert( !id->isOpen ); - SET_THREADID(id); - id->dirfd = -1; - id->h = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY); - if( id->h<0 ){ + OsFile f; + + assert( 0==*pId ); + SET_THREADID(&f); + f.dirfd = -1; + f.h = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY); + if( f.h<0 ){ return SQLITE_CANTOPEN; } sqlite3OsEnterMutex(); - rc = findLockInfo(id->h, &id->pLock, &id->pOpen); + rc = findLockInfo(f.h, &f.pLock, &f.pOpen); sqlite3OsLeaveMutex(); if( rc ){ - close(id->h); + close(f.h); return SQLITE_NOMEM; } - id->locktype = 0; - id->isOpen = 1; - TRACE3("OPEN-RO %-3d %s\n", id->h, zFilename); - OpenCounter(+1); - return SQLITE_OK; + f.locktype = 0; + TRACE3("OPEN-RO %-3d %s\n", f.h, zFilename); + *pId = allocateOsFile(&f); + if( *pId==0 ){ + return SQLITE_NOMEM; + }else{ + OpenCounter(+1); + return SQLITE_OK; + } } /* @@ -631,7 +735,7 @@ static int unixOpenReadOnly(const char *zFilename, OsFile *id){ ** 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 +** On success, a handle for a previously open file at *id is ** updated with the new directory file descriptor and SQLITE_OK is ** returned. ** @@ -642,7 +746,7 @@ static int unixOpenDirectory( const char *zDirname, OsFile *id ){ - if( !id->isOpen ){ + if( id==0 ){ /* Do not open the directory if the corresponding file is not already ** open. */ return SQLITE_CANTOPEN; @@ -727,7 +831,7 @@ static int unixIsDirWritable(char *zBuf){ */ static int unixRead(OsFile *id, void *pBuf, int amt){ int got; - assert( id->isOpen ); + assert( id ); SimulateIOError(SQLITE_IOERR); TIMER_START; got = read(id->h, pBuf, amt); @@ -748,7 +852,7 @@ static int unixRead(OsFile *id, void *pBuf, int amt){ */ static int unixWrite(OsFile *id, const void *pBuf, int amt){ int wrote = 0; - assert( id->isOpen ); + assert( id ); assert( amt>0 ); SimulateIOError(SQLITE_IOERR); SimulateDiskfullError; @@ -770,7 +874,7 @@ static int unixWrite(OsFile *id, const void *pBuf, int amt){ ** Move the read/write pointer in a file. */ static int unixSeek(OsFile *id, i64 offset){ - assert( id->isOpen ); + assert( id ); SEEK(offset/1024 + 1); #ifdef SQLITE_TEST if( offset ) SimulateDiskfullError @@ -864,7 +968,7 @@ static int full_fsync(int fd, int fullSync, int dataOnly){ ** will not roll back - possibly leading to database corruption. */ static int unixSync(OsFile *id, int dataOnly){ - assert( id->isOpen ); + assert( id ); SimulateIOError(SQLITE_IOERR); TRACE2("SYNC %-3d\n", id->h); if( full_fsync(id->h, id->fullSync, dataOnly) ){ @@ -913,7 +1017,7 @@ static int unixSyncDirectory(const char *zDirname){ ** Truncate an open file to a specified size */ static int unixTruncate(OsFile *id, i64 nByte){ - assert( id->isOpen ); + assert( id ); SimulateIOError(SQLITE_IOERR); return ftruncate(id->h, nByte)==0 ? SQLITE_OK : SQLITE_IOERR; } @@ -923,7 +1027,7 @@ static int unixTruncate(OsFile *id, i64 nByte){ */ static int unixFileSize(OsFile *id, i64 *pSize){ struct stat buf; - assert( id->isOpen ); + assert( id ); SimulateIOError(SQLITE_IOERR); if( fstat(id->h, &buf)!=0 ){ return SQLITE_IOERR; @@ -941,7 +1045,7 @@ static int unixFileSize(OsFile *id, i64 *pSize){ static int unixCheckReservedLock(OsFile *id){ int r = 0; - assert( id->isOpen ); + assert( id ); if( CHECK_THREADID(id) ) return SQLITE_MISUSE; sqlite3OsEnterMutex(); /* Needed because id->pLock is shared across threads */ @@ -1056,7 +1160,7 @@ static int unixLock(OsFile *id, int locktype){ struct flock lock; int s; - assert( id->isOpen ); + assert( id ); TRACE7("LOCK %d %s was %s(%s,%d) pid=%d\n", id->h, locktypeName(locktype), locktypeName(id->locktype), locktypeName(pLock->locktype), pLock->cnt ,getpid() ); @@ -1213,7 +1317,7 @@ static int unixUnlock(OsFile *id, int locktype){ struct flock lock; int rc = SQLITE_OK; - assert( id->isOpen ); + assert( id ); TRACE7("UNLOCK %d %d was %d(%d,%d) pid=%d\n", id->h, locktype, id->locktype, id->pLock->locktype, id->pLock->cnt, getpid()); if( CHECK_THREADID(id) ) return SQLITE_MISUSE; @@ -1291,8 +1395,9 @@ static int unixUnlock(OsFile *id, int locktype){ /* ** Close a file. */ -static int unixClose(OsFile *id){ - if( !id->isOpen ) return SQLITE_OK; +static int unixClose(OsFile **pId){ + OsFile *id = *pId; + if( !id ) return SQLITE_OK; if( CHECK_THREADID(id) ) return SQLITE_MISUSE; sqlite3Io.xUnlock(id, NO_LOCK); if( id->dirfd>=0 ) close(id->dirfd); @@ -1324,6 +1429,8 @@ static int unixClose(OsFile *id){ id->isOpen = 0; TRACE2("CLOSE %-3d\n", id->h); OpenCounter(-1); + sqliteFree(id); + *pId = 0; return SQLITE_OK; } @@ -1351,10 +1458,25 @@ static char *unixFullPathname(const char *zRelative){ } /* -** Make a copy of an OsFile object. +** Change the value of the fullsync flag in the given file descriptor. +*/ +static void unixSetFullSync(OsFile *id, int v){ + id->fullSync = v; +} + +/* +** Return the underlying file handle for an OsFile +*/ +static int unixFileHandle(OsFile *id){ + return id->h; +} + +/* +** Return an integer that indices the type of lock currently held +** by this handle. (Used for testing and analysis only.) */ -static void unixCopyOsFile(OsFile *pDest, OsFile *pSrc){ - *pDest = *pSrc; +static int unixLockState(OsFile *id){ + return id->locktype; } /* @@ -1381,7 +1503,9 @@ struct sqlite3IoVtbl sqlite3Io = { unixLock, unixUnlock, unixCheckReservedLock, - unixCopyOsFile, + unixSetFullSync, + unixFileHandle, + unixLockState, }; diff --git a/src/os_win.c b/src/os_win.c index 45ff7af62e..e1833b766a 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -16,6 +16,7 @@ #include "os.h" #if OS_WIN /* This file is used for windows only */ +#include #include #ifdef __CYGWIN__ @@ -34,6 +35,20 @@ */ #include "os_common.h" +/* +** The OsFile structure is a operating-system independing representation +** of an open file handle. It is defined differently for each architecture. +** +** This is the definition for Win32. +*/ +struct OsFile { + 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 */ +}; + + + /* ** Do not include any of the File I/O interface procedures if the ** SQLITE_OMIT_DISKIO macro is defined (indicating that there database @@ -153,6 +168,23 @@ static int winFileExists(const char *zFilename){ return exists; } + +/* +** 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. +*/ +static OsFile *allocateOsFile(OsFile *pInit){ + OsFile *pNew; + pNew = sqliteMalloc( sizeof(OsFile) ); + if( pNew==0 ){ + CloseHandle(pInit->h); + }else{ + *pNew = *pInit; + } + return pNew; +} + /* ** Attempt to open a file for both reading and writing. If that ** fails, try opening it read-only. If the file does not exist, @@ -168,12 +200,13 @@ static int winFileExists(const char *zFilename){ */ static int winOpenReadWrite( const char *zFilename, - OsFile *id, + OsFile **pId, int *pReadonly ){ + OsFile f; HANDLE h; WCHAR *zWide = utf8ToUnicode(zFilename); - assert( !id->isOpen ); + assert( *pId==0 ); if( zWide ){ h = CreateFileW(zWide, GENERIC_READ | GENERIC_WRITE, @@ -227,13 +260,17 @@ static int winOpenReadWrite( *pReadonly = 0; } } - id->h = h; - id->locktype = NO_LOCK; - id->sharedLockByte = 0; - id->isOpen = 1; - OpenCounter(+1); + f.h = h; + f.locktype = NO_LOCK; + f.sharedLockByte = 0; TRACE3("OPEN R/W %d \"%s\"\n", h, zFilename); - return SQLITE_OK; + *pId = allocateOsFile(&f); + if( *pId==0 ){ + return SQLITE_NOMEM; + }else{ + OpenCounter(+1); + return SQLITE_OK; + } } @@ -251,11 +288,12 @@ static int winOpenReadWrite( ** ** On failure, return SQLITE_CANTOPEN. */ -static int winOpenExclusive(const char *zFilename, OsFile *id, int delFlag){ +static int winOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){ + OsFile f; HANDLE h; int fileflags; WCHAR *zWide = utf8ToUnicode(zFilename); - assert( !id->isOpen ); + assert( *pId == 0 ); if( delFlag ){ fileflags = FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_DELETE_ON_CLOSE; @@ -285,13 +323,17 @@ static int winOpenExclusive(const char *zFilename, OsFile *id, int delFlag){ if( h==INVALID_HANDLE_VALUE ){ return SQLITE_CANTOPEN; } - id->h = h; - id->locktype = NO_LOCK; - id->sharedLockByte = 0; - id->isOpen = 1; - OpenCounter(+1); + f.h = h; + f.locktype = NO_LOCK; + f.sharedLockByte = 0; TRACE3("OPEN EX %d \"%s\"\n", h, zFilename); - return SQLITE_OK; + *pId = allocateOsFile(&f); + if( *pId==0 ){ + return SQLITE_NOMEM; + }else{ + OpenCounter(+1); + return SQLITE_OK; + } } /* @@ -301,10 +343,11 @@ static int winOpenExclusive(const char *zFilename, OsFile *id, int delFlag){ ** ** On failure, return SQLITE_CANTOPEN. */ -static int winOpenReadOnly(const char *zFilename, OsFile *id){ +static int winOpenReadOnly(const char *zFilename, OsFile **pId){ + OsFile f; HANDLE h; WCHAR *zWide = utf8ToUnicode(zFilename); - assert( !id->isOpen ); + assert( *pId==0 ); if( zWide ){ h = CreateFileW(zWide, GENERIC_READ, @@ -328,13 +371,17 @@ static int winOpenReadOnly(const char *zFilename, OsFile *id){ if( h==INVALID_HANDLE_VALUE ){ return SQLITE_CANTOPEN; } - id->h = h; - id->locktype = NO_LOCK; - id->sharedLockByte = 0; - id->isOpen = 1; - OpenCounter(+1); + f.h = h; + f.locktype = NO_LOCK; + f.sharedLockByte = 0; TRACE3("OPEN RO %d \"%s\"\n", h, zFilename); - return SQLITE_OK; + *pId = allocateOsFile(&f); + if( *pId==0 ){ + return SQLITE_NOMEM; + }else{ + OpenCounter(+1); + return SQLITE_OK; + } } /* @@ -413,12 +460,13 @@ static int winTempFileName(char *zBuf){ /* ** Close a file. */ -static int winClose(OsFile *id){ - if( id->isOpen ){ - TRACE2("CLOSE %d\n", id->h); - CloseHandle(id->h); +static int winClose(OsFile **pId){ + if( *pId ){ + TRACE2("CLOSE %d\n", (*pId)->h); + CloseHandle((*pId)->h); OpenCounter(-1); - id->isOpen = 0; + sqliteFree(*pId); + *pId = 0; } return SQLITE_OK; } @@ -430,7 +478,7 @@ static int winClose(OsFile *id){ */ static int winRead(OsFile *id, void *pBuf, int amt){ DWORD got; - assert( id->isOpen ); + assert( id!=0 ); SimulateIOError(SQLITE_IOERR); TRACE3("READ %d lock=%d\n", id->h, id->locktype); if( !ReadFile(id->h, pBuf, amt, &got, 0) ){ @@ -450,7 +498,7 @@ static int winRead(OsFile *id, void *pBuf, int amt){ static int winWrite(OsFile *id, const void *pBuf, int amt){ int rc = 0; DWORD wrote; - assert( id->isOpen ); + assert( id!=0 ); SimulateIOError(SQLITE_IOERR); SimulateDiskfullError; TRACE3("WRITE %d lock=%d\n", id->h, id->locktype); @@ -479,7 +527,7 @@ static int winSeek(OsFile *id, i64 offset){ LONG upperBits = offset>>32; LONG lowerBits = offset & 0xffffffff; DWORD rc; - assert( id->isOpen ); + assert( id!=0 ); #ifdef SQLITE_TEST if( offset ) SimulateDiskfullError #endif @@ -496,7 +544,7 @@ static int winSeek(OsFile *id, i64 offset){ ** Make sure all writes to a particular file are committed to disk. */ static int winSync(OsFile *id, int dataOnly){ - assert( id->isOpen ); + assert( id!=0 ); TRACE3("SYNC %d lock=%d\n", id->h, id->locktype); if( FlushFileBuffers(id->h) ){ return SQLITE_OK; @@ -519,7 +567,7 @@ static int winSyncDirectory(const char *zDirname){ */ static int winTruncate(OsFile *id, i64 nByte){ LONG upperBits = nByte>>32; - assert( id->isOpen ); + assert( id!=0 ); TRACE3("TRUNCATE %d %lld\n", id->h, nByte); SimulateIOError(SQLITE_IOERR); SetFilePointer(id->h, nByte, &upperBits, FILE_BEGIN); @@ -532,7 +580,7 @@ static int winTruncate(OsFile *id, i64 nByte){ */ static int winFileSize(OsFile *id, i64 *pSize){ DWORD upperBits, lowerBits; - assert( id->isOpen ); + assert( id!=0 ); SimulateIOError(SQLITE_IOERR); lowerBits = GetFileSize(id->h, &upperBits); *pSize = (((i64)upperBits)<<32) + lowerBits; @@ -631,7 +679,7 @@ static int winLock(OsFile *id, int locktype){ int newLocktype; /* Set id->locktype to this value before exiting */ int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */ - assert( id->isOpen ); + assert( id!=0 ); TRACE5("LOCK %d %d was %d(%d)\n", id->h, locktype, id->locktype, id->sharedLockByte); @@ -737,7 +785,7 @@ static int winLock(OsFile *id, int locktype){ */ static int winCheckReservedLock(OsFile *id){ int rc; - assert( id->isOpen ); + assert( id!=0 ); if( id->locktype>=RESERVED_LOCK ){ rc = 1; TRACE3("TEST WR-LOCK %d %d (local)\n", id->h, rc); @@ -766,7 +814,7 @@ static int winCheckReservedLock(OsFile *id){ static int winUnlock(OsFile *id, int locktype){ int type; int rc = SQLITE_OK; - assert( id->isOpen ); + assert( id!=0 ); assert( locktype<=SHARED_LOCK ); TRACE5("UNLOCK %d to %d was %d(%d)\n", id->h, locktype, id->locktype, id->sharedLockByte); @@ -830,10 +878,25 @@ static char *winFullPathname(const char *zRelative){ } /* -** Make a copy of an OsFile object. +** 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)id->h; +} + +/* +** Return an integer that indices the type of lock currently held +** by this handle. (Used for testing and analysis only.) */ -static void winCopyOsFile(OsFile *pDest, OsFile *pSrc){ - *pDest = *pSrc; +static int winLockState(OsFile *id){ + return id->locktype; } @@ -861,7 +924,9 @@ struct sqlite3IoVtbl sqlite3Io = { winLock, winUnlock, winCheckReservedLock, - winCopyOsFile, + winSetFullSync, + winFileHandle, + winLockState, }; #endif /* SQLITE_OMIT_DISKIO */ diff --git a/src/pager.c b/src/pager.c index 17a5c31925..1b6dc8846d 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.220 2005/11/26 03:51:19 drh Exp $ +** @(#) $Id: pager.c,v 1.221 2005/11/29 03:13:22 drh Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" @@ -52,8 +52,8 @@ ** associated file-descriptor is returned. FILEHANDLEID() takes an OsFile ** struct as it's argument. */ -#define PAGERID(p) (p->fd.h) -#define FILEHANDLEID(fd) (fd.h) +#define PAGERID(p) FILEHANDLEID(&(p)->fd) +#define FILEHANDLEID(fd) (sqlite3Io.xFileHandle(&fd)) /* ** The page cache as a whole is always in one of the following @@ -262,8 +262,8 @@ struct Pager { char *zFilename; /* Name of the database file */ char *zJournal; /* Name of the journal file */ char *zDirectory; /* Directory hold database and journal files */ - OsFile fd, jfd; /* File descriptors for database and journal */ - OsFile stfd; /* File descriptor for the statement subjournal*/ + OsFile *fd, *jfd; /* File descriptors for database and journal */ + OsFile *stfd; /* File descriptor for the statement subjournal*/ BusyHandler *pBusyHandler; /* Pointer to sqlite.busyHandler */ PgHdr *pFirst, *pLast; /* List of free pages */ PgHdr *pFirstSynced; /* First free page with PgHdr.needSync==0 */ @@ -590,7 +590,7 @@ static int seekJournalHdr(Pager *pPager){ assert( offset>=c ); assert( (offset-c)journalOff = offset; - return sqlite3Io.xSeek(&pPager->jfd, pPager->journalOff); + return sqlite3Io.xSeek(pPager->jfd, pPager->journalOff); } /* @@ -626,33 +626,33 @@ static int writeJournalHdr(Pager *pPager){ ** Actually maybe the whole journal header should be delayed until that ** point. Think about this. */ - rc = sqlite3Io.xWrite(&pPager->jfd, aJournalMagic, sizeof(aJournalMagic)); + rc = sqlite3Io.xWrite(pPager->jfd, aJournalMagic, sizeof(aJournalMagic)); if( rc==SQLITE_OK ){ /* The nRec Field. 0xFFFFFFFF for no-sync journals. */ - rc = write32bits(&pPager->jfd, pPager->noSync ? 0xffffffff : 0); + rc = write32bits(pPager->jfd, pPager->noSync ? 0xffffffff : 0); } if( rc==SQLITE_OK ){ /* The random check-hash initialiser */ sqlite3Randomness(sizeof(pPager->cksumInit), &pPager->cksumInit); - rc = write32bits(&pPager->jfd, pPager->cksumInit); + rc = write32bits(pPager->jfd, pPager->cksumInit); } if( rc==SQLITE_OK ){ /* The initial database size */ - rc = write32bits(&pPager->jfd, pPager->dbSize); + rc = write32bits(pPager->jfd, pPager->dbSize); } if( rc==SQLITE_OK ){ /* The assumed sector size for this process */ - rc = write32bits(&pPager->jfd, pPager->sectorSize); + rc = write32bits(pPager->jfd, pPager->sectorSize); } /* The journal header has been written successfully. Seek the journal ** file descriptor to the end of the journal header sector. */ if( rc==SQLITE_OK ){ - rc = sqlite3Io.xSeek(&pPager->jfd, pPager->journalOff-1); + rc = sqlite3Io.xSeek(pPager->jfd, pPager->journalOff-1); if( rc==SQLITE_OK ){ - rc = sqlite3Io.xWrite(&pPager->jfd, "\000", 1); + rc = sqlite3Io.xWrite(pPager->jfd, "\000", 1); } } return rc; @@ -690,20 +690,20 @@ static int readJournalHdr( return SQLITE_DONE; } - rc = sqlite3Io.xRead(&pPager->jfd, aMagic, sizeof(aMagic)); + rc = sqlite3Io.xRead(pPager->jfd, aMagic, sizeof(aMagic)); if( rc ) return rc; if( memcmp(aMagic, aJournalMagic, sizeof(aMagic))!=0 ){ return SQLITE_DONE; } - rc = read32bits(&pPager->jfd, pNRec); + rc = read32bits(pPager->jfd, pNRec); if( rc ) return rc; - rc = read32bits(&pPager->jfd, &pPager->cksumInit); + rc = read32bits(pPager->jfd, &pPager->cksumInit); if( rc ) return rc; - rc = read32bits(&pPager->jfd, pDbSize); + rc = read32bits(pPager->jfd, pDbSize); if( rc ) return rc; /* Update the assumed sector-size to match the value used by @@ -712,11 +712,11 @@ static int readJournalHdr( ** is being called from within pager_playback(). The local value ** of Pager.sectorSize is restored at the end of that routine. */ - rc = read32bits(&pPager->jfd, (u32 *)&pPager->sectorSize); + rc = read32bits(pPager->jfd, (u32 *)&pPager->sectorSize); if( rc ) return rc; pPager->journalOff += JOURNAL_HDR_SZ(pPager); - rc = sqlite3Io.xSeek(&pPager->jfd, pPager->journalOff); + rc = sqlite3Io.xSeek(pPager->jfd, pPager->journalOff); return rc; } @@ -761,19 +761,19 @@ static int writeMasterJournal(Pager *pPager, const char *zMaster){ } pPager->journalOff += (len+20); - rc = write32bits(&pPager->jfd, PAGER_MJ_PGNO(pPager)); + rc = write32bits(pPager->jfd, PAGER_MJ_PGNO(pPager)); if( rc!=SQLITE_OK ) return rc; - rc = sqlite3Io.xWrite(&pPager->jfd, zMaster, len); + rc = sqlite3Io.xWrite(pPager->jfd, zMaster, len); if( rc!=SQLITE_OK ) return rc; - rc = write32bits(&pPager->jfd, len); + rc = write32bits(pPager->jfd, len); if( rc!=SQLITE_OK ) return rc; - rc = write32bits(&pPager->jfd, cksum); + rc = write32bits(pPager->jfd, cksum); if( rc!=SQLITE_OK ) return rc; - rc = sqlite3Io.xWrite(&pPager->jfd, aJournalMagic, sizeof(aJournalMagic)); + rc = sqlite3Io.xWrite(pPager->jfd, aJournalMagic, sizeof(aJournalMagic)); pPager->needSync = !pPager->noSync; return rc; } @@ -851,7 +851,7 @@ static void pager_reset(Pager *pPager){ if( pPager->state>=PAGER_RESERVED ){ sqlite3pager_rollback(pPager); } - sqlite3Io.xUnlock(&pPager->fd, NO_LOCK); + sqlite3Io.xUnlock(pPager->fd, NO_LOCK); pPager->state = PAGER_UNLOCK; pPager->dbSize = -1; pPager->nRef = 0; @@ -923,7 +923,7 @@ static int pager_unwritelock(Pager *pPager){ assert( pPager->aInJournal==0 ); assert( pPager->dirtyCache==0 || pPager->useJournal==0 ); } - rc = sqlite3Io.xUnlock(&pPager->fd, SHARED_LOCK); + rc = sqlite3Io.xUnlock(pPager->fd, SHARED_LOCK); pPager->state = PAGER_SHARED; pPager->origDbSize = 0; pPager->setMaster = 0; @@ -978,7 +978,7 @@ static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int useCksum){ /* useCksum should be true for the main journal and false for ** statement journals. Verify that this is always the case */ - assert( jfd == (useCksum ? &pPager->jfd : &pPager->stfd) ); + assert( jfd == (useCksum ? pPager->jfd : pPager->stfd) ); rc = read32bits(jfd, &pgno); @@ -1033,9 +1033,9 @@ static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int useCksum){ assert( pPager->state>=PAGER_EXCLUSIVE || pPg!=0 ); TRACE3("PLAYBACK %d page %d\n", PAGERID(pPager), pgno); if( pPager->state>=PAGER_EXCLUSIVE && (pPg==0 || pPg->needSync==0) ){ - rc = sqlite3Io.xSeek(&pPager->fd, (pgno-1)*(i64)pPager->pageSize); + rc = sqlite3Io.xSeek(pPager->fd, (pgno-1)*(i64)pPager->pageSize); if( rc==SQLITE_OK ){ - rc = sqlite3Io.xWrite(&pPager->fd, aData, pPager->pageSize); + rc = sqlite3Io.xWrite(pPager->fd, aData, pPager->pageSize); } if( pPg ) pPg->dirty = 0; } @@ -1075,18 +1075,17 @@ static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int useCksum){ static int pager_delmaster(const char *zMaster){ int rc; int master_open = 0; - OsFile master; + OsFile *master = 0; char *zMasterJournal = 0; /* Contents of master journal file */ i64 nMasterJournal; /* Size of master journal file */ /* Open the master journal file exclusively in case some other process ** is running this routine also. Not that it makes too much difference. */ - memset(&master, 0, sizeof(master)); rc = sqlite3Io.xOpenReadOnly(zMaster, &master); if( rc!=SQLITE_OK ) goto delmaster_out; master_open = 1; - rc = sqlite3Io.xFileSize(&master, &nMasterJournal); + rc = sqlite3Io.xFileSize(master, &nMasterJournal); if( rc!=SQLITE_OK ) goto delmaster_out; if( nMasterJournal>0 ){ @@ -1101,7 +1100,7 @@ static int pager_delmaster(const char *zMaster){ rc = SQLITE_NOMEM; goto delmaster_out; } - rc = sqlite3Io.xRead(&master, zMasterJournal, nMasterJournal); + rc = sqlite3Io.xRead(master, zMasterJournal, nMasterJournal); if( rc!=SQLITE_OK ) goto delmaster_out; zJournal = zMasterJournal; @@ -1111,16 +1110,15 @@ static int pager_delmaster(const char *zMaster){ ** Open it and check if it points at the master journal. If ** so, return without deleting the master journal file. */ - OsFile journal; + OsFile *journal = 0; int c; - memset(&journal, 0, sizeof(journal)); rc = sqlite3Io.xOpenReadOnly(zJournal, &journal); if( rc!=SQLITE_OK ){ goto delmaster_out; } - rc = readMasterJournal(&journal, &zMasterPtr); + rc = readMasterJournal(journal, &zMasterPtr); sqlite3Io.xClose(&journal); if( rc!=SQLITE_OK ){ goto delmaster_out; @@ -1165,9 +1163,9 @@ static int pager_reload_cache(Pager *pPager){ char zBuf[SQLITE_MAX_PAGE_SIZE]; if( !pPg->dirty ) continue; if( (int)pPg->pgno <= pPager->origDbSize ){ - rc = sqlite3Io.xSeek(&pPager->fd, pPager->pageSize*(i64)(pPg->pgno-1)); + rc = sqlite3Io.xSeek(pPager->fd, pPager->pageSize*(i64)(pPg->pgno-1)); if( rc==SQLITE_OK ){ - rc = sqlite3Io.xRead(&pPager->fd, zBuf, pPager->pageSize); + rc = sqlite3Io.xRead(pPager->fd, zBuf, pPager->pageSize); } TRACE3("REFETCH %d page %d\n", PAGERID(pPager), pPg->pgno); if( rc ) break; @@ -1198,7 +1196,7 @@ static int pager_reload_cache(Pager *pPager){ */ static int pager_truncate(Pager *pPager, int nPage){ assert( pPager->state>=PAGER_EXCLUSIVE ); - return sqlite3Io.xTruncate(&pPager->fd, pPager->pageSize*(i64)nPage); + return sqlite3Io.xTruncate(pPager->fd, pPager->pageSize*(i64)nPage); } /* @@ -1266,7 +1264,7 @@ static int pager_playback(Pager *pPager){ ** the journal is empty. */ assert( pPager->journalOpen ); - rc = sqlite3Io.xFileSize(&pPager->jfd, &szJ); + rc = sqlite3Io.xFileSize(pPager->jfd, &szJ); if( rc!=SQLITE_OK ){ goto end_playback; } @@ -1276,7 +1274,7 @@ static int pager_playback(Pager *pPager){ ** present on disk, then the journal is not hot and does not need to be ** played back. */ - rc = readMasterJournal(&pPager->jfd, &zMaster); + rc = readMasterJournal(pPager->jfd, &zMaster); assert( rc!=SQLITE_DONE ); if( rc!=SQLITE_OK || (zMaster && !sqlite3Io.xFileExists(zMaster)) ){ sqliteFree(zMaster); @@ -1284,7 +1282,7 @@ static int pager_playback(Pager *pPager){ if( rc==SQLITE_DONE ) rc = SQLITE_OK; goto end_playback; } - sqlite3Io.xSeek(&pPager->jfd, 0); + sqlite3Io.xSeek(pPager->jfd, 0); pPager->journalOff = 0; /* This loop terminates either when the readJournalHdr() call returns @@ -1327,13 +1325,13 @@ static int pager_playback(Pager *pPager){ pPager->dbSize = mxPg; } - /* rc = sqlite3Io.xSeek(&pPager->jfd, JOURNAL_HDR_SZ(pPager)); */ + /* rc = sqlite3Io.xSeek(pPager->jfd, JOURNAL_HDR_SZ(pPager)); */ if( rc!=SQLITE_OK ) goto end_playback; /* Copy original pages out of the journal and back into the database file. */ for(i=0; ijfd, 1); + rc = pager_playback_one_page(pPager, pPager->jfd, 1); if( rc!=SQLITE_OK ){ if( rc==SQLITE_DONE ){ rc = SQLITE_OK; @@ -1400,7 +1398,7 @@ static int pager_stmt_playback(Pager *pPager){ #ifndef NDEBUG { i64 os_szJ; - rc = sqlite3Io.xFileSize(&pPager->jfd, &os_szJ); + rc = sqlite3Io.xFileSize(pPager->jfd, &os_szJ); if( rc!=SQLITE_OK ) return rc; assert( szJ==os_szJ ); } @@ -1426,7 +1424,7 @@ static int pager_stmt_playback(Pager *pPager){ /* Figure out how many records are in the statement journal. */ assert( pPager->stmtInUse && pPager->journalOpen ); - sqlite3Io.xSeek(&pPager->stfd, 0); + sqlite3Io.xSeek(pPager->stfd, 0); nRec = pPager->stmtNRec; /* Copy original pages out of the statement journal and back into the @@ -1435,7 +1433,7 @@ static int pager_stmt_playback(Pager *pPager){ ** journals. */ for(i=nRec-1; i>=0; i--){ - rc = pager_playback_one_page(pPager, &pPager->stfd, 0); + rc = pager_playback_one_page(pPager, pPager->stfd, 0); assert( rc!=SQLITE_DONE ); if( rc!=SQLITE_OK ) goto end_stmt_playback; } @@ -1448,7 +1446,7 @@ static int pager_stmt_playback(Pager *pPager){ ** If it is not zero, then Pager.stmtHdrOff is the offset to the start ** of the first journal header written during this statement transaction. */ - rc = sqlite3Io.xSeek(&pPager->jfd, pPager->stmtJSize); + rc = sqlite3Io.xSeek(pPager->jfd, pPager->stmtJSize); if( rc!=SQLITE_OK ){ goto end_stmt_playback; } @@ -1456,7 +1454,7 @@ static int pager_stmt_playback(Pager *pPager){ pPager->cksumInit = pPager->stmtCksum; assert( JOURNAL_HDR_SZ(pPager)<(pPager->pageSize+8) ); while( pPager->journalOff <= (hdrOff-(pPager->pageSize+8)) ){ - rc = pager_playback_one_page(pPager, &pPager->jfd, 1); + rc = pager_playback_one_page(pPager, pPager->jfd, 1); assert( rc!=SQLITE_DONE ); if( rc!=SQLITE_OK ) goto end_stmt_playback; } @@ -1473,7 +1471,7 @@ static int pager_stmt_playback(Pager *pPager){ nRec = (szJ - pPager->journalOff) / (pPager->pageSize+8); } for(i=nRec-1; i>=0 && pPager->journalOff < szJ; i--){ - rc = pager_playback_one_page(pPager, &pPager->jfd, 1); + rc = pager_playback_one_page(pPager, pPager->jfd, 1); assert( rc!=SQLITE_DONE ); if( rc!=SQLITE_OK ) goto end_stmt_playback; } @@ -1553,14 +1551,14 @@ int sqlite3_opentemp_count = 0; ** The OS will automatically delete the temporary file when it is ** closed. */ -static int sqlite3pager_opentemp(char *zFile, OsFile *fd){ +static int sqlite3pager_opentemp(char *zFile, OsFile **pFd){ int cnt = 8; int rc; sqlite3_opentemp_count++; /* Used for testing and analysis only */ do{ cnt--; sqlite3Io.xTempFileName(zFile); - rc = sqlite3Io.xOpenExclusive(zFile, fd, 1); + rc = sqlite3Io.xOpenExclusive(zFile, pFd, 1); }while( cnt>0 && rc!=SQLITE_OK && rc!=SQLITE_NOMEM ); return rc; } @@ -1588,7 +1586,7 @@ int sqlite3pager_open( Pager *pPager; char *zFullPathname = 0; int nameLen; - OsFile fd; + OsFile *fd; int rc = SQLITE_OK; int i; int tempFile = 0; @@ -1652,7 +1650,7 @@ int sqlite3pager_open( strcpy(pPager->zJournal, zFullPathname); sqliteFree(zFullPathname); strcpy(&pPager->zJournal[nameLen], "-journal"); - sqlite3Io.xCopyOsFile(&pPager->fd,&fd); + pPager->fd = fd; pPager->journalOpen = 0; pPager->useJournal = useJournal && !memDb; pPager->noReadlock = noReadlock && readOnly; @@ -1763,8 +1761,8 @@ void enable_simulated_io_errors(void){ void sqlite3pager_read_fileheader(Pager *pPager, int N, unsigned char *pDest){ memset(pDest, 0, N); if( MEMDB==0 ){ - sqlite3Io.xSeek(&pPager->fd, 0); - sqlite3Io.xRead(&pPager->fd, pDest, N); + sqlite3Io.xSeek(pPager->fd, 0); + sqlite3Io.xRead(pPager->fd, pDest, N); clear_simulated_io_error(); } } @@ -1784,7 +1782,7 @@ int sqlite3pager_pagecount(Pager *pPager){ if( pPager->dbSize>=0 ){ n = pPager->dbSize; } else { - if( sqlite3Io.xFileSize(&pPager->fd, &n)!=SQLITE_OK ){ + if( sqlite3Io.xFileSize(pPager->fd, &n)!=SQLITE_OK ){ pPager->errMask |= PAGER_ERR_DISK; return 0; } @@ -1916,7 +1914,7 @@ static int pager_wait_on_lock(Pager *pPager, int locktype){ rc = SQLITE_OK; }else{ do { - rc = sqlite3Io.xLock(&pPager->fd, locktype); + rc = sqlite3Io.xLock(pPager->fd, locktype); }while( rc==SQLITE_BUSY && sqlite3InvokeBusyHandler(pPager->pBusyHandler) ); if( rc==SQLITE_OK ){ pPager->state = locktype; @@ -1984,14 +1982,14 @@ int sqlite3pager_close(Pager *pPager){ sqlite3pager_rollback(pPager); enable_simulated_io_errors(); if( !MEMDB ){ - sqlite3Io.xUnlock(&pPager->fd, NO_LOCK); + sqlite3Io.xUnlock(pPager->fd, NO_LOCK); } assert( pPager->errMask || pPager->journalOpen==0 ); break; } case PAGER_SHARED: { if( !MEMDB ){ - sqlite3Io.xUnlock(&pPager->fd, NO_LOCK); + sqlite3Io.xUnlock(pPager->fd, NO_LOCK); } break; } @@ -2133,7 +2131,7 @@ static int syncJournal(Pager *pPager){ ** with the nRec computed from the size of the journal file. */ i64 jSz; - rc = sqlite3Io.xFileSize(&pPager->jfd, &jSz); + rc = sqlite3Io.xFileSize(pPager->jfd, &jSz); if( rc!=0 ) return rc; assert( pPager->journalOff==jSz ); } @@ -2146,20 +2144,20 @@ static int syncJournal(Pager *pPager){ */ if( pPager->fullSync ){ TRACE2("SYNC journal of %d\n", PAGERID(pPager)); - rc = sqlite3Io.xSync(&pPager->jfd, 0); + rc = sqlite3Io.xSync(pPager->jfd, 0); if( rc!=0 ) return rc; } - rc = sqlite3Io.xSeek(&pPager->jfd, + rc = sqlite3Io.xSeek(pPager->jfd, pPager->journalHdr + sizeof(aJournalMagic)); if( rc ) return rc; - rc = write32bits(&pPager->jfd, pPager->nRec); + rc = write32bits(pPager->jfd, pPager->nRec); if( rc ) return rc; - rc = sqlite3Io.xSeek(&pPager->jfd, pPager->journalOff); + rc = sqlite3Io.xSeek(pPager->jfd, pPager->journalOff); if( rc ) return rc; } TRACE2("SYNC journal of %d\n", PAGERID(pPager)); - rc = sqlite3Io.xSync(&pPager->jfd, pPager->fullSync); + rc = sqlite3Io.xSync(pPager->jfd, pPager->fullSync); if( rc!=0 ) return rc; pPager->journalStarted = 1; } @@ -2224,7 +2222,7 @@ static int pager_write_pagelist(PgHdr *pList){ while( pList ){ assert( pList->dirty ); - rc = sqlite3Io.xSeek(&pPager->fd, (pList->pgno-1)*(i64)pPager->pageSize); + rc = sqlite3Io.xSeek(pPager->fd, (pList->pgno-1)*(i64)pPager->pageSize); if( rc ) return rc; /* If there are dirty pages in the page cache with page numbers greater ** than Pager.dbSize, this means sqlite3pager_truncate() was called to @@ -2234,7 +2232,7 @@ static int pager_write_pagelist(PgHdr *pList){ if( pList->pgno<=pPager->dbSize ){ CODEC(pPager, PGHDR_TO_DATA(pList), pList->pgno, 6); TRACE3("STORE %d page %d\n", PAGERID(pPager), pList->pgno); - rc = sqlite3Io.xWrite(&pPager->fd, PGHDR_TO_DATA(pList), + rc = sqlite3Io.xWrite(pPager->fd, PGHDR_TO_DATA(pList), pPager->pageSize); CODEC(pPager, PGHDR_TO_DATA(pList), pList->pgno, 0); TEST_INCR(pPager->nWrite); @@ -2282,7 +2280,7 @@ static PgHdr *pager_get_all_dirty_pages(Pager *pPager){ static int hasHotJournal(Pager *pPager){ if( !pPager->useJournal ) return 0; if( !sqlite3Io.xFileExists(pPager->zJournal) ) return 0; - if( sqlite3Io.xCheckReservedLock(&pPager->fd) ) return 0; + if( sqlite3Io.xCheckReservedLock(pPager->fd) ) return 0; if( sqlite3pager_pagecount(pPager)==0 ){ sqlite3Io.xDelete(pPager->zJournal); return 0; @@ -2361,9 +2359,9 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){ ** second process will get to this point in the code and fail to ** obtain it's own EXCLUSIVE lock on the database file. */ - rc = sqlite3Io.xLock(&pPager->fd, EXCLUSIVE_LOCK); + rc = sqlite3Io.xLock(pPager->fd, EXCLUSIVE_LOCK); if( rc!=SQLITE_OK ){ - sqlite3Io.xUnlock(&pPager->fd, NO_LOCK); + sqlite3Io.xUnlock(pPager->fd, NO_LOCK); pPager->state = PAGER_UNLOCK; return rc; } @@ -2379,7 +2377,7 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){ */ rc = sqlite3Io.xOpenReadOnly(pPager->zJournal, &pPager->jfd); if( rc!=SQLITE_OK ){ - sqlite3Io.xUnlock(&pPager->fd, NO_LOCK); + sqlite3Io.xUnlock(pPager->fd, NO_LOCK); pPager->state = PAGER_UNLOCK; return SQLITE_BUSY; } @@ -2536,16 +2534,16 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){ }else{ int rc; assert( MEMDB==0 ); - rc = sqlite3Io.xSeek(&pPager->fd, (pgno-1)*(i64)pPager->pageSize); + rc = sqlite3Io.xSeek(pPager->fd, (pgno-1)*(i64)pPager->pageSize); if( rc==SQLITE_OK ){ - rc = sqlite3Io.xRead(&pPager->fd, PGHDR_TO_DATA(pPg), + rc = sqlite3Io.xRead(pPager->fd, PGHDR_TO_DATA(pPg), pPager->pageSize); } TRACE3("FETCH %d page %d\n", PAGERID(pPager), pPg->pgno); CODEC(pPager, PGHDR_TO_DATA(pPg), pPg->pgno, 3); if( rc!=SQLITE_OK ){ i64 fileSize; - if( sqlite3Io.xFileSize(&pPager->fd,&fileSize)!=SQLITE_OK + if( sqlite3Io.xFileSize(pPager->fd,&fileSize)!=SQLITE_OK || fileSize>=pgno*pPager->pageSize ){ sqlite3pager_unref(PGHDR_TO_DATA(pPg)); return rc; @@ -2675,9 +2673,9 @@ static int pager_open_journal(Pager *pPager){ if( rc!=SQLITE_OK ){ goto failed_to_open_journal; } - SET_FULLSYNC(pPager->jfd, pPager->fullSync); - SET_FULLSYNC(pPager->fd, pPager->fullSync); - sqlite3Io.xOpenDirectory(pPager->zDirectory, &pPager->jfd); + sqlite3Io.xSetFullSync(pPager->jfd, pPager->fullSync); + sqlite3Io.xSetFullSync(pPager->fd, pPager->fullSync); + sqlite3Io.xOpenDirectory(pPager->zDirectory, pPager->jfd); pPager->journalOpen = 1; pPager->journalStarted = 0; pPager->needSync = 0; @@ -2705,7 +2703,7 @@ static int pager_open_journal(Pager *pPager){ failed_to_open_journal: sqliteFree(pPager->aInJournal); pPager->aInJournal = 0; - sqlite3Io.xUnlock(&pPager->fd, NO_LOCK); + sqlite3Io.xUnlock(pPager->fd, NO_LOCK); pPager->state = PAGER_UNLOCK; return rc; } @@ -2749,7 +2747,7 @@ int sqlite3pager_begin(void *pData, int exFlag){ pPager->state = PAGER_EXCLUSIVE; pPager->origDbSize = pPager->dbSize; }else{ - rc = sqlite3Io.xLock(&pPager->fd, RESERVED_LOCK); + rc = sqlite3Io.xLock(pPager->fd, RESERVED_LOCK); if( rc==SQLITE_OK ){ pPager->state = PAGER_RESERVED; if( exFlag ){ @@ -2860,7 +2858,7 @@ int sqlite3pager_write(void *pData){ store32bits(cksum, pPg, pPager->pageSize); szPg = pPager->pageSize+8; store32bits(pPg->pgno, pPg, -4); - rc = sqlite3Io.xWrite(&pPager->jfd, &((char*)pData)[-4], szPg); + rc = sqlite3Io.xWrite(pPager->jfd, &((char*)pData)[-4], szPg); pPager->journalOff += szPg; TRACE4("JOURNAL %d page %d needSync=%d\n", PAGERID(pPager), pPg->pgno, pPg->needSync); @@ -2909,7 +2907,7 @@ int sqlite3pager_write(void *pData){ }else{ store32bits(pPg->pgno, pPg, -4); CODEC(pPager, pData, pPg->pgno, 7); - rc = sqlite3Io.xWrite(&pPager->stfd,((char*)pData)-4, + rc = sqlite3Io.xWrite(pPager->stfd,((char*)pData)-4, pPager->pageSize+4); TRACE3("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno); CODEC(pPager, pData, pPg->pgno, 0); @@ -3272,11 +3270,11 @@ int sqlite3pager_stmt_begin(Pager *pPager){ assert( pPager->journalOpen ); pPager->aInStmt = sqliteMalloc( pPager->dbSize/8 + 1 ); if( pPager->aInStmt==0 ){ - sqlite3Io.xLock(&pPager->fd, SHARED_LOCK); + sqlite3Io.xLock(pPager->fd, SHARED_LOCK); return SQLITE_NOMEM; } #ifndef NDEBUG - rc = sqlite3Io.xFileSize(&pPager->jfd, &pPager->stmtJSize); + rc = sqlite3Io.xFileSize(pPager->jfd, &pPager->stmtJSize); if( rc ) goto stmt_begin_failed; assert( pPager->stmtJSize == pPager->journalOff ); #endif @@ -3309,8 +3307,8 @@ int sqlite3pager_stmt_commit(Pager *pPager){ PgHdr *pPg, *pNext; TRACE2("STMT-COMMIT %d\n", PAGERID(pPager)); if( !MEMDB ){ - sqlite3Io.xSeek(&pPager->stfd, 0); - /* sqlite3Io.xTruncate(&pPager->stfd, 0); */ + sqlite3Io.xSeek(pPager->stfd, 0); + /* sqlite3Io.xTruncate(pPager->stfd, 0); */ sqliteFree( pPager->aInStmt ); pPager->aInStmt = 0; } @@ -3513,7 +3511,7 @@ int sqlite3pager_sync(Pager *pPager, const char *zMaster, Pgno nTrunc){ /* Sync the database file. */ if( !pPager->noSync ){ - rc = sqlite3Io.xSync(&pPager->fd, 0); + rc = sqlite3Io.xSync(pPager->fd, 0); } pPager->state = PAGER_SYNCED; @@ -3627,11 +3625,7 @@ int sqlite3pager_movepage(Pager *pPager, void *pData, Pgno pgno){ ** PENDING_LOCK, or EXCLUSIVE_LOCK. */ int sqlite3pager_lockstate(Pager *pPager){ -#ifdef OS_TEST - return pPager->fd->fd.locktype; -#else - return pPager->fd.locktype; -#endif + return sqlite3Io.xLockState(pPager->fd); } #endif diff --git a/src/test1.c b/src/test1.c index 402ff8c42c..870b729d02 100644 --- a/src/test1.c +++ b/src/test1.c @@ -13,7 +13,7 @@ ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** -** $Id: test1.c,v 1.166 2005/11/26 00:25:03 drh Exp $ +** $Id: test1.c,v 1.167 2005/11/29 03:13:22 drh Exp $ */ #include "sqliteInt.h" #include "tcl.h" @@ -2429,7 +2429,7 @@ static int test_sqlite3OsOpenReadWrite( int objc, Tcl_Obj *CONST objv[] ){ - OsFile * pFile; + OsFile *pFile; int rc; int dummy; char zBuf[100]; @@ -2440,10 +2440,8 @@ static int test_sqlite3OsOpenReadWrite( return TCL_ERROR; } - pFile = sqliteMalloc(sizeof(OsFile)); - rc = sqlite3Io.xOpenReadWrite(Tcl_GetString(objv[1]), pFile, &dummy); + rc = sqlite3Io.xOpenReadWrite(Tcl_GetString(objv[1]), &pFile, &dummy); if( rc!=SQLITE_OK ){ - sqliteFree(pFile); Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); return TCL_ERROR; } @@ -2461,7 +2459,7 @@ static int test_sqlite3OsClose( int objc, Tcl_Obj *CONST objv[] ){ - OsFile * pFile; + OsFile *pFile; int rc; if( objc!=2 ){ @@ -2473,12 +2471,11 @@ static int test_sqlite3OsClose( if( getFilePointer(interp, Tcl_GetString(objv[1]), &pFile) ){ return TCL_ERROR; } - rc = sqlite3Io.xClose(pFile); + rc = sqlite3Io.xClose(&pFile); if( rc!=SQLITE_OK ){ Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); return TCL_ERROR; } - sqliteFree(pFile); return TCL_OK; } diff --git a/src/test2.c b/src/test2.c index bb02af5da4..39e9148974 100644 --- a/src/test2.c +++ b/src/test2.c @@ -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.36 2005/11/26 00:25:04 drh Exp $ +** $Id: test2.c,v 1.37 2005/11/29 03:13:22 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -524,7 +524,7 @@ static int fake_big_file( int rc; int n; i64 offset; - OsFile fd; + OsFile *fd = 0; int readOnly = 0; if( argc!=3 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], @@ -532,7 +532,6 @@ static int fake_big_file( return TCL_ERROR; } if( Tcl_GetInt(interp, argv[1], &n) ) return TCL_ERROR; - memset(&fd, 0, sizeof(fd)); rc = sqlite3Io.xOpenReadWrite(argv[2], &fd, &readOnly); if( rc ){ Tcl_AppendResult(interp, "open failed: ", errorName(rc), 0); @@ -540,12 +539,12 @@ static int fake_big_file( } offset = n; offset *= 1024*1024; - rc = sqlite3Io.xSeek(&fd, offset); + rc = sqlite3Io.xSeek(fd, offset); if( rc ){ Tcl_AppendResult(interp, "seek failed: ", errorName(rc), 0); return TCL_ERROR; } - rc = sqlite3Io.xWrite(&fd, "Hello, World!", 14); + rc = sqlite3Io.xWrite(fd, "Hello, World!", 14); sqlite3Io.xClose(&fd); if( rc ){ Tcl_AppendResult(interp, "write failed: ", errorName(rc), 0); diff --git a/src/test6.c b/src/test6.c index 414480ba0a..3407ff2b50 100644 --- a/src/test6.c +++ b/src/test6.c @@ -18,6 +18,7 @@ #include "sqliteInt.h" #include "os.h" #include "tcl.h" +#if 0 /* ** A copy of the original sqlite3Io structure @@ -25,16 +26,16 @@ static struct sqlite3IoVtbl origIo; /* -** The pAux part of OsFile points to this structure. +** The OsFile structure for the crash-test backend. The pBase field +** points to an OsFile structure for the native backend. */ -typedef struct OsTestFile OsTestFile; -struct OsTestFile { +struct OsFile { u8 **apBlk; /* Array of blocks that have been written to. */ int nBlk; /* Size of apBlock. */ int nMaxWrite; /* Largest offset written to. */ char *zName; /* File name */ OsFile *pBase; /* Base class */ - OsTestFile *pNext; /* Next in a list of them all */ + OsFile *pNext; /* Next in a list of them all */ }; /* @@ -102,9 +103,8 @@ static OsTestFile *pAllFiles = 0; /* ** Initialise the os_test.c specific fields of pFile. */ -static void initFile(OsFile *id, char const *zName){ - OsTestFile *pFile = sqliteMalloc(sizeof(OsTestFile) + strlen(zName)+1); - id->pAux = pFile; +static void initFile(OsFile **pId, char const *zName){ + OsFile *pFile = *pId = sqliteMalloc(sizeof(OsFile) + strlen(zName)+1); pFile->nMaxWrite = 0; pFile->nBlk = 0; pFile->apBlk = 0; @@ -120,11 +120,11 @@ static void initFile(OsFile *id, char const *zName){ ** and unlink the structure from the pAllFiles list. */ static void closeFile(OsFile *id){ - OsTestFile *pFile = (OsTestFile*)id->pAux; + OsFile *pFile = id; if( pFile==pAllFiles ){ pAllFiles = pFile->pNext; }else{ - OsTestFile *p; + OsFile *p; for(p=pAllFiles; p->pNext!=pFile; p=p->pNext ){ assert( p ); } @@ -137,14 +137,14 @@ static void closeFile(OsFile *id){ ** Return the current seek offset from the start of the file. This ** is unix-only code. */ -static i64 osTell(OsTestFile *pFile){ +static i64 osTell(OsFile *pFile){ return lseek(pFile->pBase->h, 0, SEEK_CUR); } /* ** Load block 'blk' into the cache of pFile. */ -static int cacheBlock(OsTestFile *pFile, int blk){ +static int cacheBlock(OsFile *pFile, int blk){ if( blk>=pFile->nBlk ){ int n = ((pFile->nBlk * 2) + 100 + blk); /* if( pFile->nBlk==0 ){ printf("DIRTY %s\n", pFile->zName); } */ @@ -184,7 +184,7 @@ static int cacheBlock(OsTestFile *pFile, int blk){ ** 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(OsTestFile *pFile, int crash){ +static int writeCache2(OsFile *pFile, int crash){ int i; int nMax = pFile->nMaxWrite; i64 offset; @@ -249,7 +249,7 @@ printf("Writing block %d of %s\n", i, pFile->zName); /* ** Write the cache to disk. */ -static int writeCache(OsTestFile *pFile){ +static int writeCache(OsFile *pFile){ if( pFile->apBlk ){ int c = crashRequired(pFile->zName); if( c ){ @@ -275,8 +275,8 @@ static int crashClose(OsFile *id){ if( id->pAux ) return SQLITE_OK; if( id->isOpen ){ /* printf("CLOSE %s (%d blocks)\n", (*id)->zName, (*id)->nBlk); */ - writeCache((OsTestFile*)id->pAux); - origIo.xClose(id); + writeCache(id); + origIo.xClose(&id->pBase); } closeFile(id); return SQLITE_OK; @@ -472,15 +472,18 @@ static int crashParamsObjCmd( sqlite3Io.xOpenReadWrite = crashOpenReadWrite; sqlite3Io.xOpenExclusive = crashOpenExclusive; sqlite3Io.xOpenReadOnly = crashOpenReadOnly; - sqlite3Io.xCopyOsFile = crashCopyOsFile; + sqlite3Io.xSet return TCL_OK; } +#endif /* ** This procedure registers the TCL procedures defined in this file. */ int Sqlitetest6_Init(Tcl_Interp *interp){ +#if 0 Tcl_CreateObjCommand(interp, "sqlite3_crashparams", crashParamsObjCmd, 0, 0); +#endif return TCL_OK; } diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 145664044d..782e0163c6 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -202,7 +202,7 @@ static int opcodeNoPush(u8 op){ NOPUSH_MASK_6 + (NOPUSH_MASK_7<<16), NOPUSH_MASK_8 + (NOPUSH_MASK_9<<16) }; - assert( op>=0 && op<32*5 ); + assert( op<32*5 ); return (masks[op>>5] & (1<<(op&0x1F))); } @@ -967,7 +967,7 @@ static int vdbeCommit(sqlite3 *db){ int needSync = 0; char *zMaster = 0; /* File-name for the master journal */ char const *zMainFile = sqlite3BtreeGetFilename(db->aDb[0].pBt); - OsFile master; + OsFile *master = 0; /* Select a master journal file name */ do { @@ -981,7 +981,6 @@ static int vdbeCommit(sqlite3 *db){ }while( sqlite3Io.xFileExists(zMaster) ); /* Open the master journal. */ - memset(&master, 0, sizeof(master)); rc = sqlite3Io.xOpenExclusive(zMaster, &master, 0); if( rc!=SQLITE_OK ){ sqliteFree(zMaster); @@ -1003,7 +1002,7 @@ static int vdbeCommit(sqlite3 *db){ if( !needSync && !sqlite3BtreeSyncDisabled(pBt) ){ needSync = 1; } - rc = sqlite3Io.xWrite(&master, zFile, strlen(zFile)+1); + rc = sqlite3Io.xWrite(master, zFile, strlen(zFile)+1); if( rc!=SQLITE_OK ){ sqlite3Io.xClose(&master); sqlite3Io.xDelete(zMaster); @@ -1018,9 +1017,9 @@ static int vdbeCommit(sqlite3 *db){ ** the master journal file is store in so that it gets synced too. */ zMainFile = sqlite3BtreeGetDirname(db->aDb[0].pBt); - rc = sqlite3Io.xOpenDirectory(zMainFile, &master); + rc = sqlite3Io.xOpenDirectory(zMainFile, master); if( rc!=SQLITE_OK || - (needSync && (rc=sqlite3Io.xSync(&master,0))!=SQLITE_OK) ){ + (needSync && (rc=sqlite3Io.xSync(master,0))!=SQLITE_OK) ){ sqlite3Io.xClose(&master); sqlite3Io.xDelete(zMaster); sqliteFree(zMaster); diff --git a/test/attach.test b/test/attach.test index b96d86d12b..4799ce1e51 100644 --- a/test/attach.test +++ b/test/attach.test @@ -12,7 +12,7 @@ # focus of this script is testing the ATTACH and DETACH commands # and related functionality. # -# $Id: attach.test,v 1.40 2005/03/29 03:11:00 danielk1977 Exp $ +# $Id: attach.test,v 1.41 2005/11/29 03:13:22 drh Exp $ # set testdir [file dirname $argv0] @@ -742,5 +742,4 @@ db close file delete -force test2.db file delete -force no-such-file - finish_test