Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | The win32 driver compiles but does not yet work well. Many bugs fixed. (CVS 4282) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
3a68fcddfa9184e4b310ce0a21312c54 |
User & Date: | drh 2007-08-24 03:51:33.000 |
Context
2007-08-24
| ||
04:15 | Bug fix in the memory leak trace output. (CVS 4283) (check-in: a1b495c28a user: drh tags: trunk) | |
03:51 | The win32 driver compiles but does not yet work well. Many bugs fixed. (CVS 4282) (check-in: 3a68fcddfa user: drh tags: trunk) | |
2007-08-23
| ||
20:28 | Make comments and variable naming more consistent WRT rowid versus docid/blockid. This should have no code impact. (CVS 4281) (check-in: 76f1e18ebc user: shess tags: trunk) | |
Changes
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.411 2007/08/24 03:51:33 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** See the header comment on "btreeInt.h" for additional information. ** Including a description of file format and an overview of operation. */ #include "btreeInt.h" |
︙ | ︙ | |||
1098 1099 1100 1101 1102 1103 1104 | sqlite3_vfs *pVfs; /* The VFS to use for this btree */ BtShared *pBt = 0; /* Shared part of btree structure */ Btree *p; /* Handle to return */ int rc = SQLITE_OK; int nReserve; unsigned char zDbHeader[100]; | < < < < < < < > > > > > > > | 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 | sqlite3_vfs *pVfs; /* The VFS to use for this btree */ BtShared *pBt = 0; /* Shared part of btree structure */ Btree *p; /* Handle to return */ int rc = SQLITE_OK; int nReserve; unsigned char zDbHeader[100]; /* Set the variable isMemdb to true for an in-memory database, or ** false for a file-based database. This symbol is only required if ** either of the shared-data or autovacuum features are compiled ** into the library. */ #if !defined(SQLITE_OMIT_SHARED_CACHE) || !defined(SQLITE_OMIT_AUTOVACUUM) #ifdef SQLITE_OMIT_MEMORYDB const int isMemdb = 0; #else const int isMemdb = zFilename && !strcmp(zFilename, ":memory:"); #endif #endif if( pSqlite ){ pVfs = pSqlite->pVfs; }else{ pVfs = sqlite3_vfs_find(0); } assert( sqlite3BtreeMutexHeld(pSqlite->mutex) ); p = sqlite3MallocZero(sizeof(Btree)); if( !p ){ return SQLITE_NOMEM; } p->inTrans = TRANS_NONE; p->pSqlite = pSqlite; |
︙ | ︙ |
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.72 2007/08/24 03:51:33 drh Exp $ ** ** SQLite processes all times and dates as Julian Day numbers. The ** dates and times are stored as the number of days since noon ** in Greenwich on November 24, 4714 B.C. according to the Gregorian ** calendar system. ** ** 1970-01-01 00:00:00 is JD 2440587.5 |
︙ | ︙ | |||
422 423 424 425 426 427 428 | y.h = sLocal.tm_hour; y.m = sLocal.tm_min; y.s = sLocal.tm_sec; } #else { struct tm *pTm; | | | | 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 | y.h = sLocal.tm_hour; y.m = sLocal.tm_min; y.s = sLocal.tm_sec; } #else { struct tm *pTm; sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)); pTm = localtime(&t); y.Y = pTm->tm_year + 1900; y.M = pTm->tm_mon + 1; y.D = pTm->tm_mday; y.h = pTm->tm_hour; y.m = pTm->tm_min; y.s = pTm->tm_sec; sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)); } #endif y.validYMD = 1; y.validHMS = 1; y.validJD = 0; y.validTZ = 0; computeJD(&y); |
︙ | ︙ |
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.397 2007/08/24 03:51:34 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** The version of the library */ |
︙ | ︙ | |||
941 942 943 944 945 946 947 | CollSeq *pColl; /* Allocate the sqlite data structure */ db = sqlite3MallocZero( sizeof(sqlite3) ); if( db==0 ) goto opendb_out; db->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_RECURSIVE); if( db->mutex==0 ){ | > | < > | 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 | CollSeq *pColl; /* Allocate the sqlite data structure */ db = sqlite3MallocZero( sizeof(sqlite3) ); if( db==0 ) goto opendb_out; db->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_RECURSIVE); if( db->mutex==0 ){ sqlite3_free(db); db = 0; goto opendb_out; } sqlite3_mutex_enter(db->mutex); db->pVfs = sqlite3_vfs_find(zVfs); db->errMask = 0xff; db->priorNewRowid = 0; db->nDb = 2; db->magic = SQLITE_MAGIC_BUSY; db->aDb = db->aDbStatic; db->autoCommit = 1; db->flags |= SQLITE_ShortColNames #if SQLITE_DEFAULT_FILE_FORMAT<4 | SQLITE_LegacyFileFmt #endif #ifdef SQLITE_ENABLE_LOAD_EXTENSION |
︙ | ︙ | |||
1072 1073 1074 1075 1076 1077 1078 | #ifdef SQLITE_DEFAULT_LOCKING_MODE db->dfltLockMode = SQLITE_DEFAULT_LOCKING_MODE; sqlite3PagerLockingMode(sqlite3BtreePager(db->aDb[0].pBt), SQLITE_DEFAULT_LOCKING_MODE); #endif opendb_out: | | | 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 | #ifdef SQLITE_DEFAULT_LOCKING_MODE db->dfltLockMode = SQLITE_DEFAULT_LOCKING_MODE; sqlite3PagerLockingMode(sqlite3BtreePager(db->aDb[0].pBt), SQLITE_DEFAULT_LOCKING_MODE); #endif opendb_out: if( db && db->mutex ){ sqlite3_mutex_leave(db->mutex); } if( SQLITE_NOMEM==(rc = sqlite3_errcode(db)) ){ sqlite3_close(db); db = 0; } *ppDb = db; |
︙ | ︙ |
Changes to src/malloc.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Memory allocation functions used throughout sqlite. ** ** | | | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Memory allocation functions used throughout sqlite. ** ** ** $Id: malloc.c,v 1.11 2007/08/24 03:51:34 drh Exp $ */ #include "sqliteInt.h" #include <stdarg.h> #include <ctype.h> /* ** This routine runs when the memory allocator sees that the ** total memory allocation is about to exceed the soft heap ** limit. */ static void softHeapLimitEnforcer( void *NotUsed, sqlite3_int64 inUse, int allocSize ){ sqlite3_release_memory(allocSize); } /* ** Set the soft heap-size limit for the current thread. Passing a ** zero or negative value indicates no limit. |
︙ | ︙ |
Changes to src/mem1.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains the C functions that implement a memory ** allocation subsystem for use by SQLite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains the C functions that implement a memory ** allocation subsystem for use by SQLite. ** ** $Id: mem1.c,v 1.8 2007/08/24 03:51:34 drh Exp $ */ /* ** This version of the memory allocator is the default. It is ** used when no other memory allocator is specified using compile-time ** macros. */ |
︙ | ︙ | |||
47 48 49 50 51 52 53 | /* ** The alarm callback and its arguments. The mem.mutex lock will ** be held while the callback is running. Recursive calls into ** the memory subsystem are allowed, but no new callbacks will be ** issued. The alarmBusy variable is set to prevent recursive ** callbacks. */ | | | | | < < < < | | | | | | | | | | | | | 47 48 49 50 51 52 53 54 55 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 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 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 | /* ** The alarm callback and its arguments. The mem.mutex lock will ** be held while the callback is running. Recursive calls into ** the memory subsystem are allowed, but no new callbacks will be ** issued. The alarmBusy variable is set to prevent recursive ** callbacks. */ sqlite3_int64 alarmThreshold; void (*alarmCallback)(void*, sqlite3_int64,int); void *alarmArg; int alarmBusy; /* ** Mutex to control access to the memory allocation subsystem. */ sqlite3_mutex *mutex; /* ** Current allocation and high-water mark. */ sqlite3_int64 nowUsed; sqlite3_int64 mxUsed; } mem; /* ** Return the amount of memory currently checked out. */ sqlite3_int64 sqlite3_memory_used(void){ sqlite3_int64 n; if( mem.mutex==0 ){ mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM); } sqlite3_mutex_enter(mem.mutex); n = mem.nowUsed; sqlite3_mutex_leave(mem.mutex); return n; } /* ** Return the maximum amount of memory that has ever been ** checked out since either the beginning of this process ** or since the most recent reset. */ sqlite3_int64 sqlite3_memory_highwater(int resetFlag){ sqlite3_int64 n; if( mem.mutex==0 ){ mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM); } sqlite3_mutex_enter(mem.mutex); n = mem.mxUsed; if( resetFlag ){ mem.mxUsed = mem.nowUsed; } sqlite3_mutex_leave(mem.mutex); return n; } /* ** Change the alarm callback */ int sqlite3_memory_alarm( void(*xCallback)(void *pArg, sqlite3_int64 used,int N), void *pArg, sqlite3_int64 iThreshold ){ if( mem.mutex==0 ){ mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM); } sqlite3_mutex_enter(mem.mutex); mem.alarmCallback = xCallback; mem.alarmArg = pArg; mem.alarmThreshold = iThreshold; sqlite3_mutex_leave(mem.mutex); return SQLITE_OK; } /* ** Trigger the alarm */ static void sqlite3MemsysAlarm(int nByte){ void (*xCallback)(void*,sqlite3_int64,int); sqlite3_int64 nowUsed; void *pArg; if( mem.alarmCallback==0 || mem.alarmBusy ) return; mem.alarmBusy = 1; xCallback = mem.alarmCallback; nowUsed = mem.nowUsed; pArg = mem.alarmArg; sqlite3_mutex_leave(mem.mutex); xCallback(pArg, nowUsed, nByte); sqlite3_mutex_enter(mem.mutex); mem.alarmBusy = 0; } /* ** Allocate nBytes of memory */ void *sqlite3_malloc(int nBytes){ sqlite3_int64 *p; if( nBytes<=0 ){ return 0; } if( mem.mutex==0 ){ mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM); } sqlite3_mutex_enter(mem.mutex); if( mem.alarmCallback!=0 && mem.nowUsed+nBytes>=mem.alarmThreshold ){ sqlite3MemsysAlarm(nBytes); } p = malloc(nBytes+8); if( p==0 ){ sqlite3MemsysAlarm(nBytes); p = malloc(nBytes+8); } |
︙ | ︙ | |||
177 178 179 180 181 182 183 | return (void*)p; } /* ** Free memory. */ void sqlite3_free(void *pPrior){ | | | | | | | | 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 | return (void*)p; } /* ** Free memory. */ void sqlite3_free(void *pPrior){ sqlite3_int64 *p; int nByte; if( pPrior==0 ){ return; } assert( mem.mutex!=0 ); p = pPrior; p--; nByte = (int)*p; sqlite3_mutex_enter(mem.mutex); mem.nowUsed -= nByte; free(p); sqlite3_mutex_leave(mem.mutex); } /* ** Change the size of an existing memory allocation */ void *sqlite3_realloc(void *pPrior, int nBytes){ int nOld; sqlite3_int64 *p; if( pPrior==0 ){ return sqlite3_malloc(nBytes); } if( nBytes<=0 ){ sqlite3_free(pPrior); return 0; } p = pPrior; p--; nOld = (int)p[0]; assert( mem.mutex!=0 ); sqlite3_mutex_enter(mem.mutex); if( mem.nowUsed+nBytes-nOld>=mem.alarmThreshold ){ sqlite3MemsysAlarm(nBytes-nOld); } p = realloc(p, nBytes+8); if( p==0 ){ |
︙ | ︙ |
Changes to src/mem2.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains the C functions that implement a memory ** allocation subsystem for use by SQLite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains the C functions that implement a memory ** allocation subsystem for use by SQLite. ** ** $Id: mem2.c,v 1.9 2007/08/24 03:51:34 drh Exp $ */ /* ** This version of the memory allocator is used only if the ** SQLITE_MEMDEBUG macro is defined and SQLITE_OMIT_MEMORY_ALLOCATION ** is not defined. */ |
︙ | ︙ | |||
67 68 69 70 71 72 73 | ** to back up from the allocation pointer to find the MemBlockHdr. The ** MemBlockHdr tells us the size of the allocation and the number of ** backtrace pointers. There is also a guard word at the end of the ** MemBlockHdr. */ struct MemBlockHdr { struct MemBlockHdr *pNext, *pPrev; /* Linked list of all unfreed memory */ | | | | | | | 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | ** to back up from the allocation pointer to find the MemBlockHdr. The ** MemBlockHdr tells us the size of the allocation and the number of ** backtrace pointers. There is also a guard word at the end of the ** MemBlockHdr. */ struct MemBlockHdr { struct MemBlockHdr *pNext, *pPrev; /* Linked list of all unfreed memory */ int iSize; /* Size of this allocation */ char nBacktrace; /* Number of backtraces on this alloc */ char nBacktraceSlots; /* Available backtrace slots */ short nTitle; /* Bytes of title; includes '\0' */ int iForeGuard; /* Guard word for sanity */ }; /* ** Guard words */ #define FOREGUARD 0x80F5E153 #define REARGUARD 0xE4676B53 |
︙ | ︙ | |||
94 95 96 97 98 99 100 | /* ** The alarm callback and its arguments. The mem.mutex lock will ** be held while the callback is running. Recursive calls into ** the memory subsystem are allowed, but no new callbacks will be ** issued. The alarmBusy variable is set to prevent recursive ** callbacks. */ | | | | | | 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 | /* ** The alarm callback and its arguments. The mem.mutex lock will ** be held while the callback is running. Recursive calls into ** the memory subsystem are allowed, but no new callbacks will be ** issued. The alarmBusy variable is set to prevent recursive ** callbacks. */ sqlite3_int64 alarmThreshold; void (*alarmCallback)(void*, sqlite3_int64, int); void *alarmArg; int alarmBusy; /* ** Mutex to control access to the memory allocation subsystem. */ sqlite3_mutex *mutex; /* ** Current allocation and high-water mark. */ sqlite3_int64 nowUsed; sqlite3_int64 mxUsed; /* ** Head and tail of a linked list of all outstanding allocations */ struct MemBlockHdr *pFirst; struct MemBlockHdr *pLast; |
︙ | ︙ | |||
143 144 145 146 147 148 149 | /* ** sqlite3MallocDisallow() increments the following counter. ** sqlite3MallocAllow() decrements it. */ int disallow; /* Do not allow memory allocation */ | < < < < | | | | | | | | | | | | | | | | | | 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 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 | /* ** sqlite3MallocDisallow() increments the following counter. ** sqlite3MallocAllow() decrements it. */ int disallow; /* Do not allow memory allocation */ } mem; /* ** Return the amount of memory currently checked out. */ sqlite3_int64 sqlite3_memory_used(void){ sqlite3_int64 n; if( mem.mutex==0 ){ mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM); } sqlite3_mutex_enter(mem.mutex); n = mem.nowUsed; sqlite3_mutex_leave(mem.mutex); return n; } /* ** Return the maximum amount of memory that has ever been ** checked out since either the beginning of this process ** or since the most recent reset. */ sqlite3_int64 sqlite3_memory_highwater(int resetFlag){ sqlite3_int64 n; if( mem.mutex==0 ){ mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM); } sqlite3_mutex_enter(mem.mutex); n = mem.mxUsed; if( resetFlag ){ mem.mxUsed = mem.nowUsed; } sqlite3_mutex_leave(mem.mutex); return n; } /* ** Change the alarm callback */ int sqlite3_memory_alarm( void(*xCallback)(void *pArg, sqlite3_int64 used, int N), void *pArg, sqlite3_int64 iThreshold ){ if( mem.mutex==0 ){ mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM); } sqlite3_mutex_enter(mem.mutex); mem.alarmCallback = xCallback; mem.alarmArg = pArg; mem.alarmThreshold = iThreshold; sqlite3_mutex_leave(mem.mutex); return SQLITE_OK; } /* ** Trigger the alarm */ static void sqlite3MemsysAlarm(int nByte){ void (*xCallback)(void*,sqlite3_int64,int); sqlite3_int64 nowUsed; void *pArg; if( mem.alarmCallback==0 || mem.alarmBusy ) return; mem.alarmBusy = 1; xCallback = mem.alarmCallback; nowUsed = mem.nowUsed; pArg = mem.alarmArg; sqlite3_mutex_leave(mem.mutex); xCallback(pArg, nowUsed, nByte); sqlite3_mutex_enter(mem.mutex); mem.alarmBusy = 0; } /* ** Given an allocation, find the MemBlockHdr for that allocation. ** ** This routine checks the guards at either end of the allocation and ** if they are incorrect it asserts. */ static struct MemBlockHdr *sqlite3MemsysGetHeader(void *pAllocation){ struct MemBlockHdr *p; int *pInt; p = (struct MemBlockHdr*)pAllocation; p--; assert( p->iForeGuard==FOREGUARD ); assert( (p->iSize & 3)==0 ); pInt = (int*)pAllocation; assert( pInt[p->iSize/sizeof(int)]==REARGUARD ); return p; } /* ** This routine is called once the first time a simulated memory ** failure occurs. The sole purpose of this routine is to provide ** a convenient place to set a debugger breakpoint when debugging ** errors related to malloc() failures. */ static void sqlite3MemsysFailed(void){ mem.iFailCnt = 0; } /* ** Allocate nByte bytes of memory. */ void *sqlite3_malloc(int nByte){ struct MemBlockHdr *pHdr; void **pBt; char *z; int *pInt; void *p; int totalSize; if( nByte<=0 ){ return 0; } if( mem.mutex==0 ){ mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM); } sqlite3_mutex_enter(mem.mutex); assert( mem.disallow==0 ); if( mem.alarmCallback!=0 && mem.nowUsed+nByte>=mem.alarmThreshold ){ sqlite3MemsysAlarm(nByte); } nByte = (nByte+3)&~3; totalSize = nByte + sizeof(*pHdr) + sizeof(int) + mem.nBacktrace*sizeof(void*) + mem.nTitle; if( mem.iFail>0 ){ if( mem.iFail==1 ){ p = 0; mem.iFail = mem.iReset; if( mem.iFailCnt==0 ){ sqlite3MemsysFailed(); /* A place to set a breakpoint */ |
︙ | ︙ | |||
319 320 321 322 323 324 325 | }else{ pHdr->nBacktrace = 0; } if( mem.nTitle ){ memcpy(z, mem.zTitle, mem.nTitle); } pHdr->iSize = nByte; | | | | 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 | }else{ pHdr->nBacktrace = 0; } if( mem.nTitle ){ memcpy(z, mem.zTitle, mem.nTitle); } pHdr->iSize = nByte; pInt = (int*)&pHdr[1]; pInt[nByte/sizeof(int)] = REARGUARD; memset(pInt, 0x65, nByte); mem.nowUsed += nByte; if( mem.nowUsed>mem.mxUsed ){ mem.mxUsed = mem.nowUsed; } p = (void*)pInt; } |
︙ | ︙ | |||
365 366 367 368 369 370 371 | }else{ assert( mem.pLast==pHdr ); mem.pLast = pHdr->pPrev; } z = (char*)pBt; z -= pHdr->nTitle; memset(z, 0x2b, sizeof(void*)*pHdr->nBacktraceSlots + sizeof(*pHdr) + | | | 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 | }else{ assert( mem.pLast==pHdr ); mem.pLast = pHdr->pPrev; } z = (char*)pBt; z -= pHdr->nTitle; memset(z, 0x2b, sizeof(void*)*pHdr->nBacktraceSlots + sizeof(*pHdr) + pHdr->iSize + sizeof(int) + pHdr->nTitle); free(z); sqlite3_mutex_leave(mem.mutex); } /* ** Change the size of an existing memory allocation. ** |
︙ | ︙ | |||
484 485 486 487 488 489 490 | if( iRepeat>=0 ){ mem.iReset = iRepeat; } mem.iFailCnt = 0; return n; } | < < < < < < < < < | 480 481 482 483 484 485 486 487 488 489 490 491 492 493 | if( iRepeat>=0 ){ mem.iReset = iRepeat; } mem.iFailCnt = 0; return n; } /* ** The following two routines are used to assert that no memory ** allocations occur between one call and the next. The use of ** these routines does not change the computed results in any way. ** These routines are like asserts. */ void sqlite3MallocDisallow(void){ |
︙ | ︙ |
Changes to src/os.c.
︙ | ︙ | |||
106 107 108 109 110 111 112 | int sqlite3OsOpen( sqlite3_vfs *pVfs, const char *zPath, sqlite3_file *pFile, int flags, int *pFlagsOut ){ | | | | | | | | | | | | | | 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 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | int sqlite3OsOpen( sqlite3_vfs *pVfs, const char *zPath, sqlite3_file *pFile, int flags, int *pFlagsOut ){ return pVfs->xOpen(pVfs, zPath, pFile, flags, pFlagsOut); } int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ return pVfs->xDelete(pVfs, zPath, dirSync); } int sqlite3OsAccess(sqlite3_vfs *pVfs, const char *zPath, int flags){ return pVfs->xAccess(pVfs, zPath, flags); } int sqlite3OsGetTempName(sqlite3_vfs *pVfs, char *zBufOut){ return pVfs->xGetTempName(pVfs, zBufOut); } int sqlite3OsFullPathname(sqlite3_vfs *pVfs, const char *zPath, char *zPathOut){ return pVfs->xFullPathname(pVfs, zPath, zPathOut); } void *sqlite3OsDlOpen(sqlite3_vfs *pVfs, const char *zPath){ return pVfs->xDlOpen(pVfs, zPath); } void sqlite3OsDlError(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ pVfs->xDlError(pVfs, nByte, zBufOut); } void *sqlite3OsDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){ return pVfs->xDlSym(pVfs, pHandle, zSymbol); } void sqlite3OsDlClose(sqlite3_vfs *pVfs, void *pHandle){ pVfs->xDlClose(pVfs, pHandle); } int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ return pVfs->xRandomness(pVfs, nByte, zBufOut); } int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){ return pVfs->xSleep(pVfs, nMicro); } int sqlite3OsCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){ return pVfs->xCurrentTime(pVfs, pTimeOut); } int sqlite3OsOpenMalloc( sqlite3_vfs *pVfs, const char *zFile, sqlite3_file **ppFile, int flags, |
︙ | ︙ | |||
171 172 173 174 175 176 177 | if( pFile ){ rc = sqlite3OsClose(pFile); sqlite3_free(pFile); } return rc; } | | < < < < < | > > | > > > > > | 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 | if( pFile ){ rc = sqlite3OsClose(pFile); sqlite3_free(pFile); } return rc; } /* ** The list of all registered VFS implementations. This list is ** initialized to the single VFS returned by sqlite3OsDefaultVfs() ** upon the first call to sqlite3_vfs_find(). */ static sqlite3_vfs *vfsList = 0; /* ** Locate a VFS by name. If no name is given, simply return the ** first VFS on the list. */ sqlite3_vfs *sqlite3_vfs_find(const char *zVfs){ sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER); sqlite3_vfs *pVfs; static int isInit = 0; sqlite3_mutex_enter(mutex); if( !isInit ){ vfsList = sqlite3OsDefaultVfs(); isInit = 1; } for(pVfs = vfsList; pVfs; pVfs=pVfs->pNext){ if( zVfs==0 ) break; if( strcmp(zVfs, pVfs->zName)==0 ) break; } if( pVfs ){ pVfs->nRef++; assert( pVfs->nRef==1 || pVfs->vfsMutex!=0 ); |
︙ | ︙ | |||
213 214 215 216 217 218 219 | ** Release a VFS once it is no longer needed. */ int sqlite3_vfs_release(sqlite3_vfs *pVfs){ sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER); sqlite3_mutex_enter(mutex); assert( pVfs->nRef>0 ); pVfs->nRef--; | | | 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 | ** Release a VFS once it is no longer needed. */ int sqlite3_vfs_release(sqlite3_vfs *pVfs){ sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER); sqlite3_mutex_enter(mutex); assert( pVfs->nRef>0 ); pVfs->nRef--; if( pVfs->nRef==0 && pVfs->vfsMutex ){ sqlite3_mutex_free(pVfs->vfsMutex); pVfs->vfsMutex = 0; } sqlite3_mutex_leave(mutex); return SQLITE_OK; } |
︙ | ︙ |
Changes to src/os.h.
︙ | ︙ | |||
105 106 107 108 109 110 111 | /* ** Temporary files are named starting with this prefix followed by 16 random ** alphanumeric characters, and no file extension. They are stored in the ** OS's standard temporary file directory, and are deleted prior to exit. ** If sqlite is being embedded in another program, you may wish to change the ** prefix to reflect your program's name, so that if your program exits ** prematurely, old temporary files can be easily identified. This can be done | | | | | 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 | /* ** Temporary files are named starting with this prefix followed by 16 random ** alphanumeric characters, and no file extension. They are stored in the ** OS's standard temporary file directory, and are deleted prior to exit. ** If sqlite is being embedded in another program, you may wish to change the ** prefix to reflect your program's name, so that if your program exits ** prematurely, old temporary files can be easily identified. This can be done ** using -DSQLITE_TEMP_FILE_PREFIX=myprefix_ on the compiler command line. ** ** 2006-10-31: The default prefix used to be "sqlite_". But then ** Mcafee started using SQLite in their anti-virus product and it ** started putting files with the "sqlite" name in the c:/temp folder. ** This annoyed many windows users. Those users would then do a ** Google search for "sqlite", find the telephone numbers of the ** developers and call to wake them up at night and complain. ** For this reason, the default name prefix is changed to be "sqlite" ** spelled backwards. So the temp files are still identified, but ** anybody smart enough to figure out the code is also likely smart ** enough to know that calling the developer will not help get rid ** of the file. */ #ifndef SQLITE_TEMP_FILE_PREFIX # define SQLITE_TEMP_FILE_PREFIX "etilqs_" #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. */ |
︙ | ︙ | |||
269 270 271 272 273 274 275 276 | int sqlite3OsCloseFree(sqlite3_file *); #if defined(SQLITE_TEST) || defined(SQLITE_DEBUG) int sqlite3OsFileHandle(sqlite3_file *id); int sqlite3OsLockState(sqlite3_file *id); #endif #endif /* _SQLITE_OS_H_ */ | > > > > > > > > > > > > > > | 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 | int sqlite3OsCloseFree(sqlite3_file *); #if defined(SQLITE_TEST) || defined(SQLITE_DEBUG) int sqlite3OsFileHandle(sqlite3_file *id); int sqlite3OsLockState(sqlite3_file *id); #endif /* ** Each OS-specific backend defines an instance of the following ** structure for returning a pointer to its sqlite3_vfs. If OS_OTHER ** is defined (meaning that the application-defined OS interface layer ** is used) then there is no default VFS. The application must ** register one or more VFS structures using sqlite3_vfs_register() ** before attempting to use SQLite. */ #if OS_UNIX || OS_WIN || OS_OS2 sqlite3_vfs *sqlite3OsDefaultVfs(void); #else # define sqlite3OsDefaultVfs(X) 0 #endif #endif /* _SQLITE_OS_H_ */ |
Changes to src/os_unix.c.
︙ | ︙ | |||
104 105 106 107 108 109 110 | }; /* ** Include code that is common to all os_*.c files */ #include "os_common.h" | < < < < < < < | 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | }; /* ** Include code that is common to all os_*.c files */ #include "os_common.h" /* ** Define various macros that are missing from some systems. */ #ifndef O_LARGEFILE # define O_LARGEFILE 0 #endif #ifdef SQLITE_DISABLE_LFS |
︙ | ︙ | |||
2296 2297 2298 2299 2300 2301 2302 | pNew->pMethod = &sqlite3UnixIoMethod; OpenCounter(+1); return SQLITE_OK; } #endif /* SQLITE_ENABLE_LOCKING_STYLE */ | < < < < < < < | | 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 | pNew->pMethod = &sqlite3UnixIoMethod; OpenCounter(+1); return SQLITE_OK; } #endif /* SQLITE_ENABLE_LOCKING_STYLE */ /* ** Open a file descriptor to the directory containing file zFilename. ** If successful, *pFd is set to the opened file descriptor and ** SQLITE_OK is returned. If an error occurs, either SQLITE_NOMEM ** or SQLITE_CANTOPEN is returned and *pFd is set to an undefined ** value. ** ** If SQLITE_OK is returned, the caller is responsible for closing ** the file descriptor *pFd using close(). */ static int openDirectory(const char *zFilename, int *pFd){ int ii; int fd; char zDirname[MAX_PATHNAME+1]; sqlite3_snprintf(MAX_PATHNAME, zDirname, "%s", zFilename); for(ii=strlen(zDirname); ii>=0 && zDirname[ii]!='/'; ii--); if( ii>0 ){ zDirname[ii] = '\0'; fd = open(zDirname, O_RDONLY|O_BINARY, 0); if( fd>0 ){ #ifdef FD_CLOEXEC fcntl(fd, F_SETFD, fcntl(fd, F_GETFD, 0) | FD_CLOEXEC); |
︙ | ︙ | |||
2357 2358 2359 2360 2361 2362 2363 | ** The old OpenExclusive() accepted a boolean argument - "delFlag". If ** true, the file was configured to be automatically deleted when the ** file handle closed. To achieve the same effect using this new ** interface, add the DELETEONCLOSE flag to those specified above for ** OpenExclusive(). */ static int unixOpen( | | | 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 | ** The old OpenExclusive() accepted a boolean argument - "delFlag". If ** true, the file was configured to be automatically deleted when the ** file handle closed. To achieve the same effect using this new ** interface, add the DELETEONCLOSE flag to those specified above for ** OpenExclusive(). */ static int unixOpen( sqlite3_vfs *pVfs, const char *zPath, sqlite3_file *pFile, int flags, int *pOutFlags ){ int fd = 0; /* File descriptor returned by open() */ int dirfd = -1; /* Directory file descriptor */ |
︙ | ︙ | |||
2410 2411 2412 2413 2414 2415 2416 | memset(pFile, 0, sizeof(unixFile)); fd = open(zPath, oflags, isDelete?0600:SQLITE_DEFAULT_FILE_PERMISSIONS); if( fd<0 && isReadWrite && !isExclusive ){ /* Failed to open the file for read/write access. Try read-only. */ flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); flags |= SQLITE_OPEN_READONLY; | | | 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 | memset(pFile, 0, sizeof(unixFile)); fd = open(zPath, oflags, isDelete?0600:SQLITE_DEFAULT_FILE_PERMISSIONS); if( fd<0 && isReadWrite && !isExclusive ){ /* Failed to open the file for read/write access. Try read-only. */ flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); flags |= SQLITE_OPEN_READONLY; return unixOpen(pVfs, zPath, pFile, flags, pOutFlags); } if( fd<0 ){ return SQLITE_CANTOPEN; } if( isDelete ){ unlink(zPath); } |
︙ | ︙ | |||
2437 2438 2439 2440 2441 2442 2443 | return fillInUnixFile(fd, dirfd, pFile, zPath); } /* ** Delete the file at zPath. If the dirSync argument is true, fsync() ** the directory after deleting the file. */ | | | 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 | return fillInUnixFile(fd, dirfd, pFile, zPath); } /* ** Delete the file at zPath. If the dirSync argument is true, fsync() ** the directory after deleting the file. */ static int unixDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ int rc = SQLITE_OK; SimulateIOError(return SQLITE_IOERR_DELETE); unlink(zPath); if( dirSync ){ int fd; rc = openDirectory(zPath, &fd); if( rc==SQLITE_OK ){ |
︙ | ︙ | |||
2464 2465 2466 2467 2468 2469 2470 | ** ** SQLITE_ACCESS_EXISTS: Return 1 if the file exists ** SQLITE_ACCESS_READWRITE: Return 1 if the file is read and writable. ** SQLITE_ACCESS_READONLY: Return 1 if the file is readable. ** ** Otherwise return 0. */ | | | | > | | 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 | ** ** SQLITE_ACCESS_EXISTS: Return 1 if the file exists ** SQLITE_ACCESS_READWRITE: Return 1 if the file is read and writable. ** SQLITE_ACCESS_READONLY: Return 1 if the file is readable. ** ** Otherwise return 0. */ static int unixAccess(sqlite3_vfs *pVfs, const char *zPath, int flags){ int amode; switch( flags ){ case SQLITE_ACCESS_EXISTS: amode = F_OK; break; case SQLITE_ACCESS_READWRITE: amode = W_OK|R_OK; break; case SQLITE_ACCESS_READONLY: amode = R_OK; break; default: assert(!"Invalid flags argument"); } return (access(zPath, amode)==0); } /* ** Create a temporary file name in zBuf. zBuf must be allocated ** by the calling process and must be big enough to hold at least ** pVfs->mxPathname bytes. */ static int unixGetTempName(sqlite3_vfs *pVfs, char *zBuf){ static const char *azDirs[] = { 0, "/var/tmp", "/usr/tmp", "/tmp", ".", }; |
︙ | ︙ | |||
2512 2513 2514 2515 2516 2517 2518 | if( stat(azDirs[i], &buf) ) continue; if( !S_ISDIR(buf.st_mode) ) continue; if( access(azDirs[i], 07) ) continue; zDir = azDirs[i]; break; } do{ | > | | > | | < | 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 | if( stat(azDirs[i], &buf) ) continue; if( !S_ISDIR(buf.st_mode) ) continue; if( access(azDirs[i], 07) ) continue; zDir = azDirs[i]; break; } do{ assert( pVfs->mxPathname==MAX_PATHNAME ); sqlite3_snprintf(MAX_PATHNAME-17, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX, zDir); j = strlen(zBuf); sqlite3Randomness(15, &zBuf[j]); for(i=0; i<15; i++, j++){ zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; } zBuf[j] = 0; }while( access(zBuf,0)==0 ); return SQLITE_OK; } /* ** Turn a relative pathname into a full pathname. The relative path ** is stored as a nul-terminated string in the buffer pointed to by ** zPath. ** ** zOut points to a buffer of at least sqlite3_vfs.mxPathname bytes ** (in this case, MAX_PATHNAME bytes). The full-path is written to ** this buffer before returning. */ static int unixFullPathname(sqlite3_vfs *pVfs, const char *zPath, char *zOut){ assert( pVfs->mxPathname==MAX_PATHNAME ); zOut[MAX_PATHNAME-1] = '\0'; if( zPath[0]=='/' ){ sqlite3_snprintf(MAX_PATHNAME, zOut, "%s", zPath); }else{ int nCwd; if( getcwd(zOut, MAX_PATHNAME-1)==0 ){ return SQLITE_ERROR; } nCwd = strlen(zOut); sqlite3_snprintf(MAX_PATHNAME-nCwd, &zOut[nCwd], "/%s", zPath); } return SQLITE_OK; #if 0 /* ** Remove "/./" path elements and convert "/A/./" path elements ** to just "/". |
︙ | ︙ | |||
2582 2583 2584 2585 2586 2587 2588 | #ifndef SQLITE_OMIT_LOAD_EXTENSION /* ** Interfaces for opening a shared library, finding entry points ** within the shared library, and closing the shared library. */ #include <dlfcn.h> | | | | < | | | | 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 | #ifndef SQLITE_OMIT_LOAD_EXTENSION /* ** Interfaces for opening a shared library, finding entry points ** within the shared library, and closing the shared library. */ #include <dlfcn.h> static void *unixDlOpen(sqlite3_vfs *pVfs, const char *zFilename){ return dlopen(zFilename, RTLD_NOW | RTLD_GLOBAL); } static void unixDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){ char *zErr; enterMutex(); zErr = dlerror(); if( zErr ){ sqlite3_snprintf(nBuf, zBufOut, "%s", zErr); }else if(nBuf>0) { zBufOut[0] = '\0'; } leaveMutex(); } void *unixDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){ return dlsym(pHandle, zSymbol); } void unixDlClose(sqlite3_vfs *pVfs, void *pHandle){ dlclose(pHandle); } #else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */ #define unixDlOpen 0 #define unixDlError 0 #define unixDlSym 0 #define unixDlClose 0 #endif /* ** Write nBuf bytes of random data to the supplied buffer zBuf. */ static int unixRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ assert(nBuf>=(sizeof(time_t)+sizeof(int))); /* 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 |
︙ | ︙ | |||
2658 2659 2660 2661 2662 2663 2664 | ** Sleep for a little while. Return the amount of time slept. ** The argument is the number of microseconds we want to sleep. ** The return value is the number of microseconds of sleep actually ** requested from the underlying operating system, a number which ** might be greater than or equal to the argument, but not less ** than the argument. */ | | | 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 | ** Sleep for a little while. Return the amount of time slept. ** The argument is the number of microseconds we want to sleep. ** The return value is the number of microseconds of sleep actually ** requested from the underlying operating system, a number which ** might be greater than or equal to the argument, but not less ** than the argument. */ static int unixSleep(sqlite3_vfs *pVfs, int microseconds){ #if defined(HAVE_USLEEP) && HAVE_USLEEP usleep(microseconds); return microseconds; #else int seconds = (microseconds+999999)/1000000; sleep(seconds); return seconds*1000000; |
︙ | ︙ | |||
2682 2683 2684 2685 2686 2687 2688 | #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. */ | | | > > > > > > | | | | | | | | | | | | | | | | | | | | | | | | > > > | 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 | #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. */ static int unixCurrentTime(sqlite3_vfs *pVfs, double *prNow){ #ifdef NO_GETTOD time_t t; time(&t); *prNow = t/86400.0 + 2440587.5; #else struct timeval sNow; gettimeofday(&sNow, 0); *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; } /* ** Return a pointer to the sqlite3DefaultVfs structure. We use ** a function rather than give the structure global scope because ** some compilers (MSVC) do not allow forward declarations of ** initialized structures. */ sqlite3_vfs *sqlite3OsDefaultVfs(void){ static sqlite3_vfs unixVfs = { 1, /* iVersion */ sizeof(unixFile), /* szOsFile */ MAX_PATHNAME, /* mxPathname */ 0, /* nRef */ 0, /* vfsMutex */ 0, /* pNext */ "unix", /* zName */ 0, /* pAppData */ unixOpen, /* xOpen */ unixDelete, /* xDelete */ unixAccess, /* xAccess */ unixGetTempName, /* xGetTempName */ unixFullPathname, /* xFullPathname */ unixDlOpen, /* xDlOpen */ unixDlError, /* xDlError */ unixDlSym, /* xDlSym */ unixDlClose, /* xDlClose */ unixRandomness, /* xRandomness */ unixSleep, /* xSleep */ unixCurrentTime /* xCurrentTime */ }; return &unixVfs; } #endif /* OS_UNIX */ |
Changes to src/os_win.c.
︙ | ︙ | |||
54 55 56 57 58 59 60 | BOOL bPending; /* Indicates a pending lock has been obtained */ BOOL bReserved; /* Indicates a reserved lock has been obtained */ BOOL bExclusive; /* Indicates an exclusive lock has been obtained */ } winceLock; #endif /* | | | < < < < < < < > > > > | 54 55 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 99 100 101 102 103 | BOOL bPending; /* Indicates a pending lock has been obtained */ BOOL bReserved; /* Indicates a reserved lock has been obtained */ BOOL bExclusive; /* Indicates an exclusive lock has been obtained */ } winceLock; #endif /* ** The winFile structure is a subclass of sqlite3_file* specific to the win32 ** portability layer. */ typedef struct winFile winFile; struct winFile { const sqlite3_io_methods *pMethod;/* Must be first */ HANDLE h; /* Handle for accessing the file */ unsigned char locktype; /* Type of lock currently held on this file */ short sharedLockByte; /* Randomly chosen byte used as a shared lock */ #if OS_WINCE WCHAR *zDeleteOnClose; /* Name of file to delete when closing */ HANDLE hMutex; /* Mutex used to control access to shared lock */ HANDLE hShared; /* Shared memory segment used for locking */ winceLock local; /* Locks obtained by this instance of winFile */ winceLock *shared; /* Global shared lock memory for the file */ #endif }; /* ** The following variable is (normally) set once and never changes ** thereafter. It records whether the operating system is Win95 ** or WinNT. ** ** 0: Operating system unknown. ** 1: Operating system is Win95. ** 2: Operating system is WinNT. ** ** In order to facilitate testing on a WinNT system, the test fixture ** can manually set this value to 1 to emulate Win98 behavior. */ #ifdef SQLITE_TEST int sqlite3_os_type = 0; #else static int sqlite3_os_type = 0; #endif /* ** Return true (non-zero) if we are running under WinNT, Win2K, WinXP, ** or WinCE. Return false (zero) for Win95, Win98, or WinME. ** ** Here is an interesting observation: Win95, Win98, and WinME lack ** the LockFileEx() API. But we can still statically link against that |
︙ | ︙ | |||
122 123 124 125 126 127 128 | return sqlite3_os_type==2; } #endif /* OS_WINCE */ /* ** Convert a UTF-8 string to microsoft unicode (UTF-16?). ** | | | | | | | | | | | | | | | | | | 119 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 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 | return sqlite3_os_type==2; } #endif /* OS_WINCE */ /* ** Convert a UTF-8 string to microsoft unicode (UTF-16?). ** ** Space to hold the returned string is obtained from sqlite3_malloc. */ static WCHAR *utf8ToUnicode(const char *zFilename){ int nChar; WCHAR *zWideFilename; nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0); zWideFilename = sqlite3_malloc( nChar*sizeof(zWideFilename[0]) ); if( zWideFilename==0 ){ return 0; } nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, nChar); if( nChar==0 ){ sqlite3_free(zWideFilename); zWideFilename = 0; } return zWideFilename; } /* ** Convert microsoft unicode to UTF-8. Space to hold the returned string is ** obtained from sqlite3_malloc(). */ static char *unicodeToUtf8(const WCHAR *zWideFilename){ int nByte; char *zFilename; nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0); zFilename = sqlite3_malloc( nByte ); if( zFilename==0 ){ return 0; } nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte, 0, 0); if( nByte == 0 ){ sqlite3_free(zFilename); zFilename = 0; } return zFilename; } /* ** Convert an ansi string to microsoft unicode, based on the ** current codepage settings for file apis. ** ** Space to hold the returned string is obtained ** from sqlite3_malloc. */ static WCHAR *mbcsToUnicode(const char *zFilename){ int nByte; WCHAR *zMbcsFilename; int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP; nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, NULL,0)*sizeof(WCHAR); zMbcsFilename = sqlite3_malloc( nByte*sizeof(zMbcsFilename[0]) ); if( zMbcsFilename==0 ){ return 0; } nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename, nByte); if( nByte==0 ){ sqlite3_free(zMbcsFilename); zMbcsFilename = 0; } return zMbcsFilename; } /* ** Convert microsoft unicode to multibyte character string, based on the ** user's Ansi codepage. ** ** Space to hold the returned string is obtained from ** sqlite3_malloc(). */ static char *unicodeToMbcs(const WCHAR *zWideFilename){ int nByte; char *zFilename; int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP; nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0); zFilename = sqlite3_malloc( nByte ); if( zFilename==0 ){ return 0; } nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, zFilename, nByte, 0, 0); if( nByte == 0 ){ sqlite3_free(zFilename); zFilename = 0; } return zFilename; } /* ** Convert multibyte character string to UTF-8. Space to hold the ** returned string is obtained from sqlite3_malloc(). */ static char *mbcsToUtf8(const char *zFilename){ char *zFilenameUtf8; WCHAR *zTmpWide; zTmpWide = mbcsToUnicode(zFilename); if( zTmpWide==0 ){ return 0; } zFilenameUtf8 = unicodeToUtf8(zTmpWide); sqlite3_free(zTmpWide); return zFilenameUtf8; } /* ** Convert UTF-8 to multibyte character string. Space to hold the ** returned string is obtained from sqlite3_malloc(). */ static char *utf8ToMbcs(const char *zFilename){ char *zFilenameMbcs; WCHAR *zTmpWide; zTmpWide = utf8ToUnicode(zFilename); if( zTmpWide==0 ){ return 0; } zFilenameMbcs = unicodeToMbcs(zTmpWide); sqlite3_free(zTmpWide); return zFilenameMbcs; } #if OS_WINCE /************************************************************************* ** This section contains code for WinCE only. */ |
︙ | ︙ | |||
324 325 326 327 328 329 330 | for (;*zTok;zTok++){ if (*zTok == '\\') *zTok = '_'; } /* Create/open the named mutex */ pFile->hMutex = CreateMutexW(NULL, FALSE, zName); if (!pFile->hMutex){ | | | 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 | for (;*zTok;zTok++){ if (*zTok == '\\') *zTok = '_'; } /* Create/open the named mutex */ pFile->hMutex = CreateMutexW(NULL, FALSE, zName); if (!pFile->hMutex){ sqlite3_free(zName); return FALSE; } /* Acquire the mutex before continuing */ winceMutexAcquire(pFile->hMutex); /* Since the names of named mutexes, semaphores, file mappings etc are |
︙ | ︙ | |||
346 347 348 349 350 351 352 | /* Set a flag that indicates we're the first to create the memory so it ** must be zero-initialized */ if (GetLastError() == ERROR_ALREADY_EXISTS){ bInit = FALSE; } | | | 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 | /* Set a flag that indicates we're the first to create the memory so it ** must be zero-initialized */ if (GetLastError() == ERROR_ALREADY_EXISTS){ bInit = FALSE; } sqlite3_free(zName); /* If we succeeded in making the shared memory handle, map it. */ if (pFile->hShared){ pFile->shared = (winceLock*)MapViewOfFile(pFile->hShared, FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(winceLock)); /* If mapping failed, close the shared memory handle and erase it */ if (!pFile->shared){ |
︙ | ︙ | |||
405 406 407 408 409 410 411 | /* De-reference and close our copy of the shared memory handle */ UnmapViewOfFile(pFile->shared); CloseHandle(pFile->hShared); if( pFile->zDeleteOnClose ){ DeleteFileW(pFile->zDeleteOnClose); | | | 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 | /* De-reference and close our copy of the shared memory handle */ UnmapViewOfFile(pFile->shared); CloseHandle(pFile->hShared); if( pFile->zDeleteOnClose ){ DeleteFileW(pFile->zDeleteOnClose); sqlite3_free(pFile->zDeleteOnClose); pFile->zDeleteOnClose = 0; } /* Done with the mutex */ winceMutexRelease(pFile->hMutex); CloseHandle(pFile->hMutex); pFile->hMutex = NULL; |
︙ | ︙ | |||
560 561 562 563 564 565 566 | return FALSE; } /* ** End of the special code for wince *****************************************************************************/ #endif /* OS_WINCE */ | < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < | | < | | | | | | < < < > > > > > > > | > > > > > > > > > | > > > > | | > > > > > > > | > | | > > > > > > | | > < < < < < | < < | | | < < < > > | < | | < < < | | | | < < < < < < < < < < < < < < < < < < < < < < | > < | | | | > | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 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 650 651 652 653 654 655 656 657 658 659 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 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 | return FALSE; } /* ** End of the special code for wince *****************************************************************************/ #endif /* OS_WINCE */ /***************************************************************************** ** The next group of routines implement the I/O methods specified ** by the sqlite3_io_methods object. ******************************************************************************/ /* ** Close a file. ** ** It is reported that an attempt to close a handle might sometimes ** fail. This is a very unreasonable result, but windows is notorious ** for being unreasonable so I do not doubt that it might happen. If ** the close fails, we pause for 100 milliseconds and try again. As ** many as MX_CLOSE_ATTEMPT attempts to close the handle are made before ** giving up and returning an error. */ #define MX_CLOSE_ATTEMPT 3 static int winClose(sqlite3_file *id){ int rc, cnt = 0; winFile *pFile = (winFile*)id; OSTRACE2("CLOSE %d\n", pFile->h); do{ rc = CloseHandle(pFile->h); }while( rc==0 && cnt++ < MX_CLOSE_ATTEMPT && (Sleep(100), 1) ); #if OS_WINCE winceDestroyLock(pFile); #endif OpenCounter(-1); return rc ? SQLITE_OK : SQLITE_IOERR; } /* ** Some microsoft compilers lack this definition. */ #ifndef INVALID_SET_FILE_POINTER # define INVALID_SET_FILE_POINTER ((DWORD)-1) #endif /* ** Read data from a file into a buffer. Return SQLITE_OK if all ** bytes were read successfully and SQLITE_IOERR if anything goes ** wrong. */ static int winRead( sqlite3_file *id, /* File to read from */ void *pBuf, /* Write content into this buffer */ int amt, /* Number of bytes to read */ sqlite3_int64 offset /* Begin reading at this offset */ ){ LONG upperBits = (offset>>32) & 0x7fffffff; LONG lowerBits = offset & 0xffffffff; DWORD rc; DWORD got; winFile *pFile = (winFile*)id; assert( id!=0 ); SimulateIOError(return SQLITE_IOERR_READ); OSTRACE3("READ %d lock=%d\n", pFile->h, pFile->locktype); rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN); if( rc==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR ){ return SQLITE_FULL; } if( !ReadFile(pFile->h, pBuf, amt, &got, 0) ){ return SQLITE_IOERR_READ; } if( got==(DWORD)amt ){ return SQLITE_OK; }else{ memset(&((char*)pBuf)[got], 0, amt-got); return SQLITE_IOERR_SHORT_READ; } } /* ** Write data from a buffer into a file. Return SQLITE_OK on success ** or some other error code on failure. */ static int winWrite( sqlite3_file *id, /* File to write into */ const void *pBuf, /* The bytes to be written */ int amt, /* Number of bytes to write */ sqlite3_int64 offset /* Offset into the file to begin writing at */ ){ LONG upperBits = (offset>>32) & 0x7fffffff; LONG lowerBits = offset & 0xffffffff; DWORD rc; DWORD wrote; winFile *pFile = (winFile*)id; assert( id!=0 ); SimulateIOError(return SQLITE_IOERR_WRITE); SimulateDiskfullError(return SQLITE_FULL); OSTRACE3("WRITE %d lock=%d\n", pFile->h, pFile->locktype); rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN); if( rc==INVALID_SET_FILE_POINTER && GetLastError()!=NO_ERROR ){ return SQLITE_FULL; } assert( amt>0 ); while( amt>0 && (rc = WriteFile(pFile->h, pBuf, amt, &wrote, 0))!=0 && wrote>0 ){ amt -= wrote; pBuf = &((char*)pBuf)[wrote]; } if( !rc || amt>(int)wrote ){ return SQLITE_FULL; } return SQLITE_OK; } /* ** Truncate an open file to a specified size */ static int winTruncate(sqlite3_file *id, i64 nByte){ LONG upperBits = (nByte>>32) & 0x7fffffff; LONG lowerBits = nByte & 0xffffffff; winFile *pFile = (winFile*)id; OSTRACE3("TRUNCATE %d %lld\n", pFile->h, nByte); SimulateIOError(return SQLITE_IOERR_TRUNCATE); SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN); SetEndOfFile(pFile->h); return SQLITE_OK; } /* ** Make sure all writes to a particular file are committed to disk. */ static int winSync(sqlite3_file *id, int flags){ winFile *pFile = (winFile*)id; OSTRACE3("SYNC %d lock=%d\n", pFile->h, pFile->locktype); if( FlushFileBuffers(pFile->h) ){ return SQLITE_OK; }else{ return SQLITE_IOERR; } } /* ** Determine the current size of a file in bytes */ static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){ winFile *pFile = (winFile*)id; DWORD upperBits, lowerBits; SimulateIOError(return SQLITE_IOERR_FSTAT); lowerBits = GetFileSize(pFile->h, &upperBits); *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits; return SQLITE_OK; } /* ** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems. */ #ifndef LOCKFILE_FAIL_IMMEDIATELY # define LOCKFILE_FAIL_IMMEDIATELY 1 #endif /* ** Acquire a reader lock. ** Different API routines are called depending on whether or not this ** is Win95 or WinNT. */ static int getReadLock(winFile *pFile){ int res; if( isNT() ){ OVERLAPPED ovlp; ovlp.Offset = SHARED_FIRST; ovlp.OffsetHigh = 0; ovlp.hEvent = 0; res = LockFileEx(pFile->h, LOCKFILE_FAIL_IMMEDIATELY, 0, SHARED_SIZE, 0, &ovlp); }else{ int lk; sqlite3Randomness(sizeof(lk), &lk); pFile->sharedLockByte = (lk & 0x7fffffff)%(SHARED_SIZE - 1); res = LockFile(pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0); } return res; } /* ** Undo a readlock */ static int unlockReadLock(winFile *pFile){ int res; if( isNT() ){ res = UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); }else{ res = UnlockFile(pFile->h, SHARED_FIRST + pFile->sharedLockByte, 0, 1, 0); } return res; } /* ** Lock the file with the lock specified by parameter locktype - one ** of the following: ** ** (1) SHARED_LOCK ** (2) RESERVED_LOCK ** (3) PENDING_LOCK |
︙ | ︙ | |||
1203 1204 1205 1206 1207 1208 1209 | ** PENDING -> EXCLUSIVE ** ** This routine will only increase a lock. The winUnlock() routine ** erases all locks at once and returns us immediately to locking level 0. ** It is not possible to lower the locking level one step at a time. You ** must go straight to locking level 0. */ | | | | 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 | ** PENDING -> EXCLUSIVE ** ** This routine will only increase a lock. The winUnlock() routine ** erases all locks at once and returns us immediately to locking level 0. ** It is not possible to lower the locking level one step at a time. You ** must go straight to locking level 0. */ static int winLock(sqlite3_file *id, int locktype){ int rc = SQLITE_OK; /* Return code from subroutines */ int res = 1; /* Result of a windows lock call */ int newLocktype; /* Set pFile->locktype to this value before exiting */ int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */ winFile *pFile = (winFile*)id; assert( pFile!=0 ); OSTRACE5("LOCK %d %d was %d(%d)\n", pFile->h, locktype, pFile->locktype, pFile->sharedLockByte); |
︙ | ︙ | |||
1315 1316 1317 1318 1319 1320 1321 | } /* ** This routine checks if there is a RESERVED lock held on the specified ** file by this or any other process. If such a lock is held, return ** non-zero, otherwise zero. */ | | | 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 | } /* ** This routine checks if there is a RESERVED lock held on the specified ** file by this or any other process. If such a lock is held, return ** non-zero, otherwise zero. */ static int winCheckReservedLock(sqlite3_file *id){ int rc; winFile *pFile = (winFile*)id; assert( pFile!=0 ); if( pFile->locktype>=RESERVED_LOCK ){ rc = 1; OSTRACE3("TEST WR-LOCK %d %d (local)\n", pFile->h, rc); }else{ |
︙ | ︙ | |||
1344 1345 1346 1347 1348 1349 1350 | ** If the locking level of the file descriptor is already at or below ** the requested locking level, this routine is a no-op. ** ** It is not possible for this routine to fail if the second argument ** is NO_LOCK. If the second argument is SHARED_LOCK then this routine ** might return SQLITE_IOERR; */ | | < > | 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 | ** If the locking level of the file descriptor is already at or below ** the requested locking level, this routine is a no-op. ** ** It is not possible for this routine to fail if the second argument ** is NO_LOCK. If the second argument is SHARED_LOCK then this routine ** might return SQLITE_IOERR; */ static int winUnlock(sqlite3_file *id, int locktype){ int type; winFile *pFile = (winFile*)id; int rc = SQLITE_OK; assert( pFile!=0 ); assert( locktype<=SHARED_LOCK ); OSTRACE5("UNLOCK %d to %d was %d(%d)\n", pFile->h, locktype, pFile->locktype, pFile->sharedLockByte); type = pFile->locktype; if( type>=EXCLUSIVE_LOCK ){ UnlockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); |
︙ | ︙ | |||
1375 1376 1377 1378 1379 1380 1381 | UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0); } pFile->locktype = locktype; return rc; } /* | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < | | < < < < < < < | > | | > > > > > > > | | | > < < < < < > > < | < < < < < < < < < < < < < < < < < < < < < < < | | < < < < < > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > | | | > > > > > > > > > > | | | | > > > > > > < < < > | < < < < < < < < < < < < | | > > | | > > < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < | | 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 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 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 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 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 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 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 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 | UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0); } pFile->locktype = locktype; return rc; } /* ** Currently unimplemented */ static int winBreakLock(sqlite3_file *id){ return SQLITE_ERROR; } /* ** Return an integer that indices the type of lock currently held ** by this handle. (Used for testing and analysis only.) */ static int winLockState(sqlite3_file *id){ winFile *pFile = (winFile*)id; return pFile->locktype; } /* ** Return the sector size in bytes of the underlying block device for ** the specified file. This is almost always 512 bytes, but may be ** larger for some devices. ** ** SQLite code assumes this function cannot fail. It also assumes that ** if two files are created in the same file-system directory (i.e. ** a database and it's journal file) that the sector size will be the ** same for both. */ static int winSectorSize(sqlite3_file *id){ return SQLITE_DEFAULT_SECTOR_SIZE; } /* ** Return a vector of device characteristics. */ static int winDeviceCharacteristics(sqlite3_file *id){ return 0; } /* ** This vector defines all the methods that can operate on an ** sqlite3_file for win32. */ static const sqlite3_io_methods winIoMethod = { 1, /* iVersion */ winClose, winRead, winWrite, winTruncate, winSync, winFileSize, winLock, winUnlock, winCheckReservedLock, winBreakLock, winLockState, winSectorSize, winDeviceCharacteristics }; /*************************************************************************** ** Here ends the I/O methods that form the sqlite3_io_methods object. ** ** The next block of code implements the VFS methods. ****************************************************************************/ /* ** Convert a UTF-8 filename into whatever form the underlying ** operating system wants filenames in. Space to hold the result ** is obtained from sqlite3_malloc and must be freed by the calling ** function. */ static void *convertUtf8Filename(const char *zFilename){ void *zConverted = 0; if( isNT() ){ zConverted = utf8ToUnicode(zFilename); }else{ zConverted = utf8ToMbcs(zFilename); } /* caller will handle out of memory */ return zConverted; } /* ** Open a file. */ static int winOpen( sqlite3_vfs *pVfs, /* Not used */ const char *zName, /* Name of the file (UTF-8) */ sqlite3_file *id, /* Write the SQLite file handle here */ int flags, /* Open mode flags */ int *pOutFlags /* Status return flags */ ){ HANDLE h; DWORD dwDesiredAccess; DWORD dwShareMode; DWORD dwCreationDisposition; DWORD dwFlagsAndAttributes = 0; winFile *pFile = (winFile*)id; void *zConverted = convertUtf8Filename(zName); if( zConverted==0 ){ return SQLITE_NOMEM; } if( flags & SQLITE_OPEN_READWRITE ){ dwDesiredAccess = GENERIC_READ | GENERIC_WRITE; }else{ dwDesiredAccess = GENERIC_READ; } if( flags & SQLITE_OPEN_CREATE ){ dwCreationDisposition = OPEN_ALWAYS; }else{ dwCreationDisposition = OPEN_EXISTING; } if( flags & SQLITE_OPEN_MAIN_DB ){ dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; }else{ dwShareMode = 0; } if( flags & (SQLITE_OPEN_TEMP_DB | SQLITE_OPEN_TEMP_JOURNAL | SQLITE_OPEN_SUBJOURNAL) ){ dwFlagsAndAttributes = FILE_ATTRIBUTE_TEMPORARY | FILE_ATTRIBUTE_HIDDEN | FILE_FLAG_DELETE_ON_CLOSE; }else{ dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL; } if( flags & (SQLITE_OPEN_MAIN_DB | SQLITE_OPEN_TEMP_DB) ){ dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS; }else{ dwFlagsAndAttributes |= FILE_FLAG_SEQUENTIAL_SCAN; } if( isNT() ){ h = CreateFileW((WCHAR*)zConverted, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL ); }else{ #if OS_WINCE return SQLITE_NOMEM; #else h = CreateFileA((char*)zConverted, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL ); #endif } if( h==INVALID_HANDLE_VALUE ){ if( flags & SQLITE_OPEN_READWRITE ){ sqlite3_free(zConverted); return winOpen(0, zName, id, ((flags|SQLITE_OPEN_READONLY)&~SQLITE_OPEN_READWRITE), pOutFlags); }else{ return SQLITE_CANTOPEN; } } if( pOutFlags ){ if( flags & SQLITE_OPEN_READWRITE ){ *pOutFlags = SQLITE_OPEN_READWRITE; }else{ *pOutFlags = SQLITE_OPEN_READONLY; } } memset(pFile, 0, sizeof(*pFile)); pFile->pMethod = &winIoMethod; pFile->h = h; #if OS_WINCE if( (flags & (SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB)) == (SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB) && !winceCreateLock(zFilename, &f) ){ CloseHandle(h); sqlite3_free(zConverted); return SQLITE_CANTOPEN; } if( dwFlagsAndAttributes & FILE_FLAG_DELETEONCLOSE ){ pFile->zDeleteOnClose = zConverted; }else #endif { sqlite3_free(zConverted); } return SQLITE_OK; } /* ** Delete the named file. ** ** Note that windows does not allow a file to be deleted if some other ** process has it open. Sometimes a virus scanner or indexing program ** will open a journal file shortly after it is created in order to do ** whatever it is it does. While this other process is holding the ** file open, we will be unable to delete it. To work around this ** problem, we delay 100 milliseconds and try to delete again. Up ** to MX_DELETION_ATTEMPTs deletion attempts are run before giving ** up and returning an error. */ #define MX_DELETION_ATTEMPTS 3 static int winDelete( sqlite3_vfs *pVfs, /* Not used on win32 */ const char *zFilename, /* Name of file to delete */ int syncDir /* Not used on win32 */ ){ int cnt = 0; int rc; void *zConverted = convertUtf8Filename(zFilename); if( zConverted==0 ){ return SQLITE_NOMEM; } SimulateIOError(return SQLITE_IOERR_DELETE); if( isNT() ){ do{ rc = DeleteFileW(zConverted); }while( rc==0 && GetFileAttributesW(zConverted)!=0xffffffff && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) ); }else{ #if OS_WINCE return SQLITE_NOMEM; #else do{ rc = DeleteFileA(zConverted); }while( rc==0 && GetFileAttributesA(zConverted)!=0xffffffff && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) ); #endif } sqlite3_free(zConverted); OSTRACE2("DELETE \"%s\"\n", zFilename); return rc!=0 ? SQLITE_OK : SQLITE_IOERR; } /* ** Check the existance and status of a file. */ static int winAccess( sqlite3_vfs *pVfs, /* Not used on win32 */ const char *zFilename, /* Name of file to check */ int flags /* Type of test to make on this file */ ){ DWORD attr; int rc; void *zConverted = convertUtf8Filename(zFilename); if( zConverted==0 ){ return SQLITE_NOMEM; } if( isNT() ){ attr = GetFileAttributesW((WCHAR*)zConverted); }else{ #if OS_WINCE return SQLITE_NOMEM; #else attr = GetFileAttributesA((char*)zConverted); #endif } sqlite3_free(zConverted); switch( flags ){ case SQLITE_ACCESS_EXISTS: rc = attr!=0xffffffff; break; case SQLITE_ACCESS_READWRITE: rc = (attr & FILE_ATTRIBUTE_READONLY)==0; break; case SQLITE_ACCESS_READONLY: rc = (attr!=0xffffffff) && ((attr & FILE_ATTRIBUTE_READONLY)==1); break; default: assert(!"Invalid flags argument"); } return rc; } /* ** Create a temporary file name in zBuf. zBuf must be big enough to ** hold at pVfs->mxPathname characters. */ static int winGetTempName(sqlite3_vfs *pVfs, char *zBuf){ static char zChars[] = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789"; int i, j; char zTempPath[MAX_PATH+1]; if( sqlite3_temp_directory ){ sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory); }else if( isNT() ){ char *zMulti; WCHAR zWidePath[MAX_PATH]; GetTempPathW(MAX_PATH-30, zWidePath); zMulti = unicodeToUtf8(zWidePath); if( zMulti ){ sqlite3_snprintf(MAX_PATH-30, zTempPath, "%z", zMulti); }else{ return SQLITE_NOMEM; } }else{ char *zUtf8; char zMbcsPath[MAX_PATH]; GetTempPathA(MAX_PATH-30, zMbcsPath); zUtf8 = mbcsToUtf8(zMbcsPath); if( zUtf8 ){ sqlite3_snprintf(MAX_PATH-30, zTempPath, "%z", zUtf8); }else{ return SQLITE_NOMEM; } } for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){} zTempPath[i] = 0; for(;;){ sqlite3_snprintf(pVfs->mxPathname-30, zBuf, "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath); j = strlen(zBuf); sqlite3Randomness(15, &zBuf[j]); for(i=0; i<15; i++, j++){ zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; } zBuf[j] = 0; if( !sqlite3OsAccess(pVfs, zBuf, SQLITE_ACCESS_EXISTS) ) break; } OSTRACE2("TEMP FILENAME: %s\n", zBuf); return SQLITE_OK; } /* ** Turn a relative pathname into a full pathname. Write the full ** pathname into zOut[]. zOut[] will be at least pVfs->mxPathname ** bytes in size. */ static int winFullPathname( sqlite3_vfs *pVfs, const char *zRelative, char *zFull ){ #if defined(__CYGWIN__) cygwin_conv_to_full_win32_path(zRelative, zFull); return SQLITE_OK #endif #if OS_WINCE /* WinCE has no concept of a relative pathname, or so I am told. */ sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zRelative); #endif #if !OS_WINCE && !defined(__CYGWIN__) int nByte; void *zConverted; char *zOut; zConverted = convertUtf8Filename(zRelative); if( isNT() ){ WCHAR *zTemp; nByte = GetFullPathNameW((WCHAR*)zConverted, 0, 0, 0) + 3; zTemp = sqlite3_malloc( nByte*sizeof(zTemp[0]) ); if( zTemp==0 ){ sqlite3_free(zConverted); return SQLITE_NOMEM; } GetFullPathNameW((WCHAR*)zConverted, nByte, zTemp, 0); sqlite3_free(zConverted); zOut = unicodeToUtf8(zTemp); sqlite3_free(zTemp); }else{ char *zTemp; nByte = GetFullPathNameA((char*)zConverted, 0, 0, 0) + 3; zTemp = sqlite3_malloc( nByte*sizeof(zTemp[0]) ); if( zTemp==0 ){ sqlite3_free(zConverted); return SQLITE_NOMEM; } GetFullPathNameA((char*)zConverted, nByte, zTemp, 0); sqlite3_free(zConverted); zOut = mbcsToUtf8(zTemp); sqlite3_free(zTemp); } if( zOut ){ sqlite3_snprintf(pVfs->mxPathname, zFull, "%z", zOut); return SQLITE_OK; }else{ return SQLITE_NOMEM; } #endif } #ifndef SQLITE_OMIT_LOAD_EXTENSION /* ** Interfaces for opening a shared library, finding entry points ** within the shared library, and closing the shared library. */ /* ** Interfaces for opening a shared library, finding entry points ** within the shared library, and closing the shared library. */ static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){ HANDLE h; void *zConverted = convertUtf8Filename(zFilename); if( zConverted==0 ){ return 0; } if( isNT() ){ h = LoadLibraryW((WCHAR*)zConverted); }else{ #if OS_WINCE return 0; #else h = LoadLibraryA((char*)zConverted); #endif } sqlite3_free(zConverted); return (void*)h; } static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){ FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, zBufOut, nBuf-1, 0 ); } void *winDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){ #if OS_WINCE /* The GetProcAddressA() routine is only available on wince. */ return GetProcAddressA((HANDLE)pHandle, zSymbol); #else /* All other windows platforms expect GetProcAddress() to take ** an Ansi string regardless of the _UNICODE setting */ return GetProcAddress((HANDLE)pHandle, zSymbol); #endif } void winDlClose(sqlite3_vfs *pVfs, void *pHandle){ FreeLibrary((HANDLE)pHandle); } #else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */ #define winDlOpen 0 #define winDlError 0 #define winDlSym 0 #define winDlClose 0 #endif /* ** Write up to nBuf bytes of randomness into zBuf. */ static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ if( sizeof(LPSYSTEMTIME)>=nBuf ){ GetSystemTime((LPSYSTEMTIME)zBuf); return sizeof(LPSYSTEMTIME); }else{ return 0; } } /* ** Sleep for a little while. Return the amount of time slept. */ static int winSleep(sqlite3_vfs *pVfs, int microsec){ Sleep((microsec+999)/1000); return ((microsec+999)/1000)*1000; } /* ** The following variable, if set to a non-zero value, becomes the result ** returned from sqlite3OsCurrentTime(). This is used for testing. */ #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 winCurrentTime(sqlite3_vfs *pVfs, double *prNow){ FILETIME ft; /* FILETIME structure is a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5). */ double now; #if OS_WINCE SYSTEMTIME time; |
︙ | ︙ | |||
1683 1684 1685 1686 1687 1688 1689 1690 | if( sqlite3_current_time ){ *prNow = sqlite3_current_time/86400.0 + 2440587.5; } #endif return 0; } /* | > < | > > | < | | < | | | < | | | | < < < < < < < < < < < < < | < < < < | > > | | | | | | | < > | > | < | < < < < < < < < < < < < | < < < | < | | 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 | if( sqlite3_current_time ){ *prNow = sqlite3_current_time/86400.0 + 2440587.5; } #endif return 0; } /* ** Return a pointer to the sqlite3DefaultVfs structure. We use ** a function rather than give the structure global scope because ** some compilers (MSVC) do not allow forward declarations of ** initialized structures. */ sqlite3_vfs *sqlite3OsDefaultVfs(void){ static sqlite3_vfs winVfs = { 1, /* iVersion */ sizeof(winFile), /* szOsFile */ MAX_PATH, /* mxPathname */ 0, /* nRef */ 0, /* vfsMutex */ 0, /* pNext */ "win32", /* zName */ 0, /* pAppData */ winOpen, /* xOpen */ winDelete, /* xDelete */ winAccess, /* xAccess */ winGetTempName, /* xGetTempName */ winFullPathname, /* xFullPathname */ winDlOpen, /* xDlOpen */ winDlError, /* xDlError */ winDlSym, /* xDlSym */ winDlClose, /* xDlClose */ winRandomness, /* xRandomness */ winSleep, /* xSleep */ winCurrentTime /* xCurrentTime */ }; return &winVfs; } #endif /* OS_WIN */ |
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.372 2007/08/24 03:51:34 drh Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" #include <assert.h> #include <string.h> /* |
︙ | ︙ | |||
1869 1870 1871 1872 1873 1874 1875 | Pager **ppPager, /* Return the Pager structure here */ const char *zFilename, /* Name of the database file to open */ int nExtra, /* Extra bytes append to each in-memory page */ int flags /* flags controlling this file */ ){ u8 *pPtr; Pager *pPager = 0; | < | 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 | Pager **ppPager, /* Return the Pager structure here */ const char *zFilename, /* Name of the database file to open */ int nExtra, /* Extra bytes append to each in-memory page */ int flags /* flags controlling this file */ ){ u8 *pPtr; Pager *pPager = 0; int rc = SQLITE_OK; int i; int tempFile = 0; int memDb = 0; int readOnly = 0; int useJournal = (flags & PAGER_OMIT_JOURNAL)==0; int noReadlock = (flags & PAGER_NO_READLOCK)!=0; |
︙ | ︙ | |||
1901 1902 1903 1904 1905 1906 1907 | pPager->stfd = (sqlite3_file*)&pPtr[pVfs->szOsFile*1]; pPager->jfd = (sqlite3_file*)&pPtr[pVfs->szOsFile*2]; pPager->zFilename = (char*)&pPtr[pVfs->szOsFile*2+journalFileSize]; pPager->zDirectory = &pPager->zFilename[pVfs->mxPathname]; pPager->zJournal = &pPager->zDirectory[pVfs->mxPathname]; pPager->pVfs = pVfs; | | < | 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 | pPager->stfd = (sqlite3_file*)&pPtr[pVfs->szOsFile*1]; pPager->jfd = (sqlite3_file*)&pPtr[pVfs->szOsFile*2]; pPager->zFilename = (char*)&pPtr[pVfs->szOsFile*2+journalFileSize]; pPager->zDirectory = &pPager->zFilename[pVfs->mxPathname]; pPager->zJournal = &pPager->zDirectory[pVfs->mxPathname]; pPager->pVfs = pVfs; /* Open the pager file. */ if( zFilename && zFilename[0] ){ #ifndef SQLITE_OMIT_MEMORYDB if( strcmp(zFilename,":memory:")==0 ){ memDb = 1; pPager->zFilename[0] = '\0'; }else |
︙ | ︙ | |||
1938 1939 1940 1941 1942 1943 1944 | pPager->state = PAGER_EXCLUSIVE; } if( pPager && rc==SQLITE_OK ){ pPager->pTmpSpace = (char *)sqlite3_malloc(SQLITE_DEFAULT_PAGE_SIZE); } | | | | | | | 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 | pPager->state = PAGER_EXCLUSIVE; } if( pPager && rc==SQLITE_OK ){ pPager->pTmpSpace = (char *)sqlite3_malloc(SQLITE_DEFAULT_PAGE_SIZE); } /* If an error occured in either of the blocks above. ** Free the Pager structure and close the file. ** Since the pager is not allocated there is no need to set ** any Pager.errMask variables. */ if( !pPager || !pPager->pTmpSpace ){ sqlite3OsClose(pPager->fd); sqlite3_free(pPager); return ((rc==SQLITE_OK)?SQLITE_NOMEM:rc); } PAGERTRACE3("OPEN %d %s\n", FILEHANDLEID(pPager->fd), pPager->zFilename); IOTRACE(("OPEN %p %s\n", pPager, pPager->zFilename)) /* Fill in Pager.zDirectory[] */ memcpy(pPager->zDirectory, pPager->zFilename, pVfs->mxPathname); for(i=strlen(pPager->zDirectory); i>0 && pPager->zDirectory[i-1]!='/'; i--){} if( i>0 ) pPager->zDirectory[i-1] = 0; /* Fill in Pager.zJournal[] */ |
︙ | ︙ | |||
2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 | /* ** Given a list of pages (connected by the PgHdr.pDirty pointer) write ** every one of those pages out to the database file and mark them all ** as clean. */ static int pager_write_pagelist(PgHdr *pList){ Pager *pPager; int rc; if( pList==0 ) return SQLITE_OK; pPager = pList->pPager; /* At this point there may be either a RESERVED or EXCLUSIVE lock on the ** database file. If there is already an EXCLUSIVE lock, the following | > | 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 | /* ** Given a list of pages (connected by the PgHdr.pDirty pointer) write ** every one of those pages out to the database file and mark them all ** as clean. */ static int pager_write_pagelist(PgHdr *pList){ Pager *pPager; PgHdr *p; int rc; if( pList==0 ) return SQLITE_OK; pPager = pList->pPager; /* At this point there may be either a RESERVED or EXCLUSIVE lock on the ** database file. If there is already an EXCLUSIVE lock, the following |
︙ | ︙ | |||
2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 | */ rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK); if( rc!=SQLITE_OK ){ return rc; } pList = sort_pagelist(pList); while( pList ){ /* If the file has not yet been opened, open it now. */ if( !pPager->fd->pMethods ){ assert(pPager->tempFile); rc = sqlite3PagerOpentemp(pPager->pVfs, pPager->fd, pPager->zFilename); if( rc ) return rc; } | > > > > < | 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 | */ rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK); if( rc!=SQLITE_OK ){ return rc; } pList = sort_pagelist(pList); for(p=pList; p; p=p->pDirty){ assert( p->dirty ); p->dirty = 0; } while( pList ){ /* If the file has not yet been opened, open it now. */ if( !pPager->fd->pMethods ){ assert(pPager->tempFile); rc = sqlite3PagerOpentemp(pPager->pVfs, pPager->fd, pPager->zFilename); if( rc ) return rc; } /* If there are dirty pages in the page cache with page numbers greater ** than Pager.dbSize, this means sqlite3PagerTruncate() was called to ** make the file smaller (presumably by auto-vacuum code). Do not write ** any such pages to the file. */ if( pList->pgno<=pPager->dbSize ){ i64 offset = (pList->pgno-1)*(i64)pPager->pageSize; |
︙ | ︙ | |||
2739 2740 2741 2742 2743 2744 2745 | } #ifndef NDEBUG else{ PAGERTRACE3("NOSTORE %d page %d\n", PAGERID(pPager), pList->pgno); } #endif if( rc ) return rc; | < | 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 | } #ifndef NDEBUG else{ PAGERTRACE3("NOSTORE %d page %d\n", PAGERID(pPager), pList->pgno); } #endif if( rc ) return rc; #ifdef SQLITE_CHECK_PAGES pList->pageHash = pager_pagehash(pList); #endif pList = pList->pDirty; } return SQLITE_OK; } |
︙ | ︙ | |||
2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 | if( pPg->dirty ){ int rc; assert( pPg->needSync==0 ); makeClean(pPg); pPg->dirty = 1; pPg->pDirty = 0; rc = pager_write_pagelist( pPg ); if( rc!=SQLITE_OK ){ return rc; } } assert( pPg->dirty==0 ); /* If the page we are recycling is marked as alwaysRollback, then | > | 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 | if( pPg->dirty ){ int rc; assert( pPg->needSync==0 ); makeClean(pPg); pPg->dirty = 1; pPg->pDirty = 0; rc = pager_write_pagelist( pPg ); pPg->dirty = 0; if( rc!=SQLITE_OK ){ return rc; } } assert( pPg->dirty==0 ); /* If the page we are recycling is marked as alwaysRollback, then |
︙ | ︙ | |||
3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 | ** Make a page clean. Clear its dirty bit and remove it from the ** dirty page list. */ static void makeClean(PgHdr *pPg){ if( pPg->dirty ){ pPg->dirty = 0; if( pPg->pDirty ){ pPg->pDirty->pPrevDirty = pPg->pPrevDirty; } if( pPg->pPrevDirty ){ pPg->pPrevDirty->pDirty = pPg->pDirty; }else{ pPg->pPager->pDirty = pPg->pDirty; } } } /* | > > > | 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 | ** Make a page clean. Clear its dirty bit and remove it from the ** dirty page list. */ static void makeClean(PgHdr *pPg){ if( pPg->dirty ){ pPg->dirty = 0; if( pPg->pDirty ){ assert( pPg->pDirty->pPrevDirty==pPg ); pPg->pDirty->pPrevDirty = pPg->pPrevDirty; } if( pPg->pPrevDirty ){ assert( pPg->pPrevDirty->pDirty==pPg ); pPg->pPrevDirty->pDirty = pPg->pDirty; }else{ assert( pPg->pPager->pDirty==pPg ); pPg->pPager->pDirty = pPg->pDirty; } } } /* |
︙ | ︙ | |||
4259 4260 4261 4262 4263 4264 4265 | if( rc!=SQLITE_OK ) goto sync_exit; } #endif /* Write all dirty pages to the database file */ pPg = pager_get_all_dirty_pages(pPager); rc = pager_write_pagelist(pPg); | | > > > > | 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 | if( rc!=SQLITE_OK ) goto sync_exit; } #endif /* Write all dirty pages to the database file */ pPg = pager_get_all_dirty_pages(pPager); rc = pager_write_pagelist(pPg); if( rc!=SQLITE_OK ){ while( pPg && !pPg->dirty ){ pPg = pPg->pDirty; } pPager->pDirty = pPg; goto sync_exit; } pPager->pDirty = 0; /* Sync the database file. */ if( !pPager->noSync ){ rc = sqlite3OsSync(pPager->fd, pPager->sync_flags); } IOTRACE(("DBSYNC %p\n", pPager)) |
︙ | ︙ |
Changes to src/printf.c.
︙ | ︙ | |||
109 110 111 112 113 114 115 | */ static const char aDigits[] = "0123456789ABCDEF0123456789abcdef"; static const char aPrefix[] = "-x0\000X0"; static const et_info fmtinfo[] = { { 'd', 10, 1, etRADIX, 0, 0 }, { 's', 0, 4, etSTRING, 0, 0 }, { 'g', 0, 1, etGENERIC, 30, 0 }, | | | 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | */ static const char aDigits[] = "0123456789ABCDEF0123456789abcdef"; static const char aPrefix[] = "-x0\000X0"; static const et_info fmtinfo[] = { { 'd', 10, 1, etRADIX, 0, 0 }, { 's', 0, 4, etSTRING, 0, 0 }, { 'g', 0, 1, etGENERIC, 30, 0 }, { 'z', 0, 4, etDYNSTRING, 0, 0 }, { 'q', 0, 4, etSQLESCAPE, 0, 0 }, { 'Q', 0, 4, etSQLESCAPE2, 0, 0 }, { 'w', 0, 4, etSQLESCAPE3, 0, 0 }, { 'c', 0, 0, etCHARX, 0, 0 }, { 'o', 8, 0, etRADIX, 0, 2 }, { 'u', 10, 0, etRADIX, 0, 0 }, { 'x', 16, 0, etRADIX, 16, 1 }, |
︙ | ︙ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
26 27 28 29 30 31 32 | ** on how SQLite interfaces are suppose to operate. ** ** The name of this file under configuration management is "sqlite.h.in". ** The makefile makes some minor changes to this file (such as inserting ** the version number) and changes its name to "sqlite3.h" as ** part of the build process. ** | | | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | ** on how SQLite interfaces are suppose to operate. ** ** The name of this file under configuration management is "sqlite.h.in". ** The makefile makes some minor changes to this file (such as inserting ** the version number) and changes its name to "sqlite3.h" as ** part of the build process. ** ** @(#) $Id: sqlite.h.in,v 1.239 2007/08/24 03:51:34 drh Exp $ */ #ifndef _SQLITE3_H_ #define _SQLITE3_H_ #include <stdarg.h> /* Needed for the definition of va_list */ /* ** Make sure we can call this stuff from C++. |
︙ | ︙ | |||
335 336 337 338 339 340 341 | #define SQLITE_OPEN_READONLY 0x00000001 #define SQLITE_OPEN_READWRITE 0x00000002 #define SQLITE_OPEN_CREATE 0x00000004 #define SQLITE_OPEN_DELETEONCLOSE 0x00000008 #define SQLITE_OPEN_EXCLUSIVE 0x00000010 #define SQLITE_OPEN_MAIN_DB 0x00000100 #define SQLITE_OPEN_TEMP_DB 0x00000200 | | | | | | 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 | #define SQLITE_OPEN_READONLY 0x00000001 #define SQLITE_OPEN_READWRITE 0x00000002 #define SQLITE_OPEN_CREATE 0x00000004 #define SQLITE_OPEN_DELETEONCLOSE 0x00000008 #define SQLITE_OPEN_EXCLUSIVE 0x00000010 #define SQLITE_OPEN_MAIN_DB 0x00000100 #define SQLITE_OPEN_TEMP_DB 0x00000200 #define SQLITE_OPEN_MAIN_JOURNAL 0x00000400 #define SQLITE_OPEN_TEMP_JOURNAL 0x00000800 #define SQLITE_OPEN_SUBJOURNAL 0x00001000 #define SQLITE_OPEN_MASTER_JOURNAL 0x00002000 /* ** CAPI3REF: Device Characteristics ** ** The xDeviceCapabilities method of the [sqlite3_io_methods] ** object returns an integer which is a vector of the following ** bit values expressing I/O characteristics of the mass storage |
︙ | ︙ | |||
420 421 422 423 424 425 426 | ** want to subclass this object by appending additional fields ** of their own use. The pMethods entry is a pointer to an ** [sqlite3_io_methods] object that defines methods for performing ** I/O operations on the open file. */ typedef struct sqlite3_file sqlite3_file; struct sqlite3_file { | | | 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 | ** want to subclass this object by appending additional fields ** of their own use. The pMethods entry is a pointer to an ** [sqlite3_io_methods] object that defines methods for performing ** I/O operations on the open file. */ typedef struct sqlite3_file sqlite3_file; struct sqlite3_file { const struct sqlite3_io_methods *pMethods; /* Methods for an open file */ }; /* ** CAPI3REF: OS Interface File Virtual Methods Object ** ** Every open file in the [sqlite3_vfs] xOpen method contains a pointer to ** an instance of the following object. This object defines the |
︙ | ︙ | |||
548 549 550 551 552 553 554 | ** using sqlite3_mutex_alloc() upon first use of the adaptor ** by sqlite3_open_v2() and will deallocate the mutex when the ** last user closes. In other words, vfsMutex will be allocated ** when nRef transitions from 0 to 1 and will be deallocated when ** nRef transitions from 1 to 0. ** ** Registered vfs modules are kept on a linked list formed by | | | | | 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 | ** using sqlite3_mutex_alloc() upon first use of the adaptor ** by sqlite3_open_v2() and will deallocate the mutex when the ** last user closes. In other words, vfsMutex will be allocated ** when nRef transitions from 0 to 1 and will be deallocated when ** nRef transitions from 1 to 0. ** ** Registered vfs modules are kept on a linked list formed by ** the pNext pointer. The [sqlite3_register_vfs()] ** and [sqlite3_unregister_vfs()] interfaces manage this list ** in a thread-safe way. The [sqlite3_find_vfs()] interface ** searches the list. ** ** The zName field holds the name of the VFS module. The name must ** be unique across all VFS modules. ** ** SQLite will guarantee that the zFilename string passed to ** xOpen() is a full pathname as generated by xFullPathname() and ** that the string will be valid and unchanged until xClose() is |
︙ | ︙ | |||
640 641 642 643 644 645 646 | int szOsFile; /* Size of subclassed sqlite3_file */ int mxPathname; /* Maximum file pathname length */ int nRef; /* Number of references to this structure */ sqlite3_mutex *vfsMutex; /* A mutex for this VFS */ sqlite3_vfs *pNext; /* Next registered VFS */ const char *zName; /* Name of this virtual file system */ void *pAppData; /* Application context */ | | | | | | | | | | | | | | 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 | int szOsFile; /* Size of subclassed sqlite3_file */ int mxPathname; /* Maximum file pathname length */ int nRef; /* Number of references to this structure */ sqlite3_mutex *vfsMutex; /* A mutex for this VFS */ sqlite3_vfs *pNext; /* Next registered VFS */ const char *zName; /* Name of this virtual file system */ void *pAppData; /* Application context */ int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*, int flags, int *pOutFlags); int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir); int (*xAccess)(sqlite3_vfs*, const char *zName, int flags); int (*xGetTempName)(sqlite3_vfs*, char *zOut); int (*xFullPathname)(sqlite3_vfs*, const char *zName, char *zOut); void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename); void (*xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg); void *(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol); void (*xDlClose)(sqlite3_vfs*, void*); int (*xRandomness)(sqlite3_vfs*, int nByte, char *zOut); int (*xSleep)(sqlite3_vfs*, int microseconds); int (*xCurrentTime)(sqlite3_vfs*, double*); /* New fields may be appended in figure versions. The iVersion ** value will increment whenever this happens. */ }; #define SQLITE_ACCESS_EXISTS 0 #define SQLITE_ACCESS_READWRITE 1 #define SQLITE_ACCESS_READONLY 2 |
︙ | ︙ | |||
993 994 995 996 997 998 999 | ** parameter "n" is the total size of the buffer, including space for ** the zero terminator. So the longest string that can be completely ** written will be n-1 characters. ** ** These routines all implement some additional formatting ** options that are useful for constructing SQL statements. ** All of the usual printf formatting options apply. In addition, there | | | 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 | ** parameter "n" is the total size of the buffer, including space for ** the zero terminator. So the longest string that can be completely ** written will be n-1 characters. ** ** These routines all implement some additional formatting ** options that are useful for constructing SQL statements. ** All of the usual printf formatting options apply. In addition, there ** is are "%q", "%Q", and "%z" options. ** ** The %q option works like %s in that it substitutes a null-terminated ** string from the argument list. But %q also doubles every '\'' character. ** %q is designed for use inside a string literal. By doubling each '\'' ** character it escapes that character and allows it to be inserted into ** the string. ** |
︙ | ︙ | |||
1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 | ** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES(%Q)", zText); ** sqlite3_exec(db, zSQL, 0, 0, 0); ** sqlite3_free(zSQL); ** </pre></blockquote> ** ** The code above will render a correct SQL statement in the zSQL ** variable even if the zText variable is a NULL pointer. */ char *sqlite3_mprintf(const char*,...); char *sqlite3_vmprintf(const char*, va_list); char *sqlite3_snprintf(int,char*,const char*, ...); /* ** CAPI3REF: Memory Allocation Subsystem | > > > > | 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 | ** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES(%Q)", zText); ** sqlite3_exec(db, zSQL, 0, 0, 0); ** sqlite3_free(zSQL); ** </pre></blockquote> ** ** The code above will render a correct SQL statement in the zSQL ** variable even if the zText variable is a NULL pointer. ** ** The "%z" formatting option works exactly like "%s" with the ** addition that after the string has been read and copied into ** the result, [sqlite3_free()] is called on the input string. */ char *sqlite3_mprintf(const char*,...); char *sqlite3_vmprintf(const char*, va_list); char *sqlite3_snprintf(int,char*,const char*, ...); /* ** CAPI3REF: Memory Allocation Subsystem |
︙ | ︙ | |||
1088 1089 1090 1091 1092 1093 1094 | ** memory. The highwater mark is reset if the argument is ** true. The SQLite core does not use either of these routines ** and so they do not have to be implemented by the application ** if SQLITE_OMIT_MEMORY_ALLOCATION is defined. These routines ** are provided by the default memory subsystem for diagnostic ** purposes. */ | | | | 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 | ** memory. The highwater mark is reset if the argument is ** true. The SQLite core does not use either of these routines ** and so they do not have to be implemented by the application ** if SQLITE_OMIT_MEMORY_ALLOCATION is defined. These routines ** are provided by the default memory subsystem for diagnostic ** purposes. */ sqlite3_int64 sqlite3_memory_used(void); sqlite3_int64 sqlite3_memory_highwater(int resetFlag); /* ** CAPI3REF: Memory Allocation Alarms ** ** The [sqlite3_memory_alarm] routine is used to register ** a callback on memory allocation events. ** |
︙ | ︙ | |||
1120 1121 1122 1123 1124 1125 1126 | ** a memory alarm at the soft heap limit and invoking ** [sqlite3_release_memory()] in the alarm callback. Application ** programs should not attempt to use the [sqlite3_memory_alarm()] ** interface because doing so will interfere with the ** [sqlite3_soft_heap_limit()] module. */ int sqlite3_memory_alarm( | | | | 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 | ** a memory alarm at the soft heap limit and invoking ** [sqlite3_release_memory()] in the alarm callback. Application ** programs should not attempt to use the [sqlite3_memory_alarm()] ** interface because doing so will interfere with the ** [sqlite3_soft_heap_limit()] module. */ int sqlite3_memory_alarm( void(*xCallback)(void *pArg, sqlite3_int64 used, int N), void *pArg, sqlite3_int64 iThreshold ); /* ** CAPI3REF: Compile-Time Authorization Callbacks *** ** This routine registers a authorizer callback with the SQLite library. |
︙ | ︙ |
Changes to src/test6.c.
︙ | ︙ | |||
674 675 676 677 678 679 680 | void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ int iDelay; const char *zCrashFile; | | | 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 | void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ int iDelay; const char *zCrashFile; int nCrashFile, iDc, iSectorSize; static sqlite3_vfs crashVfs = { 1, /* iVersion */ 0, /* szOsFile */ 0, /* mxPathname */ 0, /* nRef */ 0, /* vfsMutex */ |
︙ | ︙ | |||
699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 | 0, /* xDlError */ 0, /* xDlSym */ 0, /* xDlClose */ cfRandomness, /* xRandomness */ cfSleep, /* xSleep */ cfCurrentTime /* xCurrentTime */ }; if( crashVfs.pAppData==0 ){ sqlite3_vfs *pOriginalVfs = sqlite3_vfs_find(0); crashVfs.xDlError = pOriginalVfs->xDlError; crashVfs.xDlSym = pOriginalVfs->xDlSym; crashVfs.xDlClose = pOriginalVfs->xDlClose; crashVfs.mxPathname = pOriginalVfs->mxPathname; crashVfs.pAppData = (void *)pOriginalVfs; crashVfs.szOsFile = sizeof(CrashFile) + pOriginalVfs->szOsFile; sqlite3_vfs_release(pOriginalVfs); /* sqlite3_vfs_unregister(pOriginalVfs); */ sqlite3_vfs_register(&crashVfs, 1); } | > | | | 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 729 | 0, /* xDlError */ 0, /* xDlSym */ 0, /* xDlClose */ cfRandomness, /* xRandomness */ cfSleep, /* xSleep */ cfCurrentTime /* xCurrentTime */ }; if( crashVfs.pAppData==0 ){ sqlite3_vfs *pOriginalVfs = sqlite3_vfs_find(0); crashVfs.xDlError = pOriginalVfs->xDlError; crashVfs.xDlSym = pOriginalVfs->xDlSym; crashVfs.xDlClose = pOriginalVfs->xDlClose; crashVfs.mxPathname = pOriginalVfs->mxPathname; crashVfs.pAppData = (void *)pOriginalVfs; crashVfs.szOsFile = sizeof(CrashFile) + pOriginalVfs->szOsFile; sqlite3_vfs_release(pOriginalVfs); /* sqlite3_vfs_unregister(pOriginalVfs); */ sqlite3_vfs_register(&crashVfs, 1); } iDc = -1; iSectorSize = -1; if( objc<3 ){ Tcl_WrongNumArgs(interp, 1, objv, "?OPTIONS? DELAY CRASHFILE"); goto error; } zCrashFile = Tcl_GetStringFromObj(objv[objc-1], &nCrashFile); |
︙ | ︙ |
Changes to src/test_malloc.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** This file contains code used to implement test interfaces to the ** memory allocation subsystem. ** | | | 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. ** ************************************************************************* ** ** This file contains code used to implement test interfaces to the ** memory allocation subsystem. ** ** $Id: test_malloc.c,v 1.5 2007/08/24 03:51:34 drh Exp $ */ #include "sqliteInt.h" #include "tcl.h" #include <stdlib.h> #include <string.h> #include <assert.h> |
︙ | ︙ | |||
282 283 284 285 286 287 288 | nFail = sqlite3_memdebug_fail(iFail, iRepeat); } #endif Tcl_SetObjResult(interp, Tcl_NewIntObj(nFail)); return TCL_OK; } | < < < < < < < < < < < < < < < < < < < | 282 283 284 285 286 287 288 289 290 291 292 293 294 295 | nFail = sqlite3_memdebug_fail(iFail, iRepeat); } #endif Tcl_SetObjResult(interp, Tcl_NewIntObj(nFail)); return TCL_OK; } /* ** Usage: sqlite3_memdebug_settitle TITLE ** ** Set a title string stored with each allocation. The TITLE is ** typically the name of the test that was running when the ** allocation occurred. The TITLE is stored with the allocation |
︙ | ︙ | |||
350 351 352 353 354 355 356 | { "sqlite3_realloc", test_realloc }, { "sqlite3_free", test_free }, { "sqlite3_memory_used", test_memory_used }, { "sqlite3_memory_highwater", test_memory_highwater }, { "sqlite3_memdebug_backtrace", test_memdebug_backtrace }, { "sqlite3_memdebug_dump", test_memdebug_dump }, { "sqlite3_memdebug_fail", test_memdebug_fail }, | < | 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 | { "sqlite3_realloc", test_realloc }, { "sqlite3_free", test_free }, { "sqlite3_memory_used", test_memory_used }, { "sqlite3_memory_highwater", test_memory_highwater }, { "sqlite3_memdebug_backtrace", test_memdebug_backtrace }, { "sqlite3_memdebug_dump", test_memdebug_dump }, { "sqlite3_memdebug_fail", test_memdebug_fail }, { "sqlite3_memdebug_settitle", test_memdebug_settitle }, }; int i; for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){ Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, 0, 0); } return TCL_OK; } |
Changes to src/vdbeapi.c.
︙ | ︙ | |||
698 699 700 701 702 703 704 705 706 | int n; if( p!=0 ){ n = sqlite3_column_count(pStmt); if( N<n && N>=0 ){ N += useType*n; ret = xFunc(&p->aColName[N]); | > < | | 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 | int n; if( p!=0 ){ n = sqlite3_column_count(pStmt); if( N<n && N>=0 ){ N += useType*n; sqlite3_mutex_enter(p->db->mutex); ret = xFunc(&p->aColName[N]); /* A malloc may have failed inside of the xFunc() call. If this ** is the case, clear the mallocFailed flag and return NULL. */ if( p->db && p->db->mallocFailed ){ p->db->mallocFailed = 0; ret = 0; } sqlite3_mutex_leave(p->db->mutex); } } return ret; } /* ** Return the name of the Nth column of the result set returned by SQL |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
1003 1004 1005 1006 1007 1008 1009 | ** statement. This is now set at compile time, rather than during ** execution of the vdbe program so that sqlite3_column_count() can ** be called on an SQL statement before sqlite3_step(). */ void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){ Mem *pColName; int n; | < | | 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 | ** statement. This is now set at compile time, rather than during ** execution of the vdbe program so that sqlite3_column_count() can ** be called on an SQL statement before sqlite3_step(). */ void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){ Mem *pColName; int n; releaseMemArray(p->aColName, p->nResColumn*COLNAME_N); sqlite3_free(p->aColName); n = nResColumn*COLNAME_N; p->nResColumn = nResColumn; p->aColName = pColName = (Mem*)sqlite3DbMallocZero(p->db, sizeof(Mem)*n ); if( p->aColName==0 ) return; while( n-- > 0 ){ pColName->flags = MEM_Null; pColName->db = p->db; pColName++; } } /* ** Set the name of the idx'th column to be returned by the SQL statement. ** zName must be a pointer to a nul terminated string. |
︙ | ︙ |
Changes to src/vtab.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2006 June 10 ** ** 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 help implement virtual tables. ** | | > | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | /* ** 2006 June 10 ** ** 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 help implement virtual tables. ** ** $Id: vtab.c,v 1.54 2007/08/24 03:51:34 drh Exp $ */ #ifndef SQLITE_OMIT_VIRTUALTABLE #include "sqliteInt.h" static int createModule( sqlite3 *db, /* Database in which module is registered */ const char *zName, /* Name assigned to this module */ const sqlite3_module *pModule, /* The definition of the module */ void *pAux, /* Context pointer for xCreate/xConnect */ void (*xDestroy)(void *) /* Module destructor function */ ) { int rc, nName; Module *pMod; sqlite3_mutex_enter(db->mutex); nName = strlen(zName); pMod = (Module *)sqlite3DbMallocRaw(db, sizeof(Module) + nName + 1); if( pMod ){ char *zCopy = (char *)(&pMod[1]); memcpy(zCopy, zName, nName+1); pMod->zName = zCopy; pMod->pModule = pModule; pMod->pAux = pAux; pMod->xDestroy = xDestroy; |
︙ | ︙ |
Changes to test/diskfull.test.
︙ | ︙ | |||
8 9 10 11 12 13 14 | # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing for correct handling of disk full # errors. # | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing for correct handling of disk full # errors. # # $Id: diskfull.test,v 1.7 2007/08/24 03:51:34 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl set sqlite_io_error_persist 0 set sqlite_io_error_hit 0 set sqlite_io_error_pending 0 |
︙ | ︙ | |||
109 110 111 112 113 114 115 | # BEGIN; # INSERT INTO t3 VALUES( randstr(100, 100), randstr(100, 100) ); # UPDATE t3 SET a = b; # COMMIT; # } finish_test | < | 109 110 111 112 113 114 115 | # BEGIN; # INSERT INTO t3 VALUES( randstr(100, 100), randstr(100, 100) ); # UPDATE t3 SET a = b; # COMMIT; # } finish_test |