Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Change the OS interface layer to use traditional direct function call implementations instead of the more complicated virtual function table. Omit the asynchronous I/O demo. (CVS 2870) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
2529c2e11fa1d345ec61f647e4f6fae2 |
User & Date: | drh 2006-01-06 14:32:20.000 |
Context
2006-01-06
| ||
14:41 | Remove vestigial file: crashtest1.c (CVS 2871) (check-in: 6676c7031d user: drh tags: trunk) | |
14:32 | Change the OS interface layer to use traditional direct function call implementations instead of the more complicated virtual function table. Omit the asynchronous I/O demo. (CVS 2870) (check-in: 2529c2e11f user: drh tags: trunk) | |
13:00 | Add some simple tests and fixes for shared-schema locking. (CVS 2869) (check-in: d054bed15a user: danielk1977 tags: trunk) | |
Changes
Changes to Makefile.in.
︙ | ︙ | |||
187 188 189 190 191 192 193 | $(TOP)/src/printf.c \ $(TOP)/src/test1.c \ $(TOP)/src/test2.c \ $(TOP)/src/test3.c \ $(TOP)/src/test4.c \ $(TOP)/src/test5.c \ $(TOP)/src/test6.c \ | < | 187 188 189 190 191 192 193 194 195 196 197 198 199 200 | $(TOP)/src/printf.c \ $(TOP)/src/test1.c \ $(TOP)/src/test2.c \ $(TOP)/src/test3.c \ $(TOP)/src/test4.c \ $(TOP)/src/test5.c \ $(TOP)/src/test6.c \ $(TOP)/src/utf.c \ $(TOP)/src/util.c \ $(TOP)/src/vdbe.c \ $(TOP)/src/md5.c \ $(TOP)/src/where.c # Header files used by all library source files. |
︙ | ︙ | |||
421 422 423 424 425 426 427 | $(LTCOMPILE) -DTCL_USE_STUBS=1 -o $@ -c $(TOP)/src/tclsqlite.c tclsqlite3: tclsqlite-shell.lo libsqlite3.la $(LTLINK) -o tclsqlite3 tclsqlite-shell.lo \ libsqlite3.la $(LIBTCL) testfixture$(TEXE): $(TOP)/src/tclsqlite.c libsqlite3.la $(TESTSRC) | | | | 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 | $(LTCOMPILE) -DTCL_USE_STUBS=1 -o $@ -c $(TOP)/src/tclsqlite.c tclsqlite3: tclsqlite-shell.lo libsqlite3.la $(LTLINK) -o tclsqlite3 tclsqlite-shell.lo \ libsqlite3.la $(LIBTCL) testfixture$(TEXE): $(TOP)/src/tclsqlite.c libsqlite3.la $(TESTSRC) $(LTLINK) -DTCLSH=1 -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1 \ $(TEMP_STORE) -o testfixture $(TESTSRC) $(TOP)/src/tclsqlite.c \ libsqlite3.la $(LIBTCL) fulltest: testfixture$(TEXE) sqlite3$(TEXE) ./testfixture $(TOP)/test/all.test test: testfixture$(TEXE) sqlite3$(TEXE) |
︙ | ︙ |
Changes to main.mk.
︙ | ︙ | |||
129 130 131 132 133 134 135 | $(TOP)/src/printf.c \ $(TOP)/src/test1.c \ $(TOP)/src/test2.c \ $(TOP)/src/test3.c \ $(TOP)/src/test4.c \ $(TOP)/src/test5.c \ $(TOP)/src/test6.c \ | < < < | 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | $(TOP)/src/printf.c \ $(TOP)/src/test1.c \ $(TOP)/src/test2.c \ $(TOP)/src/test3.c \ $(TOP)/src/test4.c \ $(TOP)/src/test5.c \ $(TOP)/src/test6.c \ $(TOP)/src/utf.c \ $(TOP)/src/util.c \ $(TOP)/src/vdbe.c \ $(TOP)/src/md5.c \ $(TOP)/src/where.c # Header files used by all library source files. # HDR = \ sqlite3.h \ $(TOP)/src/btree.h \ $(TOP)/src/hash.h \ opcodes.h \ |
︙ | ︙ | |||
354 355 356 357 358 359 360 | # Rules for building test programs and for running tests # tclsqlite3: $(TOP)/src/tclsqlite.c libsqlite3.a $(TCCX) $(TCL_FLAGS) -DTCLSH=1 -o tclsqlite3 \ $(TOP)/src/tclsqlite.c libsqlite3.a $(LIBTCL) $(THREADLIB) testfixture$(EXE): $(TOP)/src/tclsqlite.c libsqlite3.a $(TESTSRC) | | > | 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 | # Rules for building test programs and for running tests # tclsqlite3: $(TOP)/src/tclsqlite.c libsqlite3.a $(TCCX) $(TCL_FLAGS) -DTCLSH=1 -o tclsqlite3 \ $(TOP)/src/tclsqlite.c libsqlite3.a $(LIBTCL) $(THREADLIB) testfixture$(EXE): $(TOP)/src/tclsqlite.c libsqlite3.a $(TESTSRC) $(TCCX) $(TCL_FLAGS) -DTCLSH=1 -DSQLITE_TEST=1 -DSQLITE_CRASH_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 test: testfixture$(EXE) sqlite3$(EXE) |
︙ | ︙ |
Changes to src/btree.c.
1 2 3 4 5 6 7 8 9 10 11 | /* ** 2004 April 6 ** ** 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. ** ************************************************************************* | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /* ** 2004 April 6 ** ** 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. ** ************************************************************************* ** $Id: btree.c,v 1.283 2006/01/06 14:32:20 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to ** ** Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3: ** "Sorting And Searching", pages 473-480. Addison-Wesley ** Publishing Company, Reading, Massachusetts. |
︙ | ︙ | |||
1567 1568 1569 1570 1571 1572 1573 | } p->inTrans = TRANS_NONE; p->pSqlite = pSqlite; /* Try to find an existing Btree structure opened on zFilename. */ #ifndef SQLITE_OMIT_SHARED_CACHE if( pTsd->useSharedData && zFilename && !isMemdb ){ | | | 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 | } p->inTrans = TRANS_NONE; p->pSqlite = pSqlite; /* Try to find an existing Btree structure opened on zFilename. */ #ifndef SQLITE_OMIT_SHARED_CACHE if( pTsd->useSharedData && zFilename && !isMemdb ){ char *zFullPathname = sqlite3OsFullPathname(zFilename); if( !zFullPathname ){ sqliteFree(p); return SQLITE_NOMEM; } for(pBt=pTsd->pBtree; pBt; pBt=pBt->pNext){ if( 0==strcmp(zFullPathname, sqlite3pager_filename(pBt->pPager)) ){ p->pBt = pBt; |
︙ | ︙ |
Changes to src/date.c.
︙ | ︙ | |||
12 13 14 15 16 17 18 | ** This file contains the C functions that implement date and time ** functions for SQLite. ** ** There is only one exported symbol in this file - the function ** sqlite3RegisterDateTimeFunctions() found at the bottom of the file. ** All other code has file scope. ** | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | ** This file contains the C functions that implement date and time ** functions for SQLite. ** ** There is only one exported symbol in this file - the function ** sqlite3RegisterDateTimeFunctions() found at the bottom of the file. ** All other code has file scope. ** ** $Id: date.c,v 1.48 2006/01/06 14:32:20 drh Exp $ ** ** NOTES: ** ** SQLite processes all times and dates as Julian Day numbers. The ** dates and times are stored as the number of days since noon ** in Greenwich on November 24, 4714 B.C. according to the Gregorian ** calendar system. |
︙ | ︙ | |||
307 308 309 310 311 312 313 | memset(p, 0, sizeof(*p)); if( parseYyyyMmDd(zDate,p)==0 ){ return 0; }else if( parseHhMmSs(zDate, p)==0 ){ return 0; }else if( sqlite3StrICmp(zDate,"now")==0){ double r; | | | 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 | memset(p, 0, sizeof(*p)); if( parseYyyyMmDd(zDate,p)==0 ){ return 0; }else if( parseHhMmSs(zDate, p)==0 ){ return 0; }else if( sqlite3StrICmp(zDate,"now")==0){ double r; sqlite3OsCurrentTime(&r); p->rJD = r; p->validJD = 1; return 0; }else if( sqlite3IsNumber(zDate, 0, SQLITE_UTF8) ){ getValue(zDate, &p->rJD); p->validJD = 1; return 0; |
︙ | ︙ | |||
405 406 407 408 409 410 411 | int s = x.s + 0.5; x.s = s; } x.tz = 0; x.validJD = 0; computeJD(&x); t = (x.rJD-2440587.5)*86400.0 + 0.5; | | | | 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 | int s = x.s + 0.5; x.s = s; } x.tz = 0; x.validJD = 0; computeJD(&x); t = (x.rJD-2440587.5)*86400.0 + 0.5; sqlite3OsEnterMutex(); pTm = localtime(&t); y.Y = pTm->tm_year + 1900; y.M = pTm->tm_mon + 1; y.D = pTm->tm_mday; y.h = pTm->tm_hour; y.m = pTm->tm_min; y.s = pTm->tm_sec; sqlite3OsLeaveMutex(); y.validYMD = 1; y.validHMS = 1; y.validJD = 0; y.validTZ = 0; computeJD(&y); return y.rJD - x.rJD; } |
︙ | ︙ | |||
938 939 940 941 942 943 944 | extern int sqlite3_current_time; /* See os_XXX.c */ if( sqlite3_current_time ){ t = sqlite3_current_time; } } #endif | | | | 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 | extern int sqlite3_current_time; /* See os_XXX.c */ if( sqlite3_current_time ){ t = sqlite3_current_time; } } #endif sqlite3OsEnterMutex(); strftime(zBuf, 20, zFormat, gmtime(&t)); sqlite3OsLeaveMutex(); sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); } #endif /* ** This function registered all of the above C functions as SQL |
︙ | ︙ |
Changes to src/main.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** ** $Id: main.c,v 1.317 2006/01/06 14:32:20 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> /* ** The following constant value is used by the SQLITE_BIGENDIAN and |
︙ | ︙ | |||
332 333 334 335 336 337 338 | delay = delays[NDELAY-1]; prior = totals[NDELAY-1] + delay*(count-(NDELAY-1)); } if( prior + delay > timeout ){ delay = timeout - prior; if( delay<=0 ) return 0; } | | | | 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 | delay = delays[NDELAY-1]; prior = totals[NDELAY-1] + delay*(count-(NDELAY-1)); } if( prior + delay > timeout ){ delay = timeout - prior; if( delay<=0 ) return 0; } sqlite3OsSleep(delay); return 1; #else int timeout = ((sqlite3 *)ptr)->busyTimeout; if( (count+1)*1000 > timeout ){ return 0; } sqlite3OsSleep(1000); return 1; #endif } /* ** Invoke the given busy handler. ** |
︙ | ︙ |
Changes to src/os.c.
︙ | ︙ | |||
65 66 67 68 69 70 71 | } int sqlite3OsLockState(OsFile *id){ return id->pMethod->xLockState(id); } int sqlite3OsCheckReservedLock(OsFile *id){ return id->pMethod->xCheckReservedLock(id); } | < < < | 65 66 67 68 69 70 71 | } int sqlite3OsLockState(OsFile *id){ return id->pMethod->xLockState(id); } int sqlite3OsCheckReservedLock(OsFile *id){ return id->pMethod->xCheckReservedLock(id); } |
Changes to src/os.h.
︙ | ︙ | |||
14 15 16 17 18 19 20 | ** "os.c") attempt to abstract the underlying operating system so that ** the SQLite library will work on both POSIX and windows systems. */ #ifndef _SQLITE_OS_H_ #define _SQLITE_OS_H_ /* | | | < < | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | ** "os.c") attempt to abstract the underlying operating system so that ** the SQLite library will work on both POSIX and windows systems. */ #ifndef _SQLITE_OS_H_ #define _SQLITE_OS_H_ /* ** Figure out if we are dealing with Unix, Windows, or some other ** operating system. */ #if !defined(OS_UNIX) && !defined(OS_OTHER) # define OS_OTHER 0 # ifndef OS_WIN # if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__) # define OS_WIN 1 # define OS_UNIX 0 # else # define OS_WIN 0 |
︙ | ︙ | |||
68 69 70 71 72 73 74 75 76 77 78 79 80 81 | ** prefix to reflect your program's name, so that if your program exits ** prematurely, old temporary files can be easily identified. This can be done ** using -DTEMP_FILE_PREFIX=myprefix_ on the compiler command line. */ #ifndef TEMP_FILE_PREFIX # define TEMP_FILE_PREFIX "sqlite_" #endif /* ** Forward declarations */ typedef struct OsFile OsFile; typedef struct IoMethod IoMethod; | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | ** prefix to reflect your program's name, so that if your program exits ** prematurely, old temporary files can be easily identified. This can be done ** using -DTEMP_FILE_PREFIX=myprefix_ on the compiler command line. */ #ifndef TEMP_FILE_PREFIX # define TEMP_FILE_PREFIX "sqlite_" #endif /* ** Define the interfaces for Unix and for Windows. */ #if OS_UNIX #define sqlite3OsOpenReadWrite sqlite3UnixOpenReadWrite #define sqlite3OsOpenExclusive sqlite3UnixOpenExclusive #define sqlite3OsOpenReadOnly sqlite3UnixOpenReadOnly #define sqlite3OsDelete sqlite3UnixDelete #define sqlite3OsFileExists sqlite3UnixFileExists #define sqlite3OsFullPathname sqlite3UnixFullPathname #define sqlite3OsIsDirWritable sqlite3UnixIsDirWritable #define sqlite3OsSyncDirectory sqlite3UnixSyncDirectory #define sqlite3OsTempFileName sqlite3UnixTempFileName #define sqlite3OsRandomSeed sqlite3UnixRandomSeed #define sqlite3OsSleep sqlite3UnixSleep #define sqlite3OsCurrentTime sqlite3UnixCurrentTime #define sqlite3OsEnterMutex sqlite3UnixEnterMutex #define sqlite3OsLeaveMutex sqlite3UnixLeaveMutex #define sqlite3OsInMutex sqlite3UnixInMutex #define sqlite3OsThreadSpecificData sqlite3UnixThreadSpecificData #define sqlite3OsMalloc sqlite3GenericMalloc #define sqlite3OsRealloc sqlite3GenericRealloc #define sqlite3OsFree sqlite3GenericFree #define sqlite3OsAllocationSize sqlite3GenericAllocationSize #endif #if OS_WIN #define sqlite3OsOpenReadWrite sqlite3WinOpenReadWrite #define sqlite3OsOpenExclusive sqlite3WinOpenExclusive #define sqlite3OsOpenReadOnly sqlite3WinOpenReadOnly #define sqlite3OsDelete sqlite3WinDelete #define sqlite3OsFileExists sqlite3WinFileExists #define sqlite3OsFullPathname sqlite3WinFullPathname #define sqlite3OsIsDirWritable sqlite3WinIsDirWritable #define sqlite3OsSyncDirectory sqlite3WinSyncDirectory #define sqlite3OsTempFileName sqlite3WinTempFileName #define sqlite3OsRandomSeed sqlite3WinRandomSeed #define sqlite3OsSleep sqlite3WinSleep #define sqlite3OsCurrentTime sqlite3WinCurrentTime #define sqlite3OsEnterMutex sqlite3WinEnterMutex #define sqlite3OsLeaveMutex sqlite3WinLeaveMutex #define sqlite3OsInMutex sqlite3WinInMutex #define sqlite3OsThreadSpecificData sqlite3WinThreadSpecificData #define sqlite3OsMalloc sqlite3GenericMalloc #define sqlite3OsRealloc sqlite3GenericRealloc #define sqlite3OsFree sqlite3GenericFree #define sqlite3OsAllocationSize sqlite3GenericAllocationSize #endif /* ** If using an alternative OS interface, then we must have an "os_other.h" ** header file available for that interface. Presumably the "os_other.h" ** header file contains #defines similar to those above. */ #if OS_OTHER # include "os_other.h" #endif /* ** Forward declarations */ typedef struct OsFile OsFile; typedef struct IoMethod IoMethod; |
︙ | ︙ | |||
200 201 202 203 204 205 206 | #endif #define RESERVED_BYTE (PENDING_BYTE+1) #define SHARED_FIRST (PENDING_BYTE+2) #define SHARED_SIZE 510 /* | < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < > > > > > > > > > > > > > > > > > > > > | 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 | #endif #define RESERVED_BYTE (PENDING_BYTE+1) #define SHARED_FIRST (PENDING_BYTE+2) #define SHARED_SIZE 510 /* ** Prototypes for operating system interface routines. */ int sqlite3OsClose(OsFile**); int sqlite3OsOpenDirectory(OsFile*, const char*); int sqlite3OsRead(OsFile*, void*, int amt); int sqlite3OsWrite(OsFile*, const void*, int amt); int sqlite3OsSeek(OsFile*, i64 offset); int sqlite3OsTruncate(OsFile*, i64 size); int sqlite3OsSync(OsFile*, int); void sqlite3OsSetFullSync(OsFile *id, int setting); int sqlite3OsFileHandle(OsFile *id); int sqlite3OsFileSize(OsFile*, i64 *pSize); int sqlite3OsLock(OsFile*, int); int sqlite3OsUnlock(OsFile*, int); int sqlite3OsLockState(OsFile *id); int sqlite3OsCheckReservedLock(OsFile *id); int sqlite3OsOpenReadWrite(const char*, OsFile**, int*); int sqlite3OsOpenExclusive(const char*, OsFile**, int); int sqlite3OsOpenReadOnly(const char*, OsFile**); int sqlite3OsDelete(const char*); int sqlite3OsFileExists(const char*); char *sqlite3OsFullPathname(const char*); int sqlite3OsIsDirWritable(char*); int sqlite3OsSyncDirectory(const char*); int sqlite3OsTempFileName(char*); int sqlite3OsRandomSeed(char*); int sqlite3OsSleep(int ms); int sqlite3OsCurrentTime(double*); void sqlite3OsEnterMutex(void); void sqlite3OsLeaveMutex(void); int sqlite3OsInMutex(void); void *sqlite3OsThreadSpecificData(int); void *sqlite3OsMalloc(int); void *sqlite3OsRealloc(void *, int); void sqlite3OsFree(void *); int sqlite3OsAllocationSize(void *); #endif /* _SQLITE_OS_H_ */ |
Changes to src/os_common.h.
︙ | ︙ | |||
120 121 122 123 124 125 126 | int sqlite3_open_file_count = 0; #define OpenCounter(X) sqlite3_open_file_count+=(X) #else #define OpenCounter(X) #endif /* | | | | | | | | | | 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | int sqlite3_open_file_count = 0; #define OpenCounter(X) sqlite3_open_file_count+=(X) #else #define OpenCounter(X) #endif /* ** sqlite3GenericMalloc ** sqlite3GenericRealloc ** sqlite3GenericOsFree ** sqlite3GenericAllocationSize ** ** Implementation of the os level dynamic memory allocation interface in terms ** of the standard malloc(), realloc() and free() found in many operating ** systems. No rocket science here. */ void *sqlite3GenericMalloc(int n){ char *p = (char *)malloc(n+8); assert(n>0); assert(sizeof(int)<=8); if( p ){ *(int *)p = n; } return (void *)(p + 8); } void *sqlite3GenericRealloc(void *p, int n){ char *p2 = ((char *)p - 8); assert(n>0); p2 = realloc(p2, n+8); if( p2 ){ *(int *)p2 = n; } return (void *)((char *)p2 + 8); } void sqlite3GenericFree(void *p){ assert(p); free((void *)((char *)p - 8)); } int sqlite3GenericAllocationSize(void *p){ return p ? *(int *)((char *)p - 8) : 0; } |
Changes to src/os_unix.c.
︙ | ︙ | |||
11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ****************************************************************************** ** ** This file contains code that is specific to Unix systems. */ #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 | > | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | ****************************************************************************** ** ** This file contains code that is specific to Unix systems. */ #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 |
︙ | ︙ | |||
84 85 86 87 88 89 90 91 92 93 94 95 96 97 | 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 ** SQLITE_OMIT_DISKIO macro is defined (indicating that there database ** will be in-memory only) */ #ifndef SQLITE_OMIT_DISKIO | > > > > > > > > > > > > > > > > | 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | 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 }; /* ** 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; extern int sqlite3CrashOpenReadWrite(const char*, OsFile**, int*); extern int sqlite3CrashOpenExclusive(const char*, OsFile**, int); extern int sqlite3CrashOpenReadOnly(const char*, OsFile**, int); # define CRASH_TEST_OVERRIDE(X,A,B,C) \ if(sqlite3CrashTestEnable){ return X(A,B,C); } #else # define CRASH_TEST_OVERRIDE(X,A,B,C) /* no-op */ #endif /* ** Do not include any of the File I/O interface procedures if the ** SQLITE_OMIT_DISKIO macro is defined (indicating that there database ** will be in-memory only) */ #ifndef SQLITE_OMIT_DISKIO |
︙ | ︙ | |||
560 561 562 563 564 565 566 | pTsd->disableReleaseMemory = 0; return rc; } /* ** Delete the named file */ | | | | > | | | 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 | pTsd->disableReleaseMemory = 0; return rc; } /* ** Delete the named file */ int sqlite3UnixDelete(const char *zFilename){ unlink(zFilename); return SQLITE_OK; } /* ** Return TRUE if the named file exists. */ int sqlite3UnixFileExists(const char *zFilename){ return access(zFilename, 0)==0; } /* Forward declaration */ static int allocateUnixFile(unixFile *pInit, OsFile **pId); /* ** Attempt to open a file for both reading and writing. If that ** fails, try opening it read-only. If the file does not exist, ** try to create it. ** ** On success, a handle for the open file is written to *id ** and *pReadonly is set to 0 if the file was opened for reading and ** writing or 1 if the file was opened read-only. The function returns ** SQLITE_OK. ** ** On failure, the function returns SQLITE_CANTOPEN and leaves ** *id and *pReadonly unchanged. */ int sqlite3UnixOpenReadWrite( const char *zFilename, OsFile **pId, int *pReadonly ){ int rc; unixFile f; CRASH_TEST_OVERRIDE(sqlite3CrashOpenReadWrite, zFilename, pId, pReadonly); 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( f.h<0 ){ #ifdef EISDIR if( errno==EISDIR ){ return SQLITE_CANTOPEN; } #endif f.h = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY); if( f.h<0 ){ return SQLITE_CANTOPEN; } *pReadonly = 1; }else{ *pReadonly = 0; } sqlite3OsEnterMutex(); rc = findLockInfo(f.h, &f.pLock, &f.pOpen); sqlite3OsLeaveMutex(); if( rc ){ close(f.h); return SQLITE_NOMEM; } f.locktype = 0; TRACE3("OPEN %-3d %s\n", f.h, zFilename); return allocateUnixFile(&f, pId); |
︙ | ︙ | |||
642 643 644 645 646 647 648 | ** If delFlag is true, then make arrangements to automatically delete ** the file when it is closed. ** ** On success, write the file handle into *id and return SQLITE_OK. ** ** On failure, return SQLITE_CANTOPEN. */ | | > | | | > | | | 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 | ** If delFlag is true, then make arrangements to automatically delete ** the file when it is closed. ** ** On success, write the file handle into *id and return SQLITE_OK. ** ** On failure, return SQLITE_CANTOPEN. */ int sqlite3UnixOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){ int rc; unixFile f; CRASH_TEST_OVERRIDE(sqlite3CrashOpenExclusive, zFilename, pId, delFlag); assert( 0==*pId ); if( access(zFilename, 0)==0 ){ return SQLITE_CANTOPEN; } 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( f.h<0 ){ return SQLITE_CANTOPEN; } sqlite3OsEnterMutex(); rc = findLockInfo(f.h, &f.pLock, &f.pOpen); sqlite3OsLeaveMutex(); if( rc ){ close(f.h); unlink(zFilename); return SQLITE_NOMEM; } f.locktype = 0; if( delFlag ){ unlink(zFilename); } TRACE3("OPEN-EX %-3d %s\n", f.h, zFilename); return allocateUnixFile(&f, pId); } /* ** Attempt to open a new file for read-only access. ** ** On success, write the file handle into *id and return SQLITE_OK. ** ** On failure, return SQLITE_CANTOPEN. */ int sqlite3UnixOpenReadOnly(const char *zFilename, OsFile **pId){ int rc; unixFile f; CRASH_TEST_OVERRIDE(sqlite3CrashOpenReadOnly, zFilename, pId, 0); 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(f.h, &f.pLock, &f.pOpen); sqlite3OsLeaveMutex(); if( rc ){ close(f.h); return SQLITE_NOMEM; } f.locktype = 0; TRACE3("OPEN-RO %-3d %s\n", f.h, zFilename); |
︙ | ︙ | |||
752 753 754 755 756 757 758 | */ char *sqlite3_temp_directory = 0; /* ** Create a temporary file name in zBuf. zBuf must be big enough to ** hold at least SQLITE_TEMPNAME_SIZE characters. */ | | | 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 | */ char *sqlite3_temp_directory = 0; /* ** Create a temporary file name in zBuf. zBuf must be big enough to ** hold at least SQLITE_TEMPNAME_SIZE characters. */ int sqlite3UnixTempFileName(char *zBuf){ static const char *azDirs[] = { 0, "/var/tmp", "/usr/tmp", "/tmp", ".", }; |
︙ | ︙ | |||
792 793 794 795 796 797 798 | return SQLITE_OK; } /* ** Check that a given pathname is a directory and is writable ** */ | | | 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 | return SQLITE_OK; } /* ** Check that a given pathname is a directory and is writable ** */ int sqlite3UnixIsDirWritable(char *zBuf){ #ifndef SQLITE_OMIT_PAGER_PRAGMAS struct stat buf; if( zBuf==0 ) return 0; if( zBuf[0]==0 ) return 0; if( stat(zBuf, &buf) ) return 0; if( !S_ISDIR(buf.st_mode) ) return 0; if( access(zBuf, 07) ) return 0; |
︙ | ︙ | |||
978 979 980 981 982 983 984 | ** Sync the directory zDirname. This is a no-op on operating systems other ** than UNIX. ** ** This is used to make sure the master journal file has truely been deleted ** before making changes to individual journals on a multi-database commit. ** The F_FULLFSYNC option is not needed here. */ | | | 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 | ** Sync the directory zDirname. This is a no-op on operating systems other ** than UNIX. ** ** This is used to make sure the master journal file has truely been deleted ** before making changes to individual journals on a multi-database commit. ** The F_FULLFSYNC option is not needed here. */ int sqlite3UnixSyncDirectory(const char *zDirname){ #ifdef SQLITE_DISABLE_DIRSYNC return SQLITE_OK; #else int fd; int r; SimulateIOError(SQLITE_IOERR); fd = open(zDirname, O_RDONLY|O_BINARY, 0); |
︙ | ︙ | |||
1031 1032 1033 1034 1035 1036 1037 | */ static int unixCheckReservedLock(OsFile *id){ int r = 0; unixFile *pFile = (unixFile*)id; assert( pFile ); if( CHECK_THREADID(pFile) ) return SQLITE_MISUSE; | | | | 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 | */ static int unixCheckReservedLock(OsFile *id){ int r = 0; unixFile *pFile = (unixFile*)id; assert( pFile ); if( CHECK_THREADID(pFile) ) return SQLITE_MISUSE; sqlite3OsEnterMutex(); /* Because pFile->pLock is shared across threads */ /* Check if a thread in this process holds such a lock */ if( pFile->pLock->locktype>SHARED_LOCK ){ r = 1; } /* Otherwise see if some other process holds it. */ if( !r ){ struct flock lock; lock.l_whence = SEEK_SET; lock.l_start = RESERVED_BYTE; lock.l_len = 1; lock.l_type = F_WRLCK; fcntl(pFile->h, F_GETLK, &lock); if( lock.l_type!=F_UNLCK ){ r = 1; } } sqlite3OsLeaveMutex(); TRACE3("TEST WR-LOCK %d %d\n", pFile->h, r); return r; } #ifdef SQLITE_DEBUG /* |
︙ | ︙ | |||
1153 1154 1155 1156 1157 1158 1159 | TRACE7("LOCK %d %s was %s(%s,%d) pid=%d\n", pFile->h, locktypeName(locktype), locktypeName(pFile->locktype), locktypeName(pLock->locktype), pLock->cnt , getpid()); if( CHECK_THREADID(pFile) ) return SQLITE_MISUSE; /* If there is already a lock of this type or more restrictive on the ** OsFile, do nothing. Don't use the end_lock: exit path, as | | | | 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 | TRACE7("LOCK %d %s was %s(%s,%d) pid=%d\n", pFile->h, locktypeName(locktype), locktypeName(pFile->locktype), locktypeName(pLock->locktype), pLock->cnt , getpid()); if( CHECK_THREADID(pFile) ) return SQLITE_MISUSE; /* If there is already a lock of this type or more restrictive on the ** OsFile, do nothing. Don't use the end_lock: exit path, as ** sqlite3OsEnterMutex() hasn't been called yet. */ if( pFile->locktype>=locktype ){ TRACE3("LOCK %d %s ok (already held)\n", pFile->h, locktypeName(locktype)); return SQLITE_OK; } /* Make sure the locking sequence is correct */ assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK ); assert( locktype!=PENDING_LOCK ); assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK ); /* This mutex is needed because pFile->pLock is shared across threads */ sqlite3OsEnterMutex(); /* If some thread using this PID has a lock via a different OsFile* ** handle that precludes the requested lock, return BUSY. */ if( (pFile->locktype!=pLock->locktype && (pLock->locktype>=PENDING_LOCK || locktype>SHARED_LOCK)) ){ |
︙ | ︙ | |||
1281 1282 1283 1284 1285 1286 1287 | pLock->locktype = locktype; }else if( locktype==EXCLUSIVE_LOCK ){ pFile->locktype = PENDING_LOCK; pLock->locktype = PENDING_LOCK; } end_lock: | | | 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 | pLock->locktype = locktype; }else if( locktype==EXCLUSIVE_LOCK ){ pFile->locktype = PENDING_LOCK; pLock->locktype = PENDING_LOCK; } end_lock: sqlite3OsLeaveMutex(); TRACE4("LOCK %d %s %s\n", pFile->h, locktypeName(locktype), rc==SQLITE_OK ? "ok" : "failed"); return rc; } /* ** Lower the locking level on file descriptor pFile to locktype. locktype |
︙ | ︙ | |||
1313 1314 1315 1316 1317 1318 1319 | pFile->locktype, pFile->pLock->locktype, pFile->pLock->cnt, getpid()); if( CHECK_THREADID(pFile) ) return SQLITE_MISUSE; assert( locktype<=SHARED_LOCK ); if( pFile->locktype<=locktype ){ return SQLITE_OK; } | | | 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 | pFile->locktype, pFile->pLock->locktype, pFile->pLock->cnt, getpid()); if( CHECK_THREADID(pFile) ) return SQLITE_MISUSE; assert( locktype<=SHARED_LOCK ); if( pFile->locktype<=locktype ){ return SQLITE_OK; } sqlite3OsEnterMutex(); pLock = pFile->pLock; assert( pLock->cnt!=0 ); if( pFile->locktype>SHARED_LOCK ){ assert( pLock->locktype==pFile->locktype ); if( locktype==SHARED_LOCK ){ lock.l_type = F_RDLCK; lock.l_whence = SEEK_SET; |
︙ | ︙ | |||
1374 1375 1376 1377 1378 1379 1380 | close(pOpen->aPending[i]); } sqliteFree(pOpen->aPending); pOpen->nPending = 0; pOpen->aPending = 0; } } | | | | 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 | close(pOpen->aPending[i]); } sqliteFree(pOpen->aPending); pOpen->nPending = 0; pOpen->aPending = 0; } } sqlite3OsLeaveMutex(); pFile->locktype = locktype; return rc; } /* ** Close a file. */ static int unixClose(OsFile **pId){ SqliteTsd *pTsd = sqlite3Tsd(); unixFile *id = (unixFile*)*pId; if( !id ) return SQLITE_OK; if( CHECK_THREADID(id) ) return SQLITE_MISUSE; unixUnlock(*pId, NO_LOCK); if( id->dirfd>=0 ) close(id->dirfd); id->dirfd = -1; sqlite3OsEnterMutex(); /* Disable the sqlite3_release_memory() function */ assert( !pTsd->disableReleaseMemory ); pTsd->disableReleaseMemory = 1; if( id->pOpen->nLock ){ /* If there are outstanding locks, do not actually close the file just |
︙ | ︙ | |||
1422 1423 1424 1425 1426 1427 1428 | } releaseLockInfo(id->pLock); releaseOpenCnt(id->pOpen); /* Disable the sqlite3_release_memory() function */ pTsd->disableReleaseMemory = 0; | | | | 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 | } releaseLockInfo(id->pLock); releaseOpenCnt(id->pOpen); /* Disable the sqlite3_release_memory() function */ pTsd->disableReleaseMemory = 0; sqlite3OsLeaveMutex(); id->isOpen = 0; TRACE2("CLOSE %-3d\n", id->h); OpenCounter(-1); sqliteFree(id); *pId = 0; return SQLITE_OK; } /* ** Turn a relative pathname into a full pathname. Return a pointer ** to the full pathname stored in space obtained from sqliteMalloc(). ** The calling function is responsible for freeing this space once it ** is no longer needed. */ char *sqlite3UnixFullPathname(const char *zRelative){ char *zFull = 0; if( zRelative[0]=='/' ){ sqlite3SetString(&zFull, zRelative, (char*)0); }else{ char *zBuf = sqliteMalloc(5000); if( zBuf==0 ){ return 0; |
︙ | ︙ | |||
1533 1534 1535 1536 1537 1538 1539 | /* ** Get information to seed the random number generator. The seed ** is written into the buffer zBuf[256]. The calling function must ** supply a sufficiently large buffer. */ | | | 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 | /* ** Get information to seed the random number generator. The seed ** is written into the buffer zBuf[256]. The calling function must ** supply a sufficiently large buffer. */ int sqlite3UnixRandomSeed(char *zBuf){ /* We have to initialize zBuf to prevent valgrind from reporting ** errors. The reports issued by valgrind are incorrect - we would ** prefer that the randomness be increased by making use of the ** uninitialized space in zBuf - but valgrind errors tend to worry ** some users. Rather than argue, it seems easier just to initialize ** the whole array and silence valgrind, even if that means less randomness ** in the random seed. |
︙ | ︙ | |||
1567 1568 1569 1570 1571 1572 1573 | #endif return SQLITE_OK; } /* ** Sleep for a little while. Return the amount of time slept. */ | | | 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 | #endif return SQLITE_OK; } /* ** Sleep for a little while. Return the amount of time slept. */ int sqlite3UnixSleep(int ms){ #if defined(HAVE_USLEEP) && HAVE_USLEEP usleep(ms*1000); return ms; #else sleep((ms+999)/1000); return 1000*((ms+999)/1000); #endif |
︙ | ︙ | |||
1593 1594 1595 1596 1597 1598 1599 | ** The following pair of routine implement mutual exclusion for ** multi-threaded processes. Only a single thread is allowed to ** executed code that is surrounded by EnterMutex() and LeaveMutex(). ** ** SQLite uses only a single Mutex. There is not much critical ** code and what little there is executes quickly and without blocking. */ | | | | | | | | | | | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 | ** The following pair of routine implement mutual exclusion for ** multi-threaded processes. Only a single thread is allowed to ** executed code that is surrounded by EnterMutex() and LeaveMutex(). ** ** SQLite uses only a single Mutex. There is not much critical ** code and what little there is executes quickly and without blocking. */ void sqlite3UnixEnterMutex(){ #ifdef SQLITE_UNIX_THREADS pthread_mutex_lock(&mutex); #endif assert( !inMutex ); inMutex = 1; } void sqlite3UnixLeaveMutex(){ assert( inMutex ); inMutex = 0; #ifdef SQLITE_UNIX_THREADS pthread_mutex_unlock(&mutex); #endif } /* ** Return TRUE if we are currently within the mutex and FALSE if not. ** This routine is intended for sanity checking only. It is designed ** for use in an assert() to verify that the mutex is held or not held ** in certain routines. */ int sqlite3UnixInMutex(){ return inMutex; } /* ** This function is called automatically when a thread exists to delete ** the threads SqliteTsd structure. ** ** Because the SqliteTsd structure is required by higher level routines ** such as sqliteMalloc() we use OsFree() and OsMalloc() directly to ** allocate the thread specific data. */ #ifdef SQLITE_UNIX_THREADS static void deleteTsd(void *pTsd){ sqlite3OsFree(pTsd); } #endif /* ** The first time this function is called from a specific thread, nByte ** bytes of data area are allocated and zeroed. A pointer to the new ** allocation is returned to the caller. ** ** Each subsequent call to this function from the thread returns the same ** pointer. The argument is ignored in this case. */ void *sqlite3UnixThreadSpecificData(int nByte){ #ifdef SQLITE_UNIX_THREADS static pthread_key_t key; static int keyInit = 0; void *pTsd; if( !keyInit ){ sqlite3OsEnterMutex(); if( !keyInit ){ int rc; rc = pthread_key_create(&key, deleteTsd); if( rc ){ return 0; } keyInit = 1; } sqlite3OsLeaveMutex(); } pTsd = pthread_getspecific(key); if( !pTsd ){ pTsd = sqlite3OsMalloc(nByte); if( pTsd ){ memset(pTsd, 0, nByte); pthread_setspecific(key, pTsd); } } return pTsd; #else static void *pTsd = 0; if( !pTsd ){ pTsd = sqlite3OsMalloc(nByte); if( pTsd ){ memset(pTsd, 0, nByte); } } return pTsd; #endif } /* ** The following variable, if set to a non-zero value, becomes the result ** returned from sqlite3OsCurrentTime(). This is used for testing. */ #ifdef SQLITE_TEST int sqlite3_current_time = 0; #endif /* ** Find the current time (in Universal Coordinated Time). Write the ** current time and date as a Julian Day number into *prNow and ** return 0. Return 1 if the time and date cannot be found. */ int sqlite3UnixCurrentTime(double *prNow){ #ifdef NO_GETTOD time_t t; time(&t); *prNow = t/86400.0 + 2440587.5; #else struct timeval sNow; struct timezone sTz; /* Not used */ gettimeofday(&sNow, &sTz); *prNow = 2440587.5 + sNow.tv_sec/86400.0 + sNow.tv_usec/86400000000.0; #endif #ifdef SQLITE_TEST if( sqlite3_current_time ){ *prNow = sqlite3_current_time/86400.0 + 2440587.5; } #endif return 0; } #endif /* OS_UNIX */ |
Changes to src/os_win.c.
︙ | ︙ | |||
135 136 137 138 139 140 141 | return zFilename; } /* ** Delete the named file */ | | | | 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | return zFilename; } /* ** Delete the named file */ int sqlite3WinDelete(const char *zFilename){ WCHAR *zWide = utf8ToUnicode(zFilename); if( zWide ){ DeleteFileW(zWide); sqliteFree(zWide); }else{ DeleteFileA(zFilename); } TRACE2("DELETE \"%s\"\n", zFilename); return SQLITE_OK; } /* ** Return TRUE if the named file exists. */ int sqlite3WinFileExists(const char *zFilename){ int exists = 0; WCHAR *zWide = utf8ToUnicode(zFilename); if( zWide ){ exists = GetFileAttributesW(zWide) != 0xffffffff; sqliteFree(zWide); }else{ exists = GetFileAttributesA(zFilename) != 0xffffffff; |
︙ | ︙ | |||
178 179 180 181 182 183 184 | ** and *pReadonly is set to 0 if the file was opened for reading and ** writing or 1 if the file was opened read-only. The function returns ** SQLITE_OK. ** ** On failure, the function returns SQLITE_CANTOPEN and leaves ** *id and *pReadonly unchanged. */ | | | 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 | ** and *pReadonly is set to 0 if the file was opened for reading and ** writing or 1 if the file was opened read-only. The function returns ** SQLITE_OK. ** ** On failure, the function returns SQLITE_CANTOPEN and leaves ** *id and *pReadonly unchanged. */ int sqlite3WinOpenReadWrite( const char *zFilename, OsFile **pId, int *pReadonly ){ winFile f; HANDLE h; WCHAR *zWide = utf8ToUnicode(zFilename); |
︙ | ︙ | |||
262 263 264 265 266 267 268 | ** If delFlag is true, then make arrangements to automatically delete ** the file when it is closed. ** ** On success, write the file handle into *id and return SQLITE_OK. ** ** On failure, return SQLITE_CANTOPEN. */ | | | 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 | ** If delFlag is true, then make arrangements to automatically delete ** the file when it is closed. ** ** On success, write the file handle into *id and return SQLITE_OK. ** ** On failure, return SQLITE_CANTOPEN. */ int sqlite3WinOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){ winFile f; HANDLE h; int fileflags; WCHAR *zWide = utf8ToUnicode(zFilename); assert( *pId == 0 ); if( delFlag ){ fileflags = FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_RANDOM_ACCESS |
︙ | ︙ | |||
311 312 313 314 315 316 317 | /* ** Attempt to open a new file for read-only access. ** ** On success, write the file handle into *id and return SQLITE_OK. ** ** On failure, return SQLITE_CANTOPEN. */ | | | 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 | /* ** Attempt to open a new file for read-only access. ** ** On success, write the file handle into *id and return SQLITE_OK. ** ** On failure, return SQLITE_CANTOPEN. */ int sqlite3WinOpenReadOnly(const char *zFilename, OsFile **pId){ winFile f; HANDLE h; WCHAR *zWide = utf8ToUnicode(zFilename); assert( *pId==0 ); if( zWide ){ h = CreateFileW(zWide, GENERIC_READ, |
︙ | ︙ | |||
380 381 382 383 384 385 386 | */ char *sqlite3_temp_directory = 0; /* ** Create a temporary file name in zBuf. zBuf must be big enough to ** hold at least SQLITE_TEMPNAME_SIZE characters. */ | | | 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 | */ char *sqlite3_temp_directory = 0; /* ** Create a temporary file name in zBuf. zBuf must be big enough to ** hold at least SQLITE_TEMPNAME_SIZE characters. */ int sqlite3WinTempFileName(char *zBuf){ static char zChars[] = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789"; int i, j; char zTempPath[SQLITE_TEMPNAME_SIZE]; if( sqlite3_temp_directory ){ |
︙ | ︙ | |||
413 414 415 416 417 418 419 | sprintf(zBuf, "%s\\"TEMP_FILE_PREFIX, zTempPath); j = strlen(zBuf); sqlite3Randomness(15, &zBuf[j]); for(i=0; i<15; i++, j++){ zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; } zBuf[j] = 0; | | | 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 | sprintf(zBuf, "%s\\"TEMP_FILE_PREFIX, zTempPath); j = strlen(zBuf); sqlite3Randomness(15, &zBuf[j]); for(i=0; i<15; i++, j++){ zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; } zBuf[j] = 0; if( !sqlite3OsFileExists(zBuf) ) break; } TRACE2("TEMP FILENAME: %s\n", zBuf); return SQLITE_OK; } /* ** Close a file. |
︙ | ︙ | |||
521 522 523 524 525 526 527 | } } /* ** Sync the directory zDirname. This is a no-op on operating systems other ** than UNIX. */ | | | 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 | } } /* ** Sync the directory zDirname. This is a no-op on operating systems other ** than UNIX. */ int sqlite3WinSyncDirectory(const char *zDirname){ SimulateIOError(SQLITE_IOERR); return SQLITE_OK; } /* ** Truncate an open file to a specified size */ |
︙ | ︙ | |||
591 592 593 594 595 596 597 | } #ifndef SQLITE_OMIT_PAGER_PRAGMAS /* ** Check that a given pathname is a directory and is writable ** */ | | | 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 | } #ifndef SQLITE_OMIT_PAGER_PRAGMAS /* ** Check that a given pathname is a directory and is writable ** */ int sqlite3WinIsDirWritable(char *zDirname){ int fileAttr; WCHAR *zWide; if( zDirname==0 ) return 0; if( !isNT() && strlen(zDirname)>MAX_PATH ) return 0; zWide = utf8ToUnicode(zDirname); if( zWide ){ fileAttr = GetFileAttributesW(zWide); |
︙ | ︙ | |||
813 814 815 816 817 818 819 | /* ** Turn a relative pathname into a full pathname. Return a pointer ** to the full pathname stored in space obtained from sqliteMalloc(). ** The calling function is responsible for freeing this space once it ** is no longer needed. */ | | | 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 | /* ** Turn a relative pathname into a full pathname. Return a pointer ** to the full pathname stored in space obtained from sqliteMalloc(). ** The calling function is responsible for freeing this space once it ** is no longer needed. */ char *sqlite3WinFullPathname(const char *zRelative){ char *zNotUsed; char *zFull; WCHAR *zWide; int nByte; #ifdef __CYGWIN__ nByte = strlen(zRelative) + MAX_PATH + 1001; zFull = sqliteMalloc( nByte ); |
︙ | ︙ | |||
902 903 904 905 906 907 908 | if( pNew==0 ){ CloseHandle(pInit->h); *pId = 0; return SQLITE_NOMEM; }else{ *pNew = *pInit; pNew->pMethod = &sqlite3WinIoMethod; | | | | | | | | | 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 | if( pNew==0 ){ CloseHandle(pInit->h); *pId = 0; return SQLITE_NOMEM; }else{ *pNew = *pInit; pNew->pMethod = &sqlite3WinIoMethod; *pId = (OsFile*)pNew; return SQLITE_OK; } } #endif /* SQLITE_OMIT_DISKIO */ /*************************************************************************** ** Everything above deals with file I/O. Everything that follows deals ** with other miscellanous aspects of the operating system interface ****************************************************************************/ /* ** Get information to seed the random number generator. The seed ** is written into the buffer zBuf[256]. The calling function must ** supply a sufficiently large buffer. */ int sqlite3WinRandomSeed(char *zBuf){ /* We have to initialize zBuf to prevent valgrind from reporting ** errors. The reports issued by valgrind are incorrect - we would ** prefer that the randomness be increased by making use of the ** uninitialized space in zBuf - but valgrind errors tend to worry ** some users. Rather than argue, it seems easier just to initialize ** the whole array and silence valgrind, even if that means less randomness ** in the random seed. ** ** When testing, initializing zBuf[] to zero is all we do. That means ** that we always use the same random number sequence.* This makes the ** tests repeatable. */ memset(zBuf, 0, 256); GetSystemTime((LPSYSTEMTIME)zBuf); return SQLITE_OK; } /* ** Sleep for a little while. Return the amount of time slept. */ int sqlite3WinSleep(int ms){ Sleep(ms); return ms; } /* ** Static variables used for thread synchronization */ static int inMutex = 0; #ifdef SQLITE_W32_THREADS static CRITICAL_SECTION cs; #endif /* ** The following pair of routine implement mutual exclusion for ** multi-threaded processes. Only a single thread is allowed to ** executed code that is surrounded by EnterMutex() and LeaveMutex(). ** ** SQLite uses only a single Mutex. There is not much critical ** code and what little there is executes quickly and without blocking. */ void sqlite3WinEnterMutex(){ #ifdef SQLITE_W32_THREADS static int isInit = 0; while( !isInit ){ static long lock = 0; if( InterlockedIncrement(&lock)==1 ){ InitializeCriticalSection(&cs); isInit = 1; }else{ Sleep(1); } } EnterCriticalSection(&cs); #endif assert( !inMutex ); inMutex = 1; } void sqlite3WinLeaveMutex(){ assert( inMutex ); inMutex = 0; #ifdef SQLITE_W32_THREADS LeaveCriticalSection(&cs); #endif } /* ** Return TRUE if we are currently within the mutex and FALSE if not. ** This routine is intended for sanity checking only. It is designed ** for use in an assert() to verify that the mutex is held or not held ** in certain routines. */ int sqlite3WinInMutex(){ return inMutex; } /* ** The following variable, if set to a non-zero value, becomes the result ** returned from sqlite3OsCurrentTime(). This is used for testing. */ #ifdef SQLITE_TEST int sqlite3_current_time = 0; #endif /* ** Find the current time (in Universal Coordinated Time). Write the ** current time and date as a Julian Day number into *prNow and ** return 0. Return 1 if the time and date cannot be found. */ int sqlite3WinCurrentTime(double *prNow){ FILETIME ft; /* FILETIME structure is a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5). */ double now; GetSystemTimeAsFileTime( &ft ); now = ((double)ft.dwHighDateTime) * 4294967296.0; |
︙ | ︙ | |||
1035 1036 1037 1038 1039 1040 1041 | ** The first time this function is called from a specific thread, nByte ** bytes of data area are allocated and zeroed. A pointer to the new ** allocation is returned to the caller. ** ** Each subsequent call to this function from the thread returns the same ** pointer. The argument is ignored in this case. */ | | | | | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 | ** The first time this function is called from a specific thread, nByte ** bytes of data area are allocated and zeroed. A pointer to the new ** allocation is returned to the caller. ** ** Each subsequent call to this function from the thread returns the same ** pointer. The argument is ignored in this case. */ void *sqlite3WinThreadSpecificData(int nByte){ static void *pTsd = 0; static int key; static int keyInit = 0; if( !keyInit ){ sqlite3OsEnterMutex(); if( !keyInit ){ key = TlsAlloc(); if( key==0xffffffff ){ sqlite3OsLeaveMutex(); return 0; } keyInit = 1; } sqlite3OsLeaveMutex(); } pTsd = TlsGetValue(key); if( !pTsd ){ pTsd = sqlite3OsMalloc(nByte); if( pTsd ){ memset(pTsd, 0, nByte); TlsSetValue(key, pTsd); } } return pTsd; } #endif /* OS_WIN */ |
Changes to src/pager.c.
︙ | ︙ | |||
14 15 16 17 18 19 20 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** ** @(#) $Id: pager.c,v 1.231 2006/01/06 14:32:20 drh Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" #include "os.h" #include "pager.h" #include <assert.h> #include <string.h> |
︙ | ︙ | |||
930 931 932 933 934 935 936 | if( pPager->stmtOpen ){ sqlite3OsClose(&pPager->stfd); pPager->stmtOpen = 0; } if( pPager->journalOpen ){ sqlite3OsClose(&pPager->jfd); pPager->journalOpen = 0; | | | 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 | if( pPager->stmtOpen ){ sqlite3OsClose(&pPager->stfd); pPager->stmtOpen = 0; } if( pPager->journalOpen ){ sqlite3OsClose(&pPager->jfd); pPager->journalOpen = 0; sqlite3OsDelete(pPager->zJournal); sqliteFree( pPager->aInJournal ); pPager->aInJournal = 0; for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){ pPg->inJournal = 0; pPg->dirty = 0; pPg->needSync = 0; #ifdef SQLITE_CHECK_PAGES |
︙ | ︙ | |||
1106 1107 1108 1109 1110 1111 1112 | 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. */ | | | 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 | 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. */ rc = sqlite3OsOpenReadOnly(zMaster, &master); if( rc!=SQLITE_OK ) goto delmaster_out; master_open = 1; rc = sqlite3OsFileSize(master, &nMasterJournal); if( rc!=SQLITE_OK ) goto delmaster_out; if( nMasterJournal>0 ){ char *zJournal; |
︙ | ︙ | |||
1129 1130 1131 1132 1133 1134 1135 | goto delmaster_out; } rc = sqlite3OsRead(master, zMasterJournal, nMasterJournal); if( rc!=SQLITE_OK ) goto delmaster_out; zJournal = zMasterJournal; while( (zJournal-zMasterJournal)<nMasterJournal ){ | | | | 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 | goto delmaster_out; } rc = sqlite3OsRead(master, zMasterJournal, nMasterJournal); if( rc!=SQLITE_OK ) goto delmaster_out; zJournal = zMasterJournal; while( (zJournal-zMasterJournal)<nMasterJournal ){ if( sqlite3OsFileExists(zJournal) ){ /* One of the journals pointed to by the master journal exists. ** Open it and check if it points at the master journal. If ** so, return without deleting the master journal file. */ OsFile *journal = 0; int c; rc = sqlite3OsOpenReadOnly(zJournal, &journal); if( rc!=SQLITE_OK ){ goto delmaster_out; } rc = readMasterJournal(journal, &zMasterPtr); sqlite3OsClose(&journal); if( rc!=SQLITE_OK ){ |
︙ | ︙ | |||
1159 1160 1161 1162 1163 1164 1165 | goto delmaster_out; } } zJournal += (strlen(zJournal)+1); } } | | | 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 | goto delmaster_out; } } zJournal += (strlen(zJournal)+1); } } sqlite3OsDelete(zMaster); delmaster_out: if( zMasterJournal ){ sqliteFree(zMasterJournal); } if( master_open ){ sqlite3OsClose(&master); |
︙ | ︙ | |||
1300 1301 1302 1303 1304 1305 1306 | /* Read the master journal name from the journal, if it is present. ** If a master journal file name is specified, but the file is not ** present on disk, then the journal is not hot and does not need to be ** played back. */ rc = readMasterJournal(pPager->jfd, &zMaster); assert( rc!=SQLITE_DONE ); | | | 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 | /* Read the master journal name from the journal, if it is present. ** If a master journal file name is specified, but the file is not ** present on disk, then the journal is not hot and does not need to be ** played back. */ rc = readMasterJournal(pPager->jfd, &zMaster); assert( rc!=SQLITE_DONE ); if( rc!=SQLITE_OK || (zMaster && !sqlite3OsFileExists(zMaster)) ){ sqliteFree(zMaster); zMaster = 0; if( rc==SQLITE_DONE ) rc = SQLITE_OK; goto end_playback; } sqlite3OsSeek(pPager->jfd, 0); pPager->journalOff = 0; |
︙ | ︙ | |||
1581 1582 1583 1584 1585 1586 1587 | */ static int sqlite3pager_opentemp(char *zFile, OsFile **pFd){ int cnt = 8; int rc; sqlite3_opentemp_count++; /* Used for testing and analysis only */ do{ cnt--; | | | | 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 | */ static int sqlite3pager_opentemp(char *zFile, OsFile **pFd){ int cnt = 8; int rc; sqlite3_opentemp_count++; /* Used for testing and analysis only */ do{ cnt--; sqlite3OsTempFileName(zFile); rc = sqlite3OsOpenExclusive(zFile, pFd, 1); }while( cnt>0 && rc!=SQLITE_OK && rc!=SQLITE_NOMEM ); return rc; } /* ** Create a new page cache and put a pointer to the page cache in *ppPager. ** The file to be cached need not exist. The file is not locked until |
︙ | ︙ | |||
1642 1643 1644 1645 1646 1647 1648 | #ifndef SQLITE_OMIT_MEMORYDB if( strcmp(zFilename,":memory:")==0 ){ memDb = 1; zFullPathname = sqliteStrDup(""); }else #endif { | | | | | 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 | #ifndef SQLITE_OMIT_MEMORYDB if( strcmp(zFilename,":memory:")==0 ){ memDb = 1; zFullPathname = sqliteStrDup(""); }else #endif { zFullPathname = sqlite3OsFullPathname(zFilename); if( zFullPathname ){ rc = sqlite3OsOpenReadWrite(zFullPathname, &fd, &readOnly); } } }else{ rc = sqlite3pager_opentemp(zTemp, &fd); zFilename = zTemp; zFullPathname = sqlite3OsFullPathname(zFilename); if( rc==SQLITE_OK ){ tempFile = 1; } } /* Allocate the Pager structure. As part of the same allocation, allocate ** space for the full paths of the file, directory and journal |
︙ | ︙ | |||
2078 2079 2080 2081 2082 2083 2084 | sqliteFree(pPager->aInJournal); if( pPager->stmtOpen ){ sqlite3OsClose(&pPager->stfd); } sqlite3OsClose(&pPager->fd); /* Temp files are automatically deleted by the OS ** if( pPager->tempFile ){ | | | 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 | sqliteFree(pPager->aInJournal); if( pPager->stmtOpen ){ sqlite3OsClose(&pPager->stfd); } sqlite3OsClose(&pPager->fd); /* Temp files are automatically deleted by the OS ** if( pPager->tempFile ){ ** sqlite3OsDelete(pPager->zFilename); ** } */ #ifndef SQLITE_OMIT_MEMORY_MANAGEMENT /* Remove the pager from the linked list of pagers starting at ** SqliteTsd.pPager. */ |
︙ | ︙ | |||
2348 2349 2350 2351 2352 2353 2354 | ** ** If the current size of the database file is 0 but a journal file ** exists, that is probably an old journal left over from a prior ** database with the same name. Just delete the journal. */ static int hasHotJournal(Pager *pPager){ if( !pPager->useJournal ) return 0; | | | | 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 | ** ** If the current size of the database file is 0 but a journal file ** exists, that is probably an old journal left over from a prior ** database with the same name. Just delete the journal. */ static int hasHotJournal(Pager *pPager){ if( !pPager->useJournal ) return 0; if( !sqlite3OsFileExists(pPager->zJournal) ) return 0; if( sqlite3OsCheckReservedLock(pPager->fd) ) return 0; if( sqlite3pager_pagecount(pPager)==0 ){ sqlite3OsDelete(pPager->zJournal); return 0; }else{ return 1; } } /* |
︙ | ︙ | |||
2458 2459 2460 2461 2462 2463 2464 | SqliteTsd *pTsd = sqlite3Tsd(); Pager *p; int nReleased = 0; int i; /* If the disableReleaseMemory memory flag is set, this operation is ** a no-op; zero bytes of memory are freed. The flag is set before | | | 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 | SqliteTsd *pTsd = sqlite3Tsd(); Pager *p; int nReleased = 0; int i; /* If the disableReleaseMemory memory flag is set, this operation is ** a no-op; zero bytes of memory are freed. The flag is set before ** malloc() is called while the global mutex (see sqlite3OsEnterMutex) ** is held. Because some of the code invoked by this function may also ** try to obtain the mutex, proceding may cause a deadlock. */ if( pTsd->disableReleaseMemory ){ return 0; } |
︙ | ︙ | |||
2609 2610 2611 2612 2613 2614 2615 | ** we are unable to open the journal file. ** ** The journal file does not need to be locked itself. The ** journal file is never open unless the main database file holds ** a write lock, so there is never any chance of two or more ** processes opening the journal at the same time. */ | | | 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 | ** we are unable to open the journal file. ** ** The journal file does not need to be locked itself. The ** journal file is never open unless the main database file holds ** a write lock, so there is never any chance of two or more ** processes opening the journal at the same time. */ rc = sqlite3OsOpenReadOnly(pPager->zJournal, &pPager->jfd); if( rc!=SQLITE_OK ){ sqlite3OsUnlock(pPager->fd, NO_LOCK); pPager->state = PAGER_UNLOCK; return SQLITE_BUSY; } pPager->journalOpen = 1; pPager->journalStarted = 0; |
︙ | ︙ | |||
2839 2840 2841 2842 2843 2844 2845 | assert( pPager->aInJournal==0 ); sqlite3pager_pagecount(pPager); pPager->aInJournal = sqliteMalloc( pPager->dbSize/8 + 1 ); if( pPager->aInJournal==0 ){ rc = SQLITE_NOMEM; goto failed_to_open_journal; } | | | 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 | assert( pPager->aInJournal==0 ); sqlite3pager_pagecount(pPager); pPager->aInJournal = sqliteMalloc( pPager->dbSize/8 + 1 ); if( pPager->aInJournal==0 ){ rc = SQLITE_NOMEM; goto failed_to_open_journal; } rc = sqlite3OsOpenExclusive(pPager->zJournal, &pPager->jfd, pPager->tempFile); pPager->journalOff = 0; pPager->setMaster = 0; pPager->journalHdr = 0; if( rc!=SQLITE_OK ){ goto failed_to_open_journal; } |
︙ | ︙ | |||
2883 2884 2885 2886 2887 2888 2889 | pPager->aInJournal = 0; if( rc==SQLITE_NOMEM ){ /* If this was a malloc() failure, then we will not be closing the pager ** file. So delete any journal file we may have just created. Otherwise, ** the system will get confused, we have a read-lock on the file and a ** mysterious journal has appeared in the filesystem. */ | | | 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 | pPager->aInJournal = 0; if( rc==SQLITE_NOMEM ){ /* If this was a malloc() failure, then we will not be closing the pager ** file. So delete any journal file we may have just created. Otherwise, ** the system will get confused, we have a read-lock on the file and a ** mysterious journal has appeared in the filesystem. */ sqlite3OsDelete(pPager->zJournal); }else{ sqlite3OsUnlock(pPager->fd, NO_LOCK); pPager->state = PAGER_UNLOCK; } return rc; } |
︙ | ︙ |
Changes to src/pragma.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2003 April 6 ** ** 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 used to implement the PRAGMA command. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2003 April 6 ** ** 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 used to implement the PRAGMA command. ** ** $Id: pragma.c,v 1.109 2006/01/06 14:32:20 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> /* Ignore this whole file if pragmas are disabled */ |
︙ | ︙ | |||
392 393 394 395 396 397 398 | if( sqlite3_temp_directory ){ sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, "temp_store_directory", P3_STATIC); sqlite3VdbeOp3(v, OP_String8, 0, 0, sqlite3_temp_directory, 0); sqlite3VdbeAddOp(v, OP_Callback, 1, 0); } }else{ | | | 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 | if( sqlite3_temp_directory ){ sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, "temp_store_directory", P3_STATIC); sqlite3VdbeOp3(v, OP_String8, 0, 0, sqlite3_temp_directory, 0); sqlite3VdbeAddOp(v, OP_Callback, 1, 0); } }else{ if( zRight[0] && !sqlite3OsIsDirWritable(zRight) ){ sqlite3ErrorMsg(pParse, "not a writable directory"); goto pragma_out; } if( TEMP_STORE==0 || (TEMP_STORE==1 && db->temp_store<=1) || (TEMP_STORE==2 && db->temp_store==1) ){ |
︙ | ︙ |
Changes to src/random.c.
︙ | ︙ | |||
11 12 13 14 15 16 17 | ************************************************************************* ** This file contains code to implement a pseudo-random number ** generator (PRNG) for SQLite. ** ** Random numbers are used by some of the database backends in order ** to generate random integer keys for tables or random filenames. ** | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | ************************************************************************* ** This file contains code to implement a pseudo-random number ** generator (PRNG) for SQLite. ** ** Random numbers are used by some of the database backends in order ** to generate random integer keys for tables or random filenames. ** ** $Id: random.c,v 1.15 2006/01/06 14:32:20 drh Exp $ */ #include "sqliteInt.h" #include "os.h" /* ** Get a single 8-bit random value from the RC4 PRNG. The Mutex |
︙ | ︙ | |||
59 60 61 62 63 64 65 | ** number generator) not as an encryption device. */ if( !prng.isInit ){ int i; char k[256]; prng.j = 0; prng.i = 0; | | | 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | ** number generator) not as an encryption device. */ if( !prng.isInit ){ int i; char k[256]; prng.j = 0; prng.i = 0; sqlite3OsRandomSeed(k); for(i=0; i<256; i++){ prng.s[i] = i; } for(i=0; i<256; i++){ prng.j += prng.s[i] + k[i]; t = prng.s[prng.j]; prng.s[prng.j] = prng.s[i]; |
︙ | ︙ | |||
88 89 90 91 92 93 94 | } /* ** Return N random bytes. */ void sqlite3Randomness(int N, void *pBuf){ unsigned char *zBuf = pBuf; | | | | 88 89 90 91 92 93 94 95 96 97 98 99 100 | } /* ** Return N random bytes. */ void sqlite3Randomness(int N, void *pBuf){ unsigned char *zBuf = pBuf; sqlite3OsEnterMutex(); while( N-- ){ *(zBuf++) = randomByte(); } sqlite3OsLeaveMutex(); } |
Changes to src/tclsqlite.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** 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. ** ************************************************************************* ** A TCL Interface to SQLite ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** 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. ** ************************************************************************* ** A TCL Interface to SQLite ** ** $Id: tclsqlite.c,v 1.147 2006/01/06 14:32:20 drh Exp $ */ #ifndef NO_TCL /* Omit this whole file if TCL is unavailable */ #include "sqliteInt.h" #include "hash.h" #include "tcl.h" #include <stdlib.h> |
︙ | ︙ | |||
2147 2148 2149 2150 2151 2152 2153 | { extern int Sqlitetest1_Init(Tcl_Interp*); extern int Sqlitetest2_Init(Tcl_Interp*); extern int Sqlitetest3_Init(Tcl_Interp*); extern int Sqlitetest4_Init(Tcl_Interp*); extern int Sqlitetest5_Init(Tcl_Interp*); extern int Sqlitetest6_Init(Tcl_Interp*); | < < | 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 | { extern int Sqlitetest1_Init(Tcl_Interp*); extern int Sqlitetest2_Init(Tcl_Interp*); extern int Sqlitetest3_Init(Tcl_Interp*); extern int Sqlitetest4_Init(Tcl_Interp*); extern int Sqlitetest5_Init(Tcl_Interp*); extern int Sqlitetest6_Init(Tcl_Interp*); extern int Md5_Init(Tcl_Interp*); extern int Sqlitetestsse_Init(Tcl_Interp*); Sqlitetest1_Init(interp); Sqlitetest2_Init(interp); Sqlitetest3_Init(interp); Sqlitetest4_Init(interp); Sqlitetest5_Init(interp); Sqlitetest6_Init(interp); Md5_Init(interp); #ifdef SQLITE_SSE Sqlitetestsse_Init(interp); #endif } #endif if( argc>=2 || TCLSH==2 ){ |
︙ | ︙ |
Changes to src/test1.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the printf() interface to SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the printf() interface to SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** ** $Id: test1.c,v 1.181 2006/01/06 14:32:20 drh Exp $ */ #include "sqliteInt.h" #include "tcl.h" #include "os.h" #include <stdlib.h> #include <string.h> |
︙ | ︙ | |||
2595 2596 2597 2598 2599 2600 2601 | if( objc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " filename", 0); return TCL_ERROR; } | | | 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 | if( objc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " filename", 0); return TCL_ERROR; } rc = sqlite3OsOpenReadWrite(Tcl_GetString(objv[1]), &pFile, &dummy); if( rc!=SQLITE_OK ){ Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); return TCL_ERROR; } makePointerStr(interp, zBuf, pFile); Tcl_SetResult(interp, zBuf, 0); return TCL_ERROR; |
︙ | ︙ | |||
2723 2724 2725 2726 2727 2728 2729 | Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ char zFile[SQLITE_TEMPNAME_SIZE]; int rc; | | | 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 | Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ char zFile[SQLITE_TEMPNAME_SIZE]; int rc; rc = sqlite3OsTempFileName(zFile); if( rc!=SQLITE_OK ){ Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); return TCL_ERROR; } Tcl_AppendResult(interp, zFile, 0); return TCL_OK; } |
︙ | ︙ | |||
3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 | #endif #ifdef SQLITE_OMIT_CONFLICT_CLAUSE Tcl_SetVar2(interp, "sqlite_options", "conflict", "0", TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp, "sqlite_options", "conflict", "1", TCL_GLOBAL_ONLY); #endif #ifdef SQLITE_OMIT_DATETIME_FUNCS Tcl_SetVar2(interp, "sqlite_options", "datetime", "0", TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp, "sqlite_options", "datetime", "1", TCL_GLOBAL_ONLY); #endif | > > > > > > | 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 | #endif #ifdef SQLITE_OMIT_CONFLICT_CLAUSE Tcl_SetVar2(interp, "sqlite_options", "conflict", "0", TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp, "sqlite_options", "conflict", "1", TCL_GLOBAL_ONLY); #endif #if OS_UNIX Tcl_SetVar2(interp, "sqlite_options", "crashtest", "1", TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp, "sqlite_options", "crashtest", "0", TCL_GLOBAL_ONLY); #endif #ifdef SQLITE_OMIT_DATETIME_FUNCS Tcl_SetVar2(interp, "sqlite_options", "datetime", "0", TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp, "sqlite_options", "datetime", "1", TCL_GLOBAL_ONLY); #endif |
︙ | ︙ |
Changes to src/test2.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the pager.c module in SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the pager.c module in SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** ** $Id: test2.c,v 1.39 2006/01/06 14:32:20 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include "pager.h" #include "tcl.h" #include <stdlib.h> #include <string.h> |
︙ | ︙ | |||
528 529 530 531 532 533 534 | int readOnly = 0; if( argc!=3 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " N-MEGABYTES FILE\"", 0); return TCL_ERROR; } if( Tcl_GetInt(interp, argv[1], &n) ) return TCL_ERROR; | | | 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 | int readOnly = 0; if( argc!=3 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " N-MEGABYTES FILE\"", 0); return TCL_ERROR; } if( Tcl_GetInt(interp, argv[1], &n) ) return TCL_ERROR; rc = sqlite3OsOpenReadWrite(argv[2], &fd, &readOnly); if( rc ){ Tcl_AppendResult(interp, "open failed: ", errorName(rc), 0); return TCL_ERROR; } offset = n; offset *= 1024*1024; rc = sqlite3OsSeek(fd, offset); |
︙ | ︙ |
Changes to src/test6.c.
︙ | ︙ | |||
15 16 17 18 19 20 21 | ** is used to test the ability of SQLite to recover from those situations. */ #if SQLITE_TEST /* This file is used for the testing only */ #include "sqliteInt.h" #include "os.h" #include "tcl.h" | < < < < < | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | ** is used to test the ability of SQLite to recover from those situations. */ #if SQLITE_TEST /* This file is used for the testing only */ #include "sqliteInt.h" #include "os.h" #include "tcl.h" /* ** crashFile is a subclass of OsFile that is taylored for the ** crash test module. */ typedef struct crashFile crashFile; struct crashFile { IoMethod const *pMethod; /* Must be first */ |
︙ | ︙ | |||
61 62 63 64 65 66 67 | static int iCrashDelay = 0; static char zCrashFile[500]; /* ** Set the value of the two crash parameters. */ static void setCrashParams(int iDelay, char const *zFile){ | | | | | | 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | static int iCrashDelay = 0; static char zCrashFile[500]; /* ** Set the value of the two crash parameters. */ static void setCrashParams(int iDelay, char const *zFile){ sqlite3OsEnterMutex(); assert( strlen(zFile)<sizeof(zCrashFile) ); strcpy(zCrashFile, zFile); iCrashDelay = iDelay; sqlite3OsLeaveMutex(); } /* ** File zPath is being sync()ed. Return non-zero if this should ** cause a crash. */ static int crashRequired(char const *zPath){ int r; int n; sqlite3OsEnterMutex(); n = strlen(zCrashFile); if( zCrashFile[n-1]=='*' ){ n--; }else if( strlen(zPath)>n ){ n = strlen(zPath); } r = 0; if( iCrashDelay>0 && strncmp(zPath, zCrashFile, n)==0 ){ iCrashDelay--; if( iCrashDelay<=0 ){ r = 1; } } sqlite3OsLeaveMutex(); return r; } /* ** A list of all open files. */ static crashFile *pAllFiles = 0; |
︙ | ︙ | |||
383 384 385 386 387 388 389 390 391 392 393 394 | int rc = sqlite3OsFileSize(pFile->pBase, pSize); if( rc==SQLITE_OK && pSize && *pSize<pFile->nMaxWrite ){ *pSize = pFile->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. */ | > > > > > | > > > | > | > > > | > | > > > | > | 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 | int rc = sqlite3OsFileSize(pFile->pBase, pSize); if( rc==SQLITE_OK && pSize && *pSize<pFile->nMaxWrite ){ *pSize = pFile->nMaxWrite; } return rc; } /* ** Set this global variable to 1 to enable crash testing. */ int sqlite3CrashTestEnable = 0; /* ** 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 sqlite3CrashOpenReadWrite(const char *zFilename, OsFile **pId,int *pRdonly){ OsFile *pBase = 0; int rc; sqlite3CrashTestEnable = 0; rc = sqlite3OsOpenReadWrite(zFilename, &pBase, pRdonly); sqlite3CrashTestEnable = 1; if( !rc ){ initFile(pId, zFilename, pBase); } return rc; } int sqlite3CrashOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){ OsFile *pBase = 0; int rc; sqlite3CrashTestEnable = 0; rc = sqlite3OsOpenExclusive(zFilename, &pBase, delFlag); sqlite3CrashTestEnable = 1; if( !rc ){ initFile(pId, zFilename, pBase); } return rc; } int sqlite3CrashOpenReadOnly(const char *zFilename, OsFile **pId, int NotUsed){ OsFile *pBase = 0; int rc; sqlite3CrashTestEnable = 0; rc = sqlite3OsOpenReadOnly(zFilename, &pBase); sqlite3CrashTestEnable = 1; if( !rc ){ initFile(pId, zFilename, pBase); } return rc; } /* |
︙ | ︙ | |||
514 515 516 517 518 519 520 | if( Tcl_GetIntFromObj(interp, objv[1], &delay) ) return TCL_ERROR; zFile = Tcl_GetStringFromObj(objv[2], &nFile); if( nFile>=sizeof(zCrashFile)-1 ){ Tcl_AppendResult(interp, "crash file name too big", 0); return TCL_ERROR; } setCrashParams(delay, zFile); | < | < < < < | 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 | if( Tcl_GetIntFromObj(interp, objv[1], &delay) ) return TCL_ERROR; zFile = Tcl_GetStringFromObj(objv[2], &nFile); if( nFile>=sizeof(zCrashFile)-1 ){ Tcl_AppendResult(interp, "crash file name too big", 0); return TCL_ERROR; } setCrashParams(delay, zFile); sqlite3CrashTestEnable = 1; return TCL_OK; } /* ** This procedure registers the TCL procedures defined in this file. */ int Sqlitetest6_Init(Tcl_Interp *interp){ Tcl_CreateObjCommand(interp, "sqlite3_crashparams", crashParamsObjCmd, 0, 0); return TCL_OK; } #endif /* SQLITE_TEST */ |
Deleted src/test_async.c.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Changes to src/util.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** Utility functions used throughout sqlite. ** ** This file contains functions for allocating memory, comparing ** strings, and stuff like that. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** Utility functions used throughout sqlite. ** ** This file contains functions for allocating memory, comparing ** strings, and stuff like that. ** ** $Id: util.c,v 1.161 2006/01/06 14:32:20 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include <stdarg.h> #include <ctype.h> /* |
︙ | ︙ | |||
37 38 39 40 41 42 43 | ** The function sqlite3FreeX performs the same task as sqlite3Free and is ** guaranteed to be a real function. The same holds for sqlite3MallocX ** ** The above APIs are implemented in terms of the functions provided at the Os ** level (not in this file). The Os level interface is never accessed directly ** by code outside of this file. ** | | | | | | | | 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | ** The function sqlite3FreeX performs the same task as sqlite3Free and is ** guaranteed to be a real function. The same holds for sqlite3MallocX ** ** The above APIs are implemented in terms of the functions provided at the Os ** level (not in this file). The Os level interface is never accessed directly ** by code outside of this file. ** ** sqlite3OsMalloc() ** sqlite3OsRealloc() ** sqlite3OsFree() ** sqlite3OsAllocationSize() ** ** Functions sqlite3MallocRaw() and sqlite3Realloc() may invoke ** sqlite3_release_memory() if a call to sqlite3OsMalloc() or ** sqlite3OsRealloc() fails (or if the soft-heap-limit for the thread is ** exceeded). Function sqlite3Malloc() usually invokes ** sqlite3MallocRaw(). ** ** MALLOC TEST WRAPPER ARCHITECTURE ** ** The test wrapper provides extra test facilities to ensure the library ** does not leak memory and handles the failure of the underlying (Os level) |
︙ | ︙ | |||
150 151 152 153 154 155 156 | */ #define TESTALLOC_OFFSET_GUARD1(p) (sizeof(void *) * 2) #define TESTALLOC_OFFSET_DATA(p) ( \ TESTALLOC_OFFSET_GUARD1(p) + sizeof(u32) * TESTALLOC_NGUARD \ ) #define TESTALLOC_OFFSET_GUARD2(p) ( \ | | | 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | */ #define TESTALLOC_OFFSET_GUARD1(p) (sizeof(void *) * 2) #define TESTALLOC_OFFSET_DATA(p) ( \ TESTALLOC_OFFSET_GUARD1(p) + sizeof(u32) * TESTALLOC_NGUARD \ ) #define TESTALLOC_OFFSET_GUARD2(p) ( \ TESTALLOC_OFFSET_DATA(p) + sqlite3OsAllocationSize(p) - TESTALLOC_OVERHEAD \ ) #define TESTALLOC_OFFSET_LINENUMBER(p) ( \ TESTALLOC_OFFSET_GUARD2(p) + sizeof(u32) * TESTALLOC_NGUARD \ ) #define TESTALLOC_OFFSET_FILENAME(p) ( \ TESTALLOC_OFFSET_LINENUMBER(p) + sizeof(u32) \ ) |
︙ | ︙ | |||
210 211 212 213 214 215 216 | return 1; } } return 0; } /* | | | 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 | return 1; } } return 0; } /* ** The argument is a pointer returned by sqlite3OsMalloc() or xRealloc(). ** assert() that the first and last (TESTALLOC_NGUARD*4) bytes are set to the ** values set by the applyGuards() function. */ static void checkGuards(u32 *p) { int i; char *zAlloc = (char *)p; |
︙ | ︙ | |||
236 237 238 239 240 241 242 | u32 guard = 0; memcpy(&guard, &z[i*sizeof(u32)], sizeof(u32)); assert(guard==0xdead3344); } } /* | | | 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 | u32 guard = 0; memcpy(&guard, &z[i*sizeof(u32)], sizeof(u32)); assert(guard==0xdead3344); } } /* ** The argument is a pointer returned by sqlite3OsMalloc() or Realloc(). The ** first and last (TESTALLOC_NGUARD*4) bytes are set to known values for use as ** guard-posts. */ static void applyGuards(u32 *p) { int i; char *z; |
︙ | ︙ | |||
392 393 394 395 396 397 398 | Tcl_IncrRefCount(pRes); for(p=pTsd->pFirst; p; p=((void **)p)[1]){ Tcl_Obj *pEntry = Tcl_NewObj(); Tcl_Obj *pStack = Tcl_NewObj(); char *z; u32 iLine; | | | 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 | Tcl_IncrRefCount(pRes); for(p=pTsd->pFirst; p; p=((void **)p)[1]){ Tcl_Obj *pEntry = Tcl_NewObj(); Tcl_Obj *pStack = Tcl_NewObj(); char *z; u32 iLine; int nBytes = sqlite3OsAllocationSize(p) - TESTALLOC_OVERHEAD; char *zAlloc = (char *)p; int i; Tcl_ListObjAppendElement(0, pEntry, Tcl_NewIntObj(nBytes)); z = &zAlloc[TESTALLOC_OFFSET_FILENAME(p)]; Tcl_ListObjAppendElement(0, pEntry, Tcl_NewStringObj(z, -1)); |
︙ | ︙ | |||
427 428 429 430 431 432 433 | Tcl_SetObjResult(interp, pRes); Tcl_DecrRefCount(pRes); return TCL_OK; } #endif /* | | | | | | | | | | | | | | | 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 | Tcl_SetObjResult(interp, pRes); Tcl_DecrRefCount(pRes); return TCL_OK; } #endif /* ** This is the test layer's wrapper around sqlite3OsMalloc(). */ static void * OSMALLOC(int n){ #ifndef SQLITE_OMIT_MEMORY_MANAGEMENT SqliteTsd *pTsd = sqlite3Tsd(); pTsd->nMaxAlloc = MAX(pTsd->nMaxAlloc, pTsd->nAlloc); #endif if( !failMalloc() ){ u32 *p; p = (u32 *)sqlite3OsMalloc(n + TESTALLOC_OVERHEAD); assert(p); sqlite3_nMalloc++; applyGuards(p); linkAlloc(p); return (void *)(&p[TESTALLOC_NGUARD + 2*sizeof(void *)/sizeof(u32)]); } return 0; } /* ** This is the test layer's wrapper around sqlite3OsFree(). The argument is a ** pointer to the space allocated for the application to use. */ void OSFREE(void *pFree){ u32 *p = (u32 *)getOsPointer(pFree); /* p points to Os level allocation */ checkGuards(p); unlinkAlloc(p); sqlite3OsFree(p); sqlite3_nFree++; } /* ** This is the test layer's wrapper around sqlite3OsRealloc(). */ void * OSREALLOC(void *pRealloc, int n){ #ifndef SQLITE_OMIT_MEMORY_MANAGEMENT SqliteTsd *pTsd = sqlite3Tsd(); pTsd->nMaxAlloc = MAX(pTsd->nMaxAlloc, pTsd->nAlloc); #endif if( !failMalloc() ){ u32 *p = (u32 *)getOsPointer(pRealloc); checkGuards(p); p = sqlite3OsRealloc(p, n + TESTALLOC_OVERHEAD); applyGuards(p); relinkAlloc(p); return (void *)(&p[TESTALLOC_NGUARD + 2*sizeof(void *)/sizeof(u32)]); } return 0; } void OSMALLOC_FAILED(){ sqlite3Tsd()->isFail = 0; } int OSSIZEOF(void *p){ if( p ){ u32 *pOs = (u32 *)getOsPointer(p); return sqlite3OsAllocationSize(pOs) - TESTALLOC_OVERHEAD; } return 0; } #else /* Define macros to call the sqlite3OsXXX interface directly if ** the SQLITE_MEMDEBUG macro is not defined. */ #define OSMALLOC(x) sqlite3OsMalloc(x) #define OSREALLOC(x,y) sqlite3OsRealloc(x,y) #define OSFREE(x) sqlite3OsFree(x) #define OSSIZEOF(x) sqlite3OsAllocationSize(x) #define OSMALLOC_FAILED() #endif /* ** End code for memory allocation system test layer. **--------------------------------------------------------------------------*/ /* ** The handleSoftLimit() function is called before each call to ** sqlite3OsMalloc() or xRealloc(). The parameter 'n' is the number of ** extra bytes about to be allocated (for Realloc() this means the size of the ** new allocation less the size of the old allocation). If the extra allocation ** means that the total memory allocated to SQLite in this thread would exceed ** the limit set by sqlite3_soft_heap_limit(), then sqlite3_release_memory() is ** called to try to avoid this. No indication of whether or not this is ** successful is returned to the caller. ** |
︙ | ︙ | |||
530 531 532 533 534 535 536 | } #else #define handleSoftLimit() #endif /* ** Allocate and return N bytes of uninitialised memory by calling | | | 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 | } #else #define handleSoftLimit() #endif /* ** Allocate and return N bytes of uninitialised memory by calling ** sqlite3OsMalloc(). If the Malloc() call fails, attempt to free memory ** by calling sqlite3_release_memory(). */ void *sqlite3MallocRaw(int n){ SqliteTsd *pTsd = sqlite3Tsd(); void *p = 0; if( n>0 && !pTsd->mallocFailed ){ handleSoftLimit(n); |
︙ | ︙ | |||
554 555 556 557 558 559 560 | OSMALLOC_FAILED(); } } return p; } /* | | | 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 | OSMALLOC_FAILED(); } } return p; } /* ** Resize the allocation at p to n bytes by calling sqlite3OsRealloc(). The ** pointer to the new allocation is returned. If the Realloc() call fails, ** attempt to free memory by calling sqlite3_release_memory(). */ void *sqlite3Realloc(void *p, int n){ SqliteTsd *pTsd = sqlite3Tsd(); if( pTsd->mallocFailed ){ return 0; |
︙ | ︙ | |||
1301 1302 1303 1304 1305 1306 1307 | } #endif /* ** Return a pointer to the SqliteTsd associated with the calling thread. */ SqliteTsd *sqlite3Tsd(){ | | | 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 | } #endif /* ** Return a pointer to the SqliteTsd associated with the calling thread. */ SqliteTsd *sqlite3Tsd(){ SqliteTsd *pTsd = sqlite3OsThreadSpecificData(sizeof(SqliteTsd)); if( pTsd && !pTsd->isInit ){ pTsd->nSoftHeapLimit = -1; #ifndef NDEBUG pTsd->mallocAllowed = 1; #endif pTsd->isInit = 1; } |
︙ | ︙ |
Changes to src/vacuum.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** This file contains code used to implement the VACUUM command. ** ** Most of the code in this file may be omitted by defining the ** SQLITE_OMIT_VACUUM macro. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** This file contains code used to implement the VACUUM command. ** ** Most of the code in this file may be omitted by defining the ** SQLITE_OMIT_VACUUM macro. ** ** $Id: vacuum.c,v 1.54 2006/01/06 14:32:20 drh Exp $ */ #include "sqliteInt.h" #include "vdbeInt.h" #include "os.h" #ifndef SQLITE_OMIT_VACUUM /* |
︙ | ︙ | |||
144 145 146 147 148 149 150 | ** run more than once or twice is vanishingly small. We are certain ** enough that this loop will always terminate (and terminate quickly) ** that we don't even bother to set a maximum loop count. */ do { zTemp[nFilename] = '-'; randomName((unsigned char*)&zTemp[nFilename+1]); | | | 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | ** run more than once or twice is vanishingly small. We are certain ** enough that this loop will always terminate (and terminate quickly) ** that we don't even bother to set a maximum loop count. */ do { zTemp[nFilename] = '-'; randomName((unsigned char*)&zTemp[nFilename+1]); } while( sqlite3OsFileExists(zTemp) ); /* Before we even attach it, compile a DETACH statement for vacuum_db. This ** way, if malloc() fails we can detach the database without needing to ** dynamically allocate memory. */ rc = sqlite3_prepare(db, "DETACH vacuum_db", -1, &pDetach, 0); if( rc!=SQLITE_OK ){ |
︙ | ︙ | |||
329 330 331 332 333 334 335 | ** Fix this so the flag and return code match. */ if( rc==SQLITE_NOMEM ){ sqlite3Tsd()->mallocFailed = 1; } if( zTemp ){ | | | 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 | ** Fix this so the flag and return code match. */ if( rc==SQLITE_NOMEM ){ sqlite3Tsd()->mallocFailed = 1; } if( zTemp ){ sqlite3OsDelete(zTemp); sqliteFree(zTemp); } sqliteFree( zSql ); sqlite3ResetInternalSchema(db, 0); #endif return rc; } |
Changes to src/vdbe.c.
︙ | ︙ | |||
39 40 41 42 43 44 45 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** | | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** ** $Id: vdbe.c,v 1.513 2006/01/06 14:32:20 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> #include "vdbeInt.h" /* |
︙ | ︙ | |||
425 426 427 428 429 430 431 | if( p->trace ){ if( pc==0 ){ printf("VDBE Execution Trace:\n"); sqlite3VdbePrintSql(p); } sqlite3VdbePrintOp(p->trace, pc, pOp); } | | | 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 | if( p->trace ){ if( pc==0 ){ printf("VDBE Execution Trace:\n"); sqlite3VdbePrintSql(p); } sqlite3VdbePrintOp(p->trace, pc, pOp); } if( p->trace==0 && pc==0 && sqlite3OsFileExists("vdbe_sqltrace") ){ sqlite3VdbePrintSql(p); } #endif /* Check to see if we need to simulate an interrupt. This only happens ** if we have a special test build. |
︙ | ︙ |
Changes to src/vdbeapi.c.
︙ | ︙ | |||
189 190 191 192 193 194 195 | if( sqlite3SafetyOn(db) ){ p->rc = SQLITE_MISUSE; return SQLITE_MISUSE; } } if( db->xProfile && !db->init.busy ){ double rNow; | | | 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 | if( sqlite3SafetyOn(db) ){ p->rc = SQLITE_MISUSE; return SQLITE_MISUSE; } } if( db->xProfile && !db->init.busy ){ double rNow; sqlite3OsCurrentTime(&rNow); p->startTime = (rNow - (int)rNow)*3600.0*24.0*1000000000.0; } #endif /* Print a copy of SQL as it is executed if the SQL_TRACE pragma is turned ** on in debugging mode. */ |
︙ | ︙ | |||
226 227 228 229 230 231 232 | #ifndef SQLITE_OMIT_TRACE /* Invoke the profile callback if there is one */ if( rc!=SQLITE_ROW && db->xProfile && !db->init.busy ){ double rNow; u64 elapseTime; | | | 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 | #ifndef SQLITE_OMIT_TRACE /* Invoke the profile callback if there is one */ if( rc!=SQLITE_ROW && db->xProfile && !db->init.busy ){ double rNow; u64 elapseTime; sqlite3OsCurrentTime(&rNow); elapseTime = (rNow - (int)rNow)*3600.0*24.0*1000000000.0 - p->startTime; assert( p->nOp>0 ); assert( p->aOp[p->nOp-1].opcode==OP_Noop ); assert( p->aOp[p->nOp-1].p3!=0 ); assert( p->aOp[p->nOp-1].p3type==P3_DYNAMIC ); db->xProfile(db->pProfileArg, p->aOp[p->nOp-1].p3, elapseTime); } |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
269 270 271 272 273 274 275 | p->aLabel = 0; *pMaxFuncArgs = nMaxArgs; *pMaxStack = nMaxStack; /* If we never rollback a statement transaction, then statement ** transactions are not needed. So change every OP_Statement | | | 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 | p->aLabel = 0; *pMaxFuncArgs = nMaxArgs; *pMaxStack = nMaxStack; /* If we never rollback a statement transaction, then statement ** transactions are not needed. So change every OP_Statement ** opcode into an OP_Noop. This avoid a call to sqlite3OsOpenExclusive() ** which can be expensive on some platforms. */ if( hasStatementBegin && !doesStatementRollback ){ for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){ if( pOp->opcode==OP_Statement ){ pOp->opcode = OP_Noop; } |
︙ | ︙ | |||
755 756 757 758 759 760 761 | } for(n=0; n<p->nMem; n++){ p->aMem[n].flags = MEM_Null; } #ifdef SQLITE_DEBUG if( (p->db->flags & SQLITE_VdbeListing)!=0 | | | | 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 | } for(n=0; n<p->nMem; n++){ p->aMem[n].flags = MEM_Null; } #ifdef SQLITE_DEBUG if( (p->db->flags & SQLITE_VdbeListing)!=0 || sqlite3OsFileExists("vdbe_explain") ){ int i; printf("VDBE Program Listing:\n"); sqlite3VdbePrintSql(p); for(i=0; i<p->nOp; i++){ sqlite3VdbePrintOp(stdout, i, &p->aOp[i]); } } if( sqlite3OsFileExists("vdbe_trace") ){ p->trace = stdout; } #endif p->pTos = &p->aStack[-1]; p->pc = -1; p->rc = SQLITE_OK; p->uniqueCnt = 0; |
︙ | ︙ | |||
978 979 980 981 982 983 984 | u32 random; sqliteFree(zMaster); sqlite3Randomness(sizeof(random), &random); zMaster = sqlite3MPrintf("%s-mj%08X", zMainFile, random&0x7fffffff); if( !zMaster ){ return SQLITE_NOMEM; } | | | | 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 | u32 random; sqliteFree(zMaster); sqlite3Randomness(sizeof(random), &random); zMaster = sqlite3MPrintf("%s-mj%08X", zMainFile, random&0x7fffffff); if( !zMaster ){ return SQLITE_NOMEM; } }while( sqlite3OsFileExists(zMaster) ); /* Open the master journal. */ rc = sqlite3OsOpenExclusive(zMaster, &master, 0); if( rc!=SQLITE_OK ){ sqliteFree(zMaster); return rc; } /* Write the name of each database file in the transaction into the new ** master journal file. If an error occurs at this point close |
︙ | ︙ | |||
1005 1006 1007 1008 1009 1010 1011 | if( zFile[0]==0 ) continue; /* Ignore :memory: databases */ if( !needSync && !sqlite3BtreeSyncDisabled(pBt) ){ needSync = 1; } rc = sqlite3OsWrite(master, zFile, strlen(zFile)+1); if( rc!=SQLITE_OK ){ sqlite3OsClose(&master); | | | | 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 | if( zFile[0]==0 ) continue; /* Ignore :memory: databases */ if( !needSync && !sqlite3BtreeSyncDisabled(pBt) ){ needSync = 1; } rc = sqlite3OsWrite(master, zFile, strlen(zFile)+1); if( rc!=SQLITE_OK ){ sqlite3OsClose(&master); sqlite3OsDelete(zMaster); sqliteFree(zMaster); return rc; } } } /* Sync the master journal file. Before doing this, open the directory ** the master journal file is store in so that it gets synced too. */ zMainFile = sqlite3BtreeGetDirname(db->aDb[0].pBt); rc = sqlite3OsOpenDirectory(master, zMainFile); if( rc!=SQLITE_OK || (needSync && (rc=sqlite3OsSync(master,0))!=SQLITE_OK) ){ sqlite3OsClose(&master); sqlite3OsDelete(zMaster); sqliteFree(zMaster); return rc; } /* Sync all the db files involved in the transaction. The same call ** sets the master journal pointer in each individual journal. If ** an error occurs here, do not delete the master journal file. |
︙ | ︙ | |||
1053 1054 1055 1056 1057 1058 1059 | } sqlite3OsClose(&master); /* Delete the master journal file. This commits the transaction. After ** doing this the directory is synced again before any individual ** transaction files are deleted. */ | | | | 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 | } sqlite3OsClose(&master); /* Delete the master journal file. This commits the transaction. After ** doing this the directory is synced again before any individual ** transaction files are deleted. */ rc = sqlite3OsDelete(zMaster); assert( rc==SQLITE_OK ); sqliteFree(zMaster); zMaster = 0; rc = sqlite3OsSyncDirectory(zMainFile); if( rc!=SQLITE_OK ){ /* This is not good. The master journal file has been deleted, but ** the directory sync failed. There is no completely safe course of ** action from here. The individual journals contain the name of the ** master journal file, but there is no way of knowing if that ** master journal exists now or if it will exist after the operating ** system crash that may follow the fsync() failure. |
︙ | ︙ |
Deleted test/async.test.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Changes to test/crash.test.
︙ | ︙ | |||
13 14 15 16 17 18 19 | # The focus of this file is testing the ability of the database to # uses its rollback journal to recover intact (no database corruption) # from a power failure during the middle of a COMMIT. The OS interface # modules are overloaded in a separate instance of testfixture using # the modified I/O routines found in test6.c. These routines allow us # to simulate the kind of file damage that occurs after a power failure. # | | > > > > > | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | # The focus of this file is testing the ability of the database to # uses its rollback journal to recover intact (no database corruption) # from a power failure during the middle of a COMMIT. The OS interface # modules are overloaded in a separate instance of testfixture using # the modified I/O routines found in test6.c. These routines allow us # to simulate the kind of file damage that occurs after a power failure. # # $Id: crash.test,v 1.21 2006/01/06 14:32:20 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable !crashtest { finish_test return } # set repeats 100 set repeats 10 # This proc execs a seperate process that crashes midway through executing # the SQL script $sql on database test.db. # |
︙ | ︙ |
Changes to test/ioerr.test.
︙ | ︙ | |||
11 12 13 14 15 16 17 | # This file implements regression tests for SQLite library. The # focus of this file is testing for correct handling of I/O errors # such as writes failing because the disk is full. # # The tests in this file use special facilities that are only # available in the SQLite test fixture. # | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # This file implements regression tests for SQLite library. The # focus of this file is testing for correct handling of I/O errors # such as writes failing because the disk is full. # # The tests in this file use special facilities that are only # available in the SQLite test fixture. # # $Id: ioerr.test,v 1.22 2006/01/06 14:32:20 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # If SQLITE_DEFAULT_AUTOVACUUM is set to true, then a simulated IO error # on the 8th IO operation in the SQL script below doesn't report an error. |
︙ | ︙ | |||
129 130 131 132 133 134 135 | CREATE TABLE t1(a,b,c); CREATE TABLE test2.t2(a,b,c); COMMIT; } -exclude $ex # Test IO errors when replaying two hot journals from a 2-file # transaction. This test only runs on UNIX. | | | | | | | | | | | | | | | | | | | | | | | > | 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | CREATE TABLE t1(a,b,c); CREATE TABLE test2.t2(a,b,c); COMMIT; } -exclude $ex # Test IO errors when replaying two hot journals from a 2-file # transaction. This test only runs on UNIX. ifcapable crashtest { if {![catch {sqlite3 -has_codec} r] && !$r} { do_ioerr_test ioerr-6 -tclprep { execsql { ATTACH 'test2.db' as aux; CREATE TABLE tx(a, b); CREATE TABLE aux.ty(a, b); } set rc [crashsql 2 test2.db-journal { ATTACH 'test2.db' as aux; PRAGMA cache_size = 10; BEGIN; CREATE TABLE aux.t2(a, b, c); CREATE TABLE t1(a, b, c); COMMIT; }] if {$rc!="1 {child process exited abnormally}"} { error "Wrong error message: $rc" } } -sqlbody { SELECT * FROM sqlite_master; SELECT * FROM aux.sqlite_master; } } } # Test handling of IO errors that occur while rolling back hot journal # files. # # These tests can't be run on windows because the windows version of |
︙ | ︙ |
Changes to test/malloc.test.
︙ | ︙ | |||
10 11 12 13 14 15 16 | #*********************************************************************** # This file attempts to check the library in an out-of-memory situation. # When compiled with -DSQLITE_DEBUG=1, the SQLite library accepts a special # command (sqlite_malloc_fail N) which causes the N-th malloc to fail. This # special feature is used to see what happens in the library if a malloc # were to really fail due to an out-of-memory situation. # | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | #*********************************************************************** # This file attempts to check the library in an out-of-memory situation. # When compiled with -DSQLITE_DEBUG=1, the SQLite library accepts a special # command (sqlite_malloc_fail N) which causes the N-th malloc to fail. This # special feature is used to see what happens in the library if a malloc # were to really fail due to an out-of-memory situation. # # $Id: malloc.test,v 1.26 2006/01/06 14:32:20 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Only run these tests if memory debugging is turned on. # if {[info command sqlite_malloc_stat]==""} { |
︙ | ︙ | |||
336 337 338 339 340 341 342 | set sql16 [encoding convertto unicode "SELECT * FROM sqlite_master"] append sql16 "\00\00" set ::STMT [sqlite3_prepare16 $::DB $sql16 -1 DUMMY] sqlite3_finalize $::STMT } # Test malloc errors when replaying two hot journals from a 2-file | | | | 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 | set sql16 [encoding convertto unicode "SELECT * FROM sqlite_master"] append sql16 "\00\00" set ::STMT [sqlite3_prepare16 $::DB $sql16 -1 DUMMY] sqlite3_finalize $::STMT } # Test malloc errors when replaying two hot journals from a 2-file # transaction. ifcapable crashtest { do_malloc_test 13 -tclprep { set rc [crashsql 1 test2.db { ATTACH 'test2.db' as aux; PRAGMA cache_size = 10; BEGIN; CREATE TABLE aux.t2(a, b, c); CREATE TABLE t1(a, b, c); |
︙ | ︙ |