Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Merging local changes to apple-osx |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | apple-osx |
Files: | files | file ages | folders |
SHA1: |
34f0efa2b12e8eb09331768b1524a076 |
User & Date: | adam 2011-06-24 20:47:06.827 |
Context
2011-06-24
| ||
21:47 | Fix the build. (check-in: 97729542d5 user: drh tags: apple-osx) | |
20:47 | Merging local changes to apple-osx (check-in: 34f0efa2b1 user: adam tags: apple-osx) | |
2011-06-23
| ||
17:42 | Pull the last-minute fixes for 3.7.7 into the apple-osx branch. (check-in: 2d4458af59 user: drh tags: apple-osx) | |
Changes
Changes to src/btree.c.
︙ | ︙ | |||
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | ** Enable or disable the shared pager and schema features. ** ** This routine has no effect on existing database connections. ** The shared cache setting effects only future calls to ** sqlite3_open(), sqlite3_open16(), or sqlite3_open_v2(). */ int sqlite3_enable_shared_cache(int enable){ sqlite3GlobalConfig.sharedCacheEnabled = enable; return SQLITE_OK; } #endif #ifdef SQLITE_OMIT_SHARED_CACHE /* | > > > > > > | 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | ** Enable or disable the shared pager and schema features. ** ** This routine has no effect on existing database connections. ** The shared cache setting effects only future calls to ** sqlite3_open(), sqlite3_open16(), or sqlite3_open_v2(). */ int sqlite3_enable_shared_cache(int enable){ #if defined(__APPLE__) && !defined(SQLITE_TEST) && !defined(TH3_COMPATIBILITY) /* Enable global shared cache function for debugging and unit tests, ** but not for release */ return SQLITE_MISUSE; #else sqlite3GlobalConfig.sharedCacheEnabled = enable; return SQLITE_OK; #endif } #endif #ifdef SQLITE_OMIT_SHARED_CACHE /* |
︙ | ︙ | |||
2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 | */ if( page1[19]==2 && pBt->doNotUseWAL==0 ){ int isOpen = 0; rc = sqlite3PagerOpenWal(pBt->pPager, &isOpen); if( rc!=SQLITE_OK ){ goto page1_init_failed; }else if( isOpen==0 ){ releasePage(pPage1); return SQLITE_OK; } rc = SQLITE_NOTADB; } #endif | > > > > > > > > > > > > | 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 | */ if( page1[19]==2 && pBt->doNotUseWAL==0 ){ int isOpen = 0; rc = sqlite3PagerOpenWal(pBt->pPager, &isOpen); if( rc!=SQLITE_OK ){ goto page1_init_failed; }else if( isOpen==0 ){ #ifdef SQLITE_DEFAULT_WAL_SAFETYLEVEL /* Default to specified safety_level for WAL mode */ if( pBt->db!=0 && pBt->db->aDb!=0 ){ sqlite3 *db = pBt->db; if( db->aDb[0].safety_level != SQLITE_DEFAULT_WAL_SAFETYLEVEL) { db->aDb[0].safety_level = SQLITE_DEFAULT_WAL_SAFETYLEVEL; sqlite3PagerSetSafetyLevel(pBt->pPager, SQLITE_DEFAULT_WAL_SAFETYLEVEL, (db->flags&SQLITE_FullFSync)!=0, (db->flags&SQLITE_CkptFullFSync)!=0); } } #endif releasePage(pPage1); return SQLITE_OK; } rc = SQLITE_NOTADB; } #endif |
︙ | ︙ |
Changes to src/main.c.
︙ | ︙ | |||
1793 1794 1795 1796 1797 1798 1799 | newLimit = aHardLimit[limitId]; /* IMP: R-51463-25634 */ } db->aLimit[limitId] = newLimit; } return oldLimit; /* IMP: R-53341-35419 */ } #if defined(SQLITE_ENABLE_AUTO_PROFILE) | > > | > > > | 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 | newLimit = aHardLimit[limitId]; /* IMP: R-51463-25634 */ } db->aLimit[limitId] = newLimit; } return oldLimit; /* IMP: R-53341-35419 */ } #if defined(SQLITE_ENABLE_AUTO_PROFILE) void _sqlite_auto_profile(void *aux, const char *sql, u64 ns); void _sqlite_auto_trace(void *aux, const char *sql); void _sqlite_auto_profile(void *aux, const char *sql, u64 ns) { #pragma unused(aux) fprintf(stderr, "Query: %s\n Execution Time: %llu ms\n", sql, ns / 1000000); } void _sqlite_auto_trace(void *aux, const char *sql) { fprintf(stderr, "TraceSQL(%p): %s\n", aux, sql); } #endif /* ** This function is used to parse both URIs and non-URI filenames passed by the ** user to API functions sqlite3_open() or sqlite3_open_v2(), and for database ** URIs specified as part of ATTACH statements. |
︙ | ︙ | |||
2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 | assert( sizeof(db->aLimit)==sizeof(aHardLimit) ); memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit)); db->autoCommit = 1; db->nextAutovac = -1; db->nextPagesize = 0; db->flags |= SQLITE_ShortColNames | SQLITE_AutoIndex | SQLITE_EnableTrigger #if SQLITE_DEFAULT_FILE_FORMAT<4 | SQLITE_LegacyFileFmt #endif #ifdef SQLITE_ENABLE_LOAD_EXTENSION | SQLITE_LoadExtension #endif #if SQLITE_DEFAULT_RECURSIVE_TRIGGERS | > > > | 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 | assert( sizeof(db->aLimit)==sizeof(aHardLimit) ); memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit)); db->autoCommit = 1; db->nextAutovac = -1; db->nextPagesize = 0; db->flags |= SQLITE_ShortColNames | SQLITE_AutoIndex | SQLITE_EnableTrigger #if SQLITE_DEFAULT_CKPTFULLFSYNC | SQLITE_CkptFullFSync #endif #if SQLITE_DEFAULT_FILE_FORMAT<4 | SQLITE_LegacyFileFmt #endif #ifdef SQLITE_ENABLE_LOAD_EXTENSION | SQLITE_LoadExtension #endif #if SQLITE_DEFAULT_RECURSIVE_TRIGGERS |
︙ | ︙ | |||
2290 2291 2292 2293 2294 2295 2296 2297 2298 | db = 0; }else if( rc!=SQLITE_OK ){ db->magic = SQLITE_MAGIC_SICK; } #if defined(SQLITE_ENABLE_AUTO_PROFILE) if( db && !rc ){ char *envprofile = getenv("SQLITE_AUTO_PROFILE"); if( envprofile!=NULL ){ | > | > > > | 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 | db = 0; }else if( rc!=SQLITE_OK ){ db->magic = SQLITE_MAGIC_SICK; } #if defined(SQLITE_ENABLE_AUTO_PROFILE) if( db && !rc ){ char *envprofile = getenv("SQLITE_AUTO_PROFILE"); char *envtrace = getenv("SQLITE_AUTO_TRACE"); if( envprofile!=NULL ){ sqlite3_profile(db, _sqlite_auto_profile, db); } if( envtrace!=NULL ){ sqlite3_trace(db, _sqlite_auto_trace, db); } } #endif *ppDb = db; #ifdef SQLITE_ENABLE_SQLRR SRRecOpen(db, zFilename, flags); #endif |
︙ | ︙ | |||
2962 2963 2964 2965 2966 2967 2968 | int x = strcmp(zFilename, zParam); zFilename += sqlite3Strlen30(zFilename) + 1; if( x==0 ) return zFilename; zFilename += sqlite3Strlen30(zFilename) + 1; } return 0; } | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 | int x = strcmp(zFilename, zParam); zFilename += sqlite3Strlen30(zFilename) + 1; if( x==0 ) return zFilename; zFilename += sqlite3Strlen30(zFilename) + 1; } return 0; } #if (SQLITE_ENABLE_APPLE_SPI>0) #define SQLITE_FILE_HEADER_LEN 16 #include <fcntl.h> #include "sqlite3_private.h" #include "btreeInt.h" #include <errno.h> #include <sys/param.h> /* Check for a conflicting lock. If one is found, print an this ** on standard output using the format string given and return 1. ** If there are no conflicting locks, return 0. */ static int isLocked( pid_t pid, /* PID to test for lock owner */ int h, /* File descriptor to check */ int type, /* F_RDLCK or F_WRLCK */ unsigned int iOfst, /* First byte of the lock */ unsigned int iCnt, /* Number of bytes in the lock range */ const char *zType /* Type of lock */ ){ struct flock lk; int err; memset(&lk, 0, sizeof(lk)); lk.l_type = type; lk.l_whence = SEEK_SET; lk.l_start = iOfst; lk.l_len = iCnt; if( pid!=SQLITE_LOCKSTATE_ANYPID ){ #ifndef F_GETLKPID # warning F_GETLKPID undefined, _sqlite3_lockstate falling back to F_GETLK err = fcntl(h, F_GETLK, &lk); #else lk.l_pid = pid; err = fcntl(h, F_GETLKPID, &lk); #endif }else{ err = fcntl(h, F_GETLK, &lk); } if( err==(-1) ){ fprintf(stderr, "fcntl(%d) failed: errno=%d\n", h, errno); return -1; } if( lk.l_type!=F_UNLCK && (pid==SQLITE_LOCKSTATE_ANYPID || lk.l_pid==pid) ){ #ifdef SQLITE_DEBUG fprintf(stderr, "%s lock held by %d\n", zType, (int)lk.l_pid); #endif return 1; } return 0; } /* ** Location of locking bytes in the database file */ #ifndef PENDING_BYTE # define PENDING_BYTE (0x40000000) # define RESERVED_BYTE (PENDING_BYTE+1) # define SHARED_FIRST (PENDING_BYTE+2) # define SHARED_SIZE 510 #endif /* PENDING_BYTE */ /* ** Lock locations for shared-memory locks used by WAL mode. */ #ifndef SHM_BASE # define SHM_BASE 120 # define SHM_WRITE SHM_BASE # define SHM_CHECKPOINT (SHM_BASE+1) # define SHM_RECOVER (SHM_BASE+2) # define SHM_READ_FIRST (SHM_BASE+3) # define SHM_READ_SIZE 5 #endif /* SHM_BASE */ /* ** Testing a file path for sqlite locks held by a process ID. ** Returns SQLITE_LOCKSTATE_ON if locks are present on path ** that would prevent writing to the database. ** ** This test only works for lock testing on unix/posix VFS. ** Adapted from tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce */ int _sqlite3_lockstate(const char *path, pid_t pid){ int hDb; /* File descriptor for the open database file */ int hShm; /* File descriptor for WAL shared-memory file */ ssize_t got; /* Bytes read from header */ int isWal; /* True if in WAL mode */ int nLock = 0; /* Number of locks held */ unsigned char aHdr[100]; /* Database header */ /* Open the file at path and make sure we are dealing with a database file */ hDb = open(path, O_RDONLY | O_NOCTTY); if( hDb<0 ){ return SQLITE_LOCKSTATE_ERROR; } assert( (strlen(SQLITE_FILE_HEADER)+1)==SQLITE_FILE_HEADER_LEN ); got = pread(hDb, aHdr, 100, 0); if( got<0 ){ close(hDb); return SQLITE_LOCKSTATE_ERROR; } if( got!=100 || memcmp(aHdr, SQLITE_FILE_HEADER, SQLITE_FILE_HEADER_LEN)!=0 ){ close(hDb); return SQLITE_LOCKSTATE_NOTADB; } /* First check for an exclusive lock */ nLock += isLocked(pid, hDb, F_RDLCK, SHARED_FIRST, SHARED_SIZE, "EXCLUSIVE"); isWal = aHdr[18]==2; if( nLock==0 && isWal==0 ){ /* Rollback mode */ nLock += isLocked(pid, hDb, F_WRLCK, PENDING_BYTE, SHARED_SIZE+2, "PENDING|RESERVED|SHARED"); } close(hDb); if( nLock==0 && isWal!=0 ){ char zShm[MAXPATHLEN]; close(hDb); /* WAL mode */ strlcpy(zShm, path, MAXPATHLEN); strlcat(zShm, "-shm", MAXPATHLEN); hShm = open(zShm, O_RDONLY, 0); if( hShm<0 ){ return SQLITE_LOCKSTATE_OFF; } if( isLocked(pid, hShm, F_RDLCK, SHM_RECOVER, 1, "WAL-RECOVERY") || isLocked(pid, hShm, F_RDLCK, SHM_WRITE, 1, "WAL-WRITE") ){ nLock = 1; } close(hShm); } if( nLock>0 ){ return SQLITE_LOCKSTATE_ON; } return SQLITE_LOCKSTATE_OFF; } #endif /* SQLITE_ENABLE_APPLE_SPI */ |
Changes to src/os.c.
︙ | ︙ | |||
127 128 129 130 131 132 133 134 135 136 137 138 | sqlite3_vfs *pVfs, const char *zPath, sqlite3_file *pFile, int flags, int *pFlagsOut ){ int rc; DO_OS_MALLOC_TEST(0); /* 0x87f3f is a mask of SQLITE_OPEN_ flags that are valid to be passed ** down into the VFS layer. Some SQLITE_OPEN_ flags (for example, ** SQLITE_OPEN_FULLMUTEX or SQLITE_OPEN_SHAREDCACHE) are blocked before ** reaching the VFS. */ | > > > > > > | | 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 | sqlite3_vfs *pVfs, const char *zPath, sqlite3_file *pFile, int flags, int *pFlagsOut ){ int rc; int openFlags; DO_OS_MALLOC_TEST(0); /* 0x87f3f is a mask of SQLITE_OPEN_ flags that are valid to be passed ** down into the VFS layer. Some SQLITE_OPEN_ flags (for example, ** SQLITE_OPEN_FULLMUTEX or SQLITE_OPEN_SHAREDCACHE) are blocked before ** reaching the VFS. */ #if SQLITE_ENABLE_DATA_PROTECTION openFlags = flags & (0x87f3f | SQLITE_OPEN_FILEPROTECTION_MASK); #else openFlags = flags & 0x87f3f; #endif rc = pVfs->xOpen(pVfs, zPath, pFile, openFlags, pFlagsOut); assert( rc==SQLITE_OK || pFile->pMethods==0 ); return rc; } int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ return pVfs->xDelete(pVfs, zPath, dirSync); } int sqlite3OsAccess( |
︙ | ︙ |
Changes to src/os_unix.c.
︙ | ︙ | |||
121 122 123 124 125 126 127 128 129 130 131 132 133 134 | #include <errno.h> #ifndef SQLITE_OMIT_WAL #include <sys/mman.h> #endif #if SQLITE_ENABLE_LOCKING_STYLE # include <sys/ioctl.h> # if OS_VXWORKS # include <semaphore.h> # include <limits.h> # else # include <sys/file.h> # include <sys/param.h> # endif | > > > > > | 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | #include <errno.h> #ifndef SQLITE_OMIT_WAL #include <sys/mman.h> #endif #if SQLITE_ENABLE_LOCKING_STYLE # include <sys/ioctl.h> # include <uuid/uuid.h> # if defined(__APPLE__) && ((__MAC_OS_X_VERSION_MIN_REQUIRED > 1050) || \ (__IPHONE_OS_VERSION_MIN_REQUIRED > 2000)) # define HAVE_GETHOSTUUID 1 # endif # if OS_VXWORKS # include <semaphore.h> # include <limits.h> # else # include <sys/file.h> # include <sys/param.h> # endif |
︙ | ︙ | |||
216 217 218 219 220 221 222 223 224 225 226 227 228 229 | UnixUnusedFd *pUnused; /* Pre-allocated UnixUnusedFd */ const char *zPath; /* Name of the file */ unixShm *pShm; /* Shared memory segment information */ int szChunk; /* Configured by FCNTL_CHUNK_SIZE */ #if SQLITE_ENABLE_LOCKING_STYLE int openFlags; /* The flags specified at open() */ #endif #if SQLITE_ENABLE_LOCKING_STYLE || defined(__APPLE__) unsigned fsFlags; /* cached details from statfs() */ #endif #if OS_VXWORKS int isDelete; /* Delete on close if true */ struct vxworksFileId *pId; /* Unique file ID */ #endif | > > > | 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 | UnixUnusedFd *pUnused; /* Pre-allocated UnixUnusedFd */ const char *zPath; /* Name of the file */ unixShm *pShm; /* Shared memory segment information */ int szChunk; /* Configured by FCNTL_CHUNK_SIZE */ #if SQLITE_ENABLE_LOCKING_STYLE int openFlags; /* The flags specified at open() */ #endif #if SQLITE_ENABLE_DATA_PROTECTION int protFlags; /* Data protection flags from unixOpen */ #endif #if SQLITE_ENABLE_LOCKING_STYLE || defined(__APPLE__) unsigned fsFlags; /* cached details from statfs() */ #endif #if OS_VXWORKS int isDelete; /* Delete on close if true */ struct vxworksFileId *pId; /* Unique file ID */ #endif |
︙ | ︙ | |||
280 281 282 283 284 285 286 287 288 289 290 291 292 293 | ** testing and debugging only. */ #if SQLITE_THREADSAFE #define threadid pthread_self() #else #define threadid 0 #endif /* ** Different Unix systems declare open() in different ways. Same use ** open(const char*,int,mode_t). Others use open(const char*,int,...). ** The difference is important when using a pointer to the function. ** ** The safest way to deal with the problem is to always use this wrapper | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 | ** testing and debugging only. */ #if SQLITE_THREADSAFE #define threadid pthread_self() #else #define threadid 0 #endif #ifdef __APPLE__ #define SQLITE_ENABLE_SUPERLOCK 1 #endif #if SQLITE_ENABLE_SUPERLOCK #include "sqlite3.h" #include <string.h> /* memset(), strlen() */ #include <assert.h> /* assert() */ /* ** A structure to collect a busy-handler callback and argument and a count ** of the number of times it has been invoked. */ struct SuperlockBusy { int (*xBusy)(void*,int); /* Pointer to busy-handler function */ void *pBusyArg; /* First arg to pass to xBusy */ int nBusy; /* Number of times xBusy has been invoked */ }; typedef struct SuperlockBusy SuperlockBusy; /* ** An instance of the following structure is allocated for each active ** superlock. The opaque handle returned by sqlite3demo_superlock() is ** actually a pointer to an instance of this structure. */ struct Superlock { sqlite3 *db; /* Database handle used to lock db */ int bWal; /* True if db is a WAL database */ }; typedef struct Superlock Superlock; /* ** The pCtx pointer passed to this function is actually a pointer to a ** SuperlockBusy structure. Invoke the busy-handler function encapsulated ** by the structure and return the result. */ static int superlockBusyHandler(void *pCtx, int UNUSED){ SuperlockBusy *pBusy = (SuperlockBusy *)pCtx; if( pBusy->xBusy==0 ) return 0; return pBusy->xBusy(pBusy->pBusyArg, pBusy->nBusy++); } /* ** This function is used to determine if the main database file for ** connection db is open in WAL mode or not. If no error occurs and the ** database file is in WAL mode, set *pbWal to true and return SQLITE_OK. ** If it is not in WAL mode, set *pbWal to false. ** ** If an error occurs, return an SQLite error code. The value of *pbWal ** is undefined in this case. */ static int superlockIsWal(Superlock *pLock){ int rc; /* Return Code */ sqlite3_stmt *pStmt; /* Compiled PRAGMA journal_mode statement */ rc = sqlite3_prepare(pLock->db, "PRAGMA main.journal_mode", -1, &pStmt, 0); if( rc!=SQLITE_OK ) return rc; pLock->bWal = 0; if( SQLITE_ROW==sqlite3_step(pStmt) ){ const char *zMode = (const char *)sqlite3_column_text(pStmt, 0); if( zMode && strlen(zMode)==3 && sqlite3_strnicmp("wal", zMode, 3)==0 ){ pLock->bWal = 1; } } return sqlite3_finalize(pStmt); } /* ** Obtain an exclusive shm-lock on nByte bytes starting at offset idx ** of the file fd. If the lock cannot be obtained immediately, invoke ** the busy-handler until either it is obtained or the busy-handler ** callback returns 0. */ static int superlockShmLock( sqlite3_file *fd, /* Database file handle */ int idx, /* Offset of shm-lock to obtain */ int nByte, /* Number of consective bytes to lock */ SuperlockBusy *pBusy /* Busy-handler wrapper object */ ){ int rc; int (*xShmLock)(sqlite3_file*, int, int, int) = fd->pMethods->xShmLock; do { rc = xShmLock(fd, idx, nByte, SQLITE_SHM_LOCK|SQLITE_SHM_EXCLUSIVE); }while( rc==SQLITE_BUSY && superlockBusyHandler((void *)pBusy, 0) ); return rc; } /* ** Obtain the extra locks on the database file required for WAL databases. ** Invoke the supplied busy-handler as required. */ static int superlockWalLock( sqlite3 *db, /* Database handle open on WAL database */ SuperlockBusy *pBusy /* Busy handler wrapper object */ ){ int rc; /* Return code */ sqlite3_file *fd = 0; /* Main database file handle */ void volatile *p = 0; /* Pointer to first page of shared memory */ /* Obtain a pointer to the sqlite3_file object open on the main db file. */ rc = sqlite3_file_control(db, "main", SQLITE_FCNTL_FILE_POINTER, (void *)&fd); if( rc!=SQLITE_OK ) return rc; /* Obtain the "recovery" lock. Normally, this lock is only obtained by ** clients running database recovery. */ rc = superlockShmLock(fd, 2, 1, pBusy); if( rc!=SQLITE_OK ) return rc; /* Zero the start of the first shared-memory page. This means that any ** clients that open read or write transactions from this point on will ** have to run recovery before proceeding. Since they need the "recovery" ** lock that this process is holding to do that, no new read or write ** transactions may now be opened. Nor can a checkpoint be run, for the ** same reason. */ rc = fd->pMethods->xShmMap(fd, 0, 32*1024, 1, &p); if( rc!=SQLITE_OK ) return rc; memset((void *)p, 0, 32); /* Obtain exclusive locks on all the "read-lock" slots. Once these locks ** are held, it is guaranteed that there are no active reader, writer or ** checkpointer clients. */ rc = superlockShmLock(fd, 3, SQLITE_SHM_NLOCK-3, pBusy); return rc; } /* ** Release a superlock held on a database file. The argument passed to ** this function must have been obtained from a successful call to ** sqlite3demo_superlock(). */ static void sqlite3demo_superunlock(void *pLock){ Superlock *p = (Superlock *)pLock; if( p->bWal ){ int rc; /* Return code */ int flags = SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE; sqlite3_file *fd = 0; rc = sqlite3_file_control(p->db, "main", SQLITE_FCNTL_FILE_POINTER, (void *)&fd); if( rc==SQLITE_OK ){ fd->pMethods->xShmLock(fd, 2, 1, flags); fd->pMethods->xShmLock(fd, 3, SQLITE_SHM_NLOCK-3, flags); } } sqlite3_close(p->db); sqlite3_free(p); } /* ** Obtain a superlock on the database file identified by zPath, using the ** locking primitives provided by VFS zVfs. If successful, SQLITE_OK is ** returned and output variable *ppLock is populated with an opaque handle ** that may be used with sqlite3demo_superunlock() to release the lock. ** ** If an error occurs, *ppLock is set to 0 and an SQLite error code ** (e.g. SQLITE_BUSY) is returned. ** ** If a required lock cannot be obtained immediately and the xBusy parameter ** to this function is not NULL, then xBusy is invoked in the same way ** as a busy-handler registered with SQLite (using sqlite3_busy_handler()) ** until either the lock can be obtained or the busy-handler function returns ** 0 (indicating "give up"). */ static int sqlite3demo_superlock( const char *zPath, /* Path to database file to lock */ const char *zVfs, /* VFS to use to access database file */ int flags, /* Additional flags to pass to sqlite3_open_v2 */ int (*xBusy)(void*,int), /* Busy handler callback */ void *pBusyArg, /* Context arg for busy handler */ void **ppLock /* OUT: Context to pass to superunlock() */ ){ SuperlockBusy busy = {0, 0, 0}; /* Busy handler wrapper object */ int rc; /* Return code */ Superlock *pLock; pLock = sqlite3_malloc(sizeof(Superlock)); if( !pLock ) return SQLITE_NOMEM; memset(pLock, 0, sizeof(Superlock)); /* Open a database handle on the file to superlock. */ rc = sqlite3_open_v2( zPath, &pLock->db, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|flags, zVfs ); /* Install a busy-handler and execute a BEGIN EXCLUSIVE. If this is not ** a WAL database, this is all we need to do. ** ** A wrapper function is used to invoke the busy-handler instead of ** registering the busy-handler function supplied by the user directly ** with SQLite. This is because the same busy-handler function may be ** invoked directly later on when attempting to obtain the extra locks ** required in WAL mode. By using the wrapper, we are able to guarantee ** that the "nBusy" integer parameter passed to the users busy-handler ** represents the total number of busy-handler invocations made within ** this call to sqlite3demo_superlock(), including any made during the ** "BEGIN EXCLUSIVE". */ if( rc==SQLITE_OK ){ busy.xBusy = xBusy; busy.pBusyArg = pBusyArg; sqlite3_busy_handler(pLock->db, superlockBusyHandler, (void *)&busy); rc = sqlite3_exec(pLock->db, "BEGIN EXCLUSIVE", 0, 0, 0); } /* If the BEGIN EXCLUSIVE was executed successfully and this is a WAL ** database, call superlockWalLock() to obtain the extra locks required ** to prevent readers, writers and/or checkpointers from accessing the ** db while this process is holding the superlock. ** ** Before attempting any WAL locks, commit the transaction started above ** to drop the WAL read and write locks currently held. Otherwise, the ** new WAL locks may conflict with the old. */ if( rc==SQLITE_OK ){ if( SQLITE_OK==(rc = superlockIsWal(pLock)) && pLock->bWal ){ rc = sqlite3_exec(pLock->db, "COMMIT", 0, 0, 0); if( rc==SQLITE_OK ){ rc = superlockWalLock(pLock->db, &busy); } } } if( rc!=SQLITE_OK ){ sqlite3demo_superunlock(pLock); *ppLock = 0; }else{ *ppLock = pLock; } return rc; } /* A corrupt DB won't work with the sql-based locking attempt, grab an ** exclusive lock and return SQLITE_OK or SQLITE_BUSY if the lock fails ** returns the current lock level held on sqlite3_file */ static int sqlite3demo_superlock_corrupt(sqlite3_file *id, int eTargetFileLock, int *pFileLock) { unixFile *pFile = (unixFile*)id; int eFileLock = pFile->eFileLock; int rc = SQLITE_OK; if( eFileLock<eTargetFileLock ){ rc = pFile->pMethod->xLock(id, SQLITE_LOCK_SHARED); } if( !rc && eFileLock<eTargetFileLock ){ rc = pFile->pMethod->xLock(id, SQLITE_LOCK_EXCLUSIVE); } if( rc ){ if( pFile->eFileLock > eFileLock ){ pFile->pMethod->xUnlock(id, eFileLock); } return rc; } if (pFileLock) { *pFileLock = eFileLock; } return SQLITE_OK; } static int sqlite3demo_superunlock_corrupt(sqlite3_file *id, int eFileLock) { unixFile *pFile = (unixFile*)id; int rc = SQLITE_OK; if( pFile->eFileLock > eFileLock ){ rc = pFile->pMethod->xUnlock(id, SQLITE_LOCK_SHARED); } if( pFile->eFileLock > eFileLock ){ int unlockRC = pFile->pMethod->xUnlock(id, SQLITE_LOCK_NONE); if (!rc) rc = unlockRC; } return rc; } #endif /* SQLITE_ENABLE_SUPERLOCK */ /* ** Different Unix systems declare open() in different ways. Same use ** open(const char*,int,mode_t). Others use open(const char*,int,...). ** The difference is important when using a pointer to the function. ** ** The safest way to deal with the problem is to always use this wrapper |
︙ | ︙ | |||
1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 | */ static void closePendingFds(unixFile *pFile){ unixInodeInfo *pInode = pFile->pInode; UnixUnusedFd *p; UnixUnusedFd *pNext; for(p=pInode->pUnused; p; p=pNext){ pNext = p->pNext; robust_close(pFile, p->fd, __LINE__); sqlite3_free(p); } pInode->pUnused = 0; } /* ** Release a unixInodeInfo structure previously allocated by findInodeInfo(). ** | > > > > > > > > > > > | 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 | */ static void closePendingFds(unixFile *pFile){ unixInodeInfo *pInode = pFile->pInode; UnixUnusedFd *p; UnixUnusedFd *pNext; for(p=pInode->pUnused; p; p=pNext){ pNext = p->pNext; #if OSCLOSE_CHECK_CLOSE_IOERR if( close(p->fd) ){ pFile->lastErrno = errno; rc = SQLITE_IOERR_CLOSE; p->pNext = pError; pError = p; }else{ sqlite3_free(p); } #else robust_close(pFile, p->fd, __LINE__); sqlite3_free(p); #endif } pInode->pUnused = 0; } /* ** Release a unixInodeInfo structure previously allocated by findInodeInfo(). ** |
︙ | ︙ | |||
1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 | if( !reserved && !pFile->pInode->bProcessLock ){ struct flock lock; lock.l_whence = SEEK_SET; lock.l_start = RESERVED_BYTE; lock.l_len = 1; lock.l_type = F_WRLCK; if( osFcntl(pFile->h, F_GETLK, &lock) ){ rc = SQLITE_IOERR_CHECKRESERVEDLOCK; pFile->lastErrno = errno; } else if( lock.l_type!=F_UNLCK ){ reserved = 1; } } #endif unixLeaveMutex(); | > > > > > > | 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 | if( !reserved && !pFile->pInode->bProcessLock ){ struct flock lock; lock.l_whence = SEEK_SET; lock.l_start = RESERVED_BYTE; lock.l_len = 1; lock.l_type = F_WRLCK; if( osFcntl(pFile->h, F_GETLK, &lock) ){ #if OSLOCKING_CHECK_BUSY_IOERR int tErrno = errno; rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_CHECKRESERVEDLOCK); pFile->lastErrno = tErrno; #else rc = SQLITE_IOERR_CHECKRESERVEDLOCK; pFile->lastErrno = errno; #endif } else if( lock.l_type!=F_UNLCK ){ reserved = 1; } } #endif unixLeaveMutex(); |
︙ | ︙ | |||
1416 1417 1418 1419 1420 1421 1422 | || (eFileLock==EXCLUSIVE_LOCK && pFile->eFileLock<PENDING_LOCK) ){ lock.l_type = (eFileLock==SHARED_LOCK?F_RDLCK:F_WRLCK); lock.l_start = PENDING_BYTE; if( unixFileLock(pFile, &lock) ){ tErrno = errno; rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); | | | 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 | || (eFileLock==EXCLUSIVE_LOCK && pFile->eFileLock<PENDING_LOCK) ){ lock.l_type = (eFileLock==SHARED_LOCK?F_RDLCK:F_WRLCK); lock.l_start = PENDING_BYTE; if( unixFileLock(pFile, &lock) ){ tErrno = errno; rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); if( IS_LOCK_ERROR(rc) ){ pFile->lastErrno = tErrno; } goto end_lock; } } |
︙ | ︙ | |||
1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 | /* Drop the temporary PENDING lock */ lock.l_start = PENDING_BYTE; lock.l_len = 1L; lock.l_type = F_UNLCK; if( unixFileLock(pFile, &lock) && rc==SQLITE_OK ){ /* This could happen with a network mount */ tErrno = errno; rc = SQLITE_IOERR_UNLOCK; } if( rc ){ | > > > > | | 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 | /* Drop the temporary PENDING lock */ lock.l_start = PENDING_BYTE; lock.l_len = 1L; lock.l_type = F_UNLCK; if( unixFileLock(pFile, &lock) && rc==SQLITE_OK ){ /* This could happen with a network mount */ tErrno = errno; #if OSLOCKING_CHECK_BUSY_IOERR rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); #else rc = SQLITE_IOERR_UNLOCK; #endif } if( rc ){ if( IS_LOCK_ERROR(rc) ){ pFile->lastErrno = tErrno; } goto end_lock; }else{ pFile->eFileLock = SHARED_LOCK; pInode->nLock++; pInode->nShared = 1; |
︙ | ︙ | |||
1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 | lock.l_type = F_UNLCK; lock.l_whence = SEEK_SET; lock.l_start = SHARED_FIRST; lock.l_len = divSize; if( unixFileLock(pFile, &lock)==(-1) ){ tErrno = errno; rc = SQLITE_IOERR_UNLOCK; if( IS_LOCK_ERROR(rc) ){ pFile->lastErrno = tErrno; } goto end_unlock; } lock.l_type = F_RDLCK; lock.l_whence = SEEK_SET; | > > > > | 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 | lock.l_type = F_UNLCK; lock.l_whence = SEEK_SET; lock.l_start = SHARED_FIRST; lock.l_len = divSize; if( unixFileLock(pFile, &lock)==(-1) ){ tErrno = errno; #if OSLOCKING_CHECK_BUSY_IOERR rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); #else rc = SQLITE_IOERR_UNLOCK; #endif if( IS_LOCK_ERROR(rc) ){ pFile->lastErrno = tErrno; } goto end_unlock; } lock.l_type = F_RDLCK; lock.l_whence = SEEK_SET; |
︙ | ︙ | |||
1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 | } lock.l_type = F_UNLCK; lock.l_whence = SEEK_SET; lock.l_start = SHARED_FIRST+divSize; lock.l_len = SHARED_SIZE-divSize; if( unixFileLock(pFile, &lock)==(-1) ){ tErrno = errno; rc = SQLITE_IOERR_UNLOCK; if( IS_LOCK_ERROR(rc) ){ pFile->lastErrno = tErrno; } goto end_unlock; } }else #endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */ { lock.l_type = F_RDLCK; lock.l_whence = SEEK_SET; lock.l_start = SHARED_FIRST; lock.l_len = SHARED_SIZE; if( unixFileLock(pFile, &lock) ){ /* In theory, the call to unixFileLock() cannot fail because another ** process is holding an incompatible lock. If it does, this ** indicates that the other process is not following the locking ** protocol. If this happens, return SQLITE_IOERR_RDLOCK. Returning ** SQLITE_BUSY would confuse the upper layer (in practice it causes ** an assert to fail). */ rc = SQLITE_IOERR_RDLOCK; pFile->lastErrno = errno; goto end_unlock; } } } lock.l_type = F_UNLCK; lock.l_whence = SEEK_SET; lock.l_start = PENDING_BYTE; lock.l_len = 2L; assert( PENDING_BYTE+1==RESERVED_BYTE ); if( unixFileLock(pFile, &lock)==0 ){ pInode->eFileLock = SHARED_LOCK; }else{ rc = SQLITE_IOERR_UNLOCK; pFile->lastErrno = errno; goto end_unlock; } } if( eFileLock==NO_LOCK ){ /* Decrement the shared lock counter. Release the lock using an ** OS call only when all threads in this same process have released ** the lock. */ pInode->nShared--; if( pInode->nShared==0 ){ lock.l_type = F_UNLCK; lock.l_whence = SEEK_SET; lock.l_start = lock.l_len = 0L; SimulateIOErrorBenign(1); SimulateIOError( h=(-1) ) SimulateIOErrorBenign(0); if( unixFileLock(pFile, &lock)==0 ){ pInode->eFileLock = NO_LOCK; }else{ rc = SQLITE_IOERR_UNLOCK; | > > > > > > > > > > > > > > > > > > > > > > > > > > > | > | 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 | } lock.l_type = F_UNLCK; lock.l_whence = SEEK_SET; lock.l_start = SHARED_FIRST+divSize; lock.l_len = SHARED_SIZE-divSize; if( unixFileLock(pFile, &lock)==(-1) ){ tErrno = errno; #if OSLOCKING_CHECK_BUSY_IOERR rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); #else rc = SQLITE_IOERR_UNLOCK; #endif if( IS_LOCK_ERROR(rc) ){ pFile->lastErrno = tErrno; } goto end_unlock; } }else #endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */ { lock.l_type = F_RDLCK; lock.l_whence = SEEK_SET; lock.l_start = SHARED_FIRST; lock.l_len = SHARED_SIZE; if( unixFileLock(pFile, &lock) ){ #if OSLOCKING_CHECK_BUSY_IOERR tErrno = errno; rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_RDLOCK); if( IS_LOCK_ERROR(rc) ){ pFile->lastErrno = tErrno; } #else /* In theory, the call to unixFileLock() cannot fail because another ** process is holding an incompatible lock. If it does, this ** indicates that the other process is not following the locking ** protocol. If this happens, return SQLITE_IOERR_RDLOCK. Returning ** SQLITE_BUSY would confuse the upper layer (in practice it causes ** an assert to fail). */ rc = SQLITE_IOERR_RDLOCK; pFile->lastErrno = errno; #endif goto end_unlock; } } } lock.l_type = F_UNLCK; lock.l_whence = SEEK_SET; lock.l_start = PENDING_BYTE; lock.l_len = 2L; assert( PENDING_BYTE+1==RESERVED_BYTE ); if( unixFileLock(pFile, &lock)==0 ){ pInode->eFileLock = SHARED_LOCK; }else{ #if OSLOCKING_CHECK_BUSY_IOERR tErrno = errno; rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); if( IS_LOCK_ERROR(rc) ){ pFile->lastErrno = tErrno; } #else rc = SQLITE_IOERR_UNLOCK; pFile->lastErrno = errno; #endif goto end_unlock; } } if( eFileLock==NO_LOCK ){ /* Decrement the shared lock counter. Release the lock using an ** OS call only when all threads in this same process have released ** the lock. */ pInode->nShared--; if( pInode->nShared==0 ){ lock.l_type = F_UNLCK; lock.l_whence = SEEK_SET; lock.l_start = lock.l_len = 0L; SimulateIOErrorBenign(1); SimulateIOError( h=(-1) ) SimulateIOErrorBenign(0); if( unixFileLock(pFile, &lock)==0 ){ pInode->eFileLock = NO_LOCK; }else{ #if OSLOCKING_CHECK_BUSY_IOERR tErrno = errno; rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); if( IS_LOCK_ERROR(rc) ){ pFile->lastErrno = tErrno; } #else rc = SQLITE_IOERR_UNLOCK; pFile->lastErrno = errno; #endif pInode->eFileLock = NO_LOCK; pFile->eFileLock = NO_LOCK; } } /* Decrement the count of locks against this same file. When the ** count reaches zero, close any other file descriptors whose close |
︙ | ︙ | |||
1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 | ** ** It is *not* necessary to hold the mutex when this routine is called, ** even on VxWorks. A mutex will be acquired on VxWorks by the ** vxworksReleaseFileId() routine. */ static int closeUnixFile(sqlite3_file *id){ unixFile *pFile = (unixFile*)id; if( pFile->dirfd>=0 ){ robust_close(pFile, pFile->dirfd, __LINE__); pFile->dirfd=-1; } if( pFile->h>=0 ){ robust_close(pFile, pFile->h, __LINE__); pFile->h = -1; } #if OS_VXWORKS if( pFile->pId ){ if( pFile->isDelete ){ unlink(pFile->pId->zCanonicalName); } vxworksReleaseFileId(pFile->pId); pFile->pId = 0; | > > > > > > > > > > > > > > > > > > > > > | 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 | ** ** It is *not* necessary to hold the mutex when this routine is called, ** even on VxWorks. A mutex will be acquired on VxWorks by the ** vxworksReleaseFileId() routine. */ static int closeUnixFile(sqlite3_file *id){ unixFile *pFile = (unixFile*)id; #if OSCLOSE_CHECK_CLOSE_IOERR if( pFile->dirfd>=0 ){ int err = close(pFile->dirfd); if( err ){ pFile->lastErrno = errno; return SQLITE_IOERR_DIR_CLOSE; }else{ pFile->dirfd=-1; } } if( pFile->h>=0 ){ int err = close(pFile->h); if( err ){ pFile->lastErrno = errno; return SQLITE_IOERR_CLOSE; }else{ pFile->h=-1; } } #else if( pFile->dirfd>=0 ){ robust_close(pFile, pFile->dirfd, __LINE__); pFile->dirfd=-1; } if( pFile->h>=0 ){ robust_close(pFile, pFile->h, __LINE__); pFile->h = -1; } #endif #if OS_VXWORKS if( pFile->pId ){ if( pFile->isDelete ){ unlink(pFile->pId->zCanonicalName); } vxworksReleaseFileId(pFile->pId); pFile->pId = 0; |
︙ | ︙ | |||
1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 | rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); if( IS_LOCK_ERROR(rc) ){ pFile->lastErrno = tErrno; } } return rc; } robust_close(pFile, fd, __LINE__); /* got it, set the type and return ok */ pFile->eFileLock = eFileLock; return rc; } /* | > > > > > > > | 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 | rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); if( IS_LOCK_ERROR(rc) ){ pFile->lastErrno = tErrno; } } return rc; } #if OSCLOSE_CHECK_CLOSE_IOERR if( close(fd) ){ pFile->lastErrno = errno; rc = SQLITE_IOERR_CLOSE; } #else robust_close(pFile, fd, __LINE__); #endif /* got it, set the type and return ok */ pFile->eFileLock = eFileLock; return rc; } /* |
︙ | ︙ | |||
2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 | /* To fully unlock the database, delete the lock file */ assert( eFileLock==NO_LOCK ); if( unlink(zLockFile) ){ int rc = 0; int tErrno = errno; if( ENOENT != tErrno ){ rc = SQLITE_IOERR_UNLOCK; } if( IS_LOCK_ERROR(rc) ){ pFile->lastErrno = tErrno; } return rc; } pFile->eFileLock = NO_LOCK; | > > > > | 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 | /* To fully unlock the database, delete the lock file */ assert( eFileLock==NO_LOCK ); if( unlink(zLockFile) ){ int rc = 0; int tErrno = errno; if( ENOENT != tErrno ){ #if OSLOCKING_CHECK_BUSY_IOERR rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); #else rc = SQLITE_IOERR_UNLOCK; #endif } if( IS_LOCK_ERROR(rc) ){ pFile->lastErrno = tErrno; } return rc; } pFile->eFileLock = NO_LOCK; |
︙ | ︙ | |||
2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 | int lrc = robust_flock(pFile->h, LOCK_EX | LOCK_NB); if( !lrc ){ /* got the lock, unlock it */ lrc = robust_flock(pFile->h, LOCK_UN); if ( lrc ) { int tErrno = errno; /* unlock failed with an error */ lrc = SQLITE_IOERR_UNLOCK; if( IS_LOCK_ERROR(lrc) ){ pFile->lastErrno = tErrno; rc = lrc; } } } else { int tErrno = errno; | > > > > | 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 | int lrc = robust_flock(pFile->h, LOCK_EX | LOCK_NB); if( !lrc ){ /* got the lock, unlock it */ lrc = robust_flock(pFile->h, LOCK_UN); if ( lrc ) { int tErrno = errno; /* unlock failed with an error */ #if OSLOCKING_CHECK_BUSY_IOERR lrc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); #else lrc = SQLITE_IOERR_UNLOCK; #endif if( IS_LOCK_ERROR(lrc) ){ pFile->lastErrno = tErrno; rc = lrc; } } } else { int tErrno = errno; |
︙ | ︙ | |||
3313 3314 3315 3316 3317 3318 3319 | ** A failed directory sync is not a big deal. So it seems ** better to ignore the error. Ticket #1657 */ /* pFile->lastErrno = errno; */ /* return SQLITE_IOERR; */ } #endif | | > > > > > > > > > | 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 | ** A failed directory sync is not a big deal. So it seems ** better to ignore the error. Ticket #1657 */ /* pFile->lastErrno = errno; */ /* return SQLITE_IOERR; */ } #endif /* Only need to sync once, so close the directory when we are done */ #if OSCLOSE_CHECK_CLOSE_IOERR if( close(pFile->dirfd)==0 ){ pFile->dirfd = -1; }else{ pFile->lastErrno = errno; rc = SQLITE_IOERR_DIR_CLOSE; } #else robust_close(pFile, pFile->dirfd, __LINE__); pFile->dirfd = -1; #endif } return rc; } /* ** Truncate an open file to a specified size */ |
︙ | ︙ | |||
3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 | } #if (SQLITE_ENABLE_APPLE_SPI>0) && defined(__APPLE__) #include "sqlite3_private.h" #include <copyfile.h> static int getDbPathForUnixFile(unixFile *pFile, char *dbPath); #endif /* ** Information and control of an open file handle. */ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ switch( op ){ case SQLITE_FCNTL_LOCKSTATE: { | > | 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 | } #if (SQLITE_ENABLE_APPLE_SPI>0) && defined(__APPLE__) #include "sqlite3_private.h" #include <copyfile.h> static int getDbPathForUnixFile(unixFile *pFile, char *dbPath); #endif static int isProxyLockingMode(unixFile *); /* ** Information and control of an open file handle. */ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ switch( op ){ case SQLITE_FCNTL_LOCKSTATE: { |
︙ | ︙ | |||
3495 3496 3497 3498 3499 3500 3501 | case SQLITE_GET_LOCKPROXYFILE: { return proxyFileControl(id,op,pArg); } #endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */ #if (SQLITE_ENABLE_APPLE_SPI>0) && defined(__APPLE__) case SQLITE_TRUNCATE_DATABASE: { unixFile *pFile = (unixFile*)id; | | | | | | | | | > > > > < < > | > | > | > | > | > | > > > > > > > | | | | | | | | | | | < < | < < | < | < | < | | < | < < < < < < < > > > > > > > > > > > | | > | > > > > > | > > > > | | | > > > | | | | | | | | | | | | | | | > | > | | > | > | | < < < > > | | > | < < | | < < > > | > > | < < < < < < > > > | | < < < > | > | > > > > > > | > > > > > > > > > > > > > | < | < < < < | > | | < < < < < < | | | < > | > | > | | | < < < < < < | > > > | > | | > > > | < < > > > > > | > | | > > > > > > > | | | | | | | | | | | < < | < > | < < < | > | < < > > > | > | > | 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 | case SQLITE_GET_LOCKPROXYFILE: { return proxyFileControl(id,op,pArg); } #endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */ #if (SQLITE_ENABLE_APPLE_SPI>0) && defined(__APPLE__) case SQLITE_TRUNCATE_DATABASE: { unixFile *pFile = (unixFile*)id; int rc = SQLITE_OK; void *pLock = NULL; int flags = 0; int corruptFileLock = 0; int isCorrupt = 0; #if SQLITE_ENABLE_DATA_PROTECTION flags |= pFile->protFlags; #endif #if SQLITE_ENABLE_LOCKING_STYLE if( isProxyLockingMode(pFile) ){ flags |= SQLITE_OPEN_AUTOPROXY; } #endif rc = sqlite3demo_superlock(pFile->zPath, 0, flags, 0, 0, &pLock); if( rc ){ if( rc==SQLITE_CORRUPT || rc==SQLITE_NOTADB ){ isCorrupt = 1; rc = sqlite3demo_superlock_corrupt(id, SQLITE_LOCK_EXCLUSIVE, &corruptFileLock); } if( rc ){ return rc; } } rc = pFile->pMethod->xTruncate(id, ((pFile->fsFlags & SQLITE_FSFLAGS_IS_MSDOS) != 0) ? 1L : 0L); if( rc==SQLITE_OK ){ char jPath[MAXPATHLEN+9]; int zLen = strlcpy(jPath, pFile->zPath, MAXPATHLEN+9); if( zLen<MAXPATHLEN ){ size_t jLen; const char extensions[2][9] = { "-wal", "-journal" /*, "-shm" */ }; int j = 0; for( j=0; j<2; j++ ){ jLen = strlcpy(&jPath[zLen], extensions[j], 9); if( jLen < 9 ){ int jfd = open(jPath, O_TRUNC); if( jfd==(-1) ){ if ( errno!=ENOENT ){ perror(jPath); } } else { fsync(jfd); close(jfd); } } } } pFile->pMethod->xSync(id, SQLITE_SYNC_FULL); } if( isCorrupt ){ sqlite3demo_superunlock_corrupt(id, corruptFileLock); }else{ sqlite3demo_superunlock(pLock); } return rc; } case SQLITE_REPLACE_DATABASE: { unixFile *pFile = (unixFile*)id; sqlite3 *srcdb = (sqlite3 *)pArg; Btree *pSrcBtree = NULL; sqlite3_file *src_file = NULL; unixFile *pSrcFile = NULL; char srcWalPath[MAXPATHLEN+5]; int srcWalFD = -1; int rc = SQLITE_OK; void *pLock = NULL; int flags = 0; sqlite3 *srcdb2 = NULL; copyfile_state_t s; int corruptSrcFileLock = 0; int corruptDstFileLock = 0; int isSrcCorrupt = 0; int isDstCorrupt = 0; if( !sqlite3SafetyCheckOk(srcdb) ){ return SQLITE_MISUSE; } #if SQLITE_ENABLE_DATA_PROTECTION flags |= pFile->protFlags; #endif #if SQLITE_ENABLE_LOCKING_STYLE if( isProxyLockingMode(pFile) ){ flags |= SQLITE_OPEN_AUTOPROXY; } #endif rc = sqlite3demo_superlock(pFile->zPath, 0, flags, 0, 0, &pLock); if( rc ){ if( rc==SQLITE_CORRUPT || rc==SQLITE_NOTADB ){ isDstCorrupt = 1; rc = sqlite3demo_superlock_corrupt(id, SQLITE_LOCK_EXCLUSIVE, &corruptDstFileLock); } if( rc ){ return rc; } } /* get the src file descriptor adhering to the db struct access rules ** this code is modeled after sqlite3_file_control() in main.c */ sqlite3_mutex_enter(srcdb->mutex); if( srcdb->nDb>0 ){ pSrcBtree = srcdb->aDb[0].pBt; } if( pSrcBtree ){ Pager *pSrcPager; sqlite3BtreeEnter(pSrcBtree); pSrcPager = sqlite3BtreePager(pSrcBtree); assert( pSrcPager!=0 ); src_file = sqlite3PagerFile(pSrcPager); assert( src_file!=0 ); if( src_file->pMethods ){ int srcFlags = 0; pSrcFile = (unixFile *)src_file; /* wal mode db cannot be opened readonly */ if ((pSrcFile->openFlags & O_RDWR) == O_RDWR) { srcFlags = SQLITE_OPEN_READWRITE; } else { srcFlags = SQLITE_OPEN_READONLY; } #if SQLITE_ENABLE_DATA_PROTECTION srcFlags |= pSrcFile->protFlags; #endif #if SQLITE_ENABLE_LOCKING_STYLE if( isProxyLockingMode(pSrcFile) ){ srcFlags |= SQLITE_OPEN_AUTOPROXY; } #endif rc = sqlite3_open_v2(pSrcFile->zPath, &srcdb2, srcFlags, 0); if( rc==SQLITE_OK ){ /* start a deferred transaction and read to establish a read lock */ rc = sqlite3_exec(srcdb2, "BEGIN DEFERRED; PRAGMA schema_version", 0, 0, 0); if( rc==SQLITE_CORRUPT || rc==SQLITE_NOTADB ){ isSrcCorrupt = 1; rc = sqlite3demo_superlock_corrupt(src_file, SQLITE_LOCK_SHARED, &corruptSrcFileLock); } } } } if( !srcdb2 || pSrcFile==NULL || pSrcFile->h<0){ rc = SQLITE_INTERNAL; } if( rc!=SQLITE_OK ){ goto end_replace_database; } /* both databases are locked appropriately, copy the src wal journal if ** one exists and then the actual database file */ strlcpy(srcWalPath, pSrcFile->zPath, MAXPATHLEN+5); strlcat(srcWalPath, "-wal", MAXPATHLEN+5); srcWalFD = open(srcWalPath, O_RDONLY); if( !(srcWalFD<0) ){ char dstWalPath[MAXPATHLEN+5]; int dstWalFD = -1; strlcpy(dstWalPath, pFile->zPath, MAXPATHLEN+5); strlcat(dstWalPath, "-wal", MAXPATHLEN+5); dstWalFD = open(dstWalPath, O_RDWR|O_CREAT, SQLITE_DEFAULT_FILE_PERMISSIONS); if( !(dstWalFD<0) ){ s = copyfile_state_alloc(); lseek(srcWalFD, 0, SEEK_SET); lseek(dstWalFD, 0, SEEK_SET); if( fcopyfile(srcWalFD, dstWalFD, s, COPYFILE_ALL) ){ int err=errno; switch(err) { case ENOMEM: rc = SQLITE_NOMEM; break; default: pFile->lastErrno = err; rc = SQLITE_IOERR; } } copyfile_state_free(s); close(dstWalFD); } close(srcWalFD); } if( rc==SQLITE_OK ){ /* before we copy, ensure that the file change counter will be modified */ uint32_t srcChange = 0; uint32_t dstChange = 0; pread(pSrcFile->h, &srcChange, 4, 24); pread(pFile->h, &dstChange, 4, 24); /* copy the actual database */ s = copyfile_state_alloc(); lseek(pSrcFile->h, 0, SEEK_SET); lseek(pFile->h, 0, SEEK_SET); if( fcopyfile(pSrcFile->h, pFile->h, s, COPYFILE_ALL) ){ int err=errno; switch(err) { case ENOMEM: rc = SQLITE_NOMEM; break; default: pFile->lastErrno = err; rc = SQLITE_IOERR; } } copyfile_state_free(s); if (srcChange == dstChange) { /* modify the change counter to force page zero to be reloaded */ dstChange ++; pwrite(pFile->h, &dstChange, 4, 24); } } if( isSrcCorrupt ){ sqlite3demo_superunlock_corrupt(src_file, corruptSrcFileLock); }else{ /* done with the source db so end the transaction */ sqlite3_exec(srcdb2, "COMMIT", 0, 0, 0); } /* zero out any old journal clutter */ if( rc==SQLITE_OK ){ char jPath[MAXPATHLEN+9]; int zLen = strlcpy(jPath, pFile->zPath, MAXPATHLEN+9); if( zLen<MAXPATHLEN ){ size_t jLen; const char extensions[2][9] = { "-wal", "-journal" /* "-shm" */ }; int j = (srcWalFD<0)?0:1; /* skip the wal if we replaced it */ for( ; j<2; j++ ){ jLen = strlcpy(&jPath[zLen], extensions[j], 9); if( jLen < 9 ){ int jfd = open(jPath, O_TRUNC); if( jfd==(-1) ){ if ( errno!=ENOENT ){ perror(jPath); } } else { fsync(jfd); close(jfd); } } } } pFile->pMethod->xSync(id, SQLITE_SYNC_FULL); } end_replace_database: if( pSrcBtree ){ sqlite3_close(srcdb2); sqlite3BtreeLeave(pSrcBtree); } sqlite3_mutex_leave(srcdb->mutex); if( isDstCorrupt ){ sqlite3demo_superunlock_corrupt(id, corruptDstFileLock); }else{ sqlite3demo_superunlock(pLock); } return rc; } #endif /* (SQLITE_ENABLE_APPLE_SPI>0) && defined(__APPLE__) */ case SQLITE_FCNTL_SYNC_OMITTED: { return SQLITE_OK; /* A no-op */ } |
︙ | ︙ | |||
3920 3921 3922 3923 3924 3925 3926 | p->h = -1; } p->pInode->pShmNode = 0; sqlite3_free(p); } } | < | 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 | p->h = -1; } p->pInode->pShmNode = 0; sqlite3_free(p); } } static const char *proxySharedMemoryBasePath(unixFile *); /* ** Open a shared-memory area associated with open database file pDbFd. ** This particular implementation uses mmapped files. ** ** The file used to implement shared-memory is in the same directory |
︙ | ︙ | |||
4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 | /* Check to see if another process is holding the dead-man switch. ** If not, truncate the file to zero length. */ rc = SQLITE_OK; if( unixShmSystemLock(pShmNode, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){ if( robust_ftruncate(pShmNode->h, 0) ){ rc = unixLogError(SQLITE_IOERR_SHMOPEN, "ftruncate", zShmFilename); } } if( rc==SQLITE_OK ){ rc = unixShmSystemLock(pShmNode, F_RDLCK, UNIX_SHM_DMS, 1); } if( rc ) goto shm_open_err; } | > > > > > > > > | 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 | /* Check to see if another process is holding the dead-man switch. ** If not, truncate the file to zero length. */ rc = SQLITE_OK; if( unixShmSystemLock(pShmNode, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){ if( robust_ftruncate(pShmNode->h, 0) ){ rc = unixLogError(SQLITE_IOERR_SHMOPEN, "ftruncate", zShmFilename); }else{ /* If running as root set the uid/gid of the shm file to match the database */ uid_t euid = geteuid(); if( euid==0 && (euid!=sStat.st_uid || getegid()!=sStat.st_gid) ){ if( fchown(pShmNode->h, sStat.st_uid, sStat.st_gid) ){ rc = SQLITE_IOERR_SHMOPEN; } } } } if( rc==SQLITE_OK ){ rc = unixShmSystemLock(pShmNode, F_RDLCK, UNIX_SHM_DMS, 1); } if( rc ) goto shm_open_err; } |
︙ | ︙ | |||
5077 5078 5079 5080 5081 5082 5083 | ** original filename is unavailable. But 8_3_NAMES is only used for ** FAT filesystems and permissions do not matter there, so just use ** the default permissions. */ static int findCreateFileMode( const char *zPath, /* Path of file (possibly) being created */ int flags, /* Flags passed as 4th argument to xOpen() */ | | > > | 5516 5517 5518 5519 5520 5521 5522 5523 5524 5525 5526 5527 5528 5529 5530 5531 5532 | ** original filename is unavailable. But 8_3_NAMES is only used for ** FAT filesystems and permissions do not matter there, so just use ** the default permissions. */ static int findCreateFileMode( const char *zPath, /* Path of file (possibly) being created */ int flags, /* Flags passed as 4th argument to xOpen() */ mode_t *pMode, /* OUT: Permissions to open file with */ uid_t *pUid, /* OUT: uid to set on the file */ gid_t *pGid /* OUT: gid to set on the file */ ){ int rc = SQLITE_OK; /* Return Code */ *pMode = SQLITE_DEFAULT_FILE_PERMISSIONS; if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){ char zDb[MAX_PATHNAME+1]; /* Database file path */ int nDb; /* Number of valid bytes in zDb */ struct stat sStat; /* Output of stat() on database file */ |
︙ | ︙ | |||
5106 5107 5108 5109 5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 | while( nDb>0 && zPath[nDb]!='-' ) nDb--; if( nDb==0 ) return SQLITE_OK; memcpy(zDb, zPath, nDb); zDb[nDb] = '\0'; if( 0==stat(zDb, &sStat) ){ *pMode = sStat.st_mode & 0777; }else{ rc = SQLITE_IOERR_FSTAT; } }else if( flags & SQLITE_OPEN_DELETEONCLOSE ){ *pMode = 0600; } return rc; | > > | 5547 5548 5549 5550 5551 5552 5553 5554 5555 5556 5557 5558 5559 5560 5561 5562 | while( nDb>0 && zPath[nDb]!='-' ) nDb--; if( nDb==0 ) return SQLITE_OK; memcpy(zDb, zPath, nDb); zDb[nDb] = '\0'; if( 0==stat(zDb, &sStat) ){ *pMode = sStat.st_mode & 0777; *pUid = sStat.st_uid; *pGid = sStat.st_gid; }else{ rc = SQLITE_IOERR_FSTAT; } }else if( flags & SQLITE_OPEN_DELETEONCLOSE ){ *pMode = 0600; } return rc; |
︙ | ︙ | |||
5148 5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 | int flags, /* Input flags to control the opening */ int *pOutFlags /* Output flags returned to SQLite core */ ){ unixFile *p = (unixFile *)pFile; int fd = -1; /* File descriptor returned by open() */ int dirfd = -1; /* Directory file descriptor */ int openFlags = 0; /* Flags to pass to open() */ int eType = flags&0xFFFFFF00; /* Type of file to open */ int noLock; /* True to omit locking primitives */ int rc = SQLITE_OK; /* Function Return Code */ int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE); int isDelete = (flags & SQLITE_OPEN_DELETEONCLOSE); int isCreate = (flags & SQLITE_OPEN_CREATE); int isReadonly = (flags & SQLITE_OPEN_READONLY); | > > > > | 5591 5592 5593 5594 5595 5596 5597 5598 5599 5600 5601 5602 5603 5604 5605 5606 5607 5608 5609 | int flags, /* Input flags to control the opening */ int *pOutFlags /* Output flags returned to SQLite core */ ){ unixFile *p = (unixFile *)pFile; int fd = -1; /* File descriptor returned by open() */ int dirfd = -1; /* Directory file descriptor */ int openFlags = 0; /* Flags to pass to open() */ #if SQLITE_ENABLE_DATA_PROTECTION int eType = flags&0xFF0FFF00; /* Type of file to open */ #else int eType = flags&0xFFFFFF00; /* Type of file to open */ #endif int noLock; /* True to omit locking primitives */ int rc = SQLITE_OK; /* Function Return Code */ int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE); int isDelete = (flags & SQLITE_OPEN_DELETEONCLOSE); int isCreate = (flags & SQLITE_OPEN_CREATE); int isReadonly = (flags & SQLITE_OPEN_READONLY); |
︙ | ︙ | |||
5237 5238 5239 5240 5241 5242 5243 5244 5245 | ** 'conch file' locking functions later on. */ if( isReadonly ) openFlags |= O_RDONLY; if( isReadWrite ) openFlags |= O_RDWR; if( isCreate ) openFlags |= O_CREAT; if( isExclusive ) openFlags |= (O_EXCL|O_NOFOLLOW); openFlags |= (O_LARGEFILE|O_BINARY); if( fd<0 ){ mode_t openMode; /* Permissions to create file with */ | > > > > > > | > > > > > > > > > > | 5684 5685 5686 5687 5688 5689 5690 5691 5692 5693 5694 5695 5696 5697 5698 5699 5700 5701 5702 5703 5704 5705 5706 5707 5708 5709 5710 5711 5712 5713 5714 5715 5716 5717 5718 5719 5720 5721 5722 5723 5724 5725 5726 5727 5728 5729 5730 5731 5732 5733 5734 5735 | ** 'conch file' locking functions later on. */ if( isReadonly ) openFlags |= O_RDONLY; if( isReadWrite ) openFlags |= O_RDWR; if( isCreate ) openFlags |= O_CREAT; if( isExclusive ) openFlags |= (O_EXCL|O_NOFOLLOW); openFlags |= (O_LARGEFILE|O_BINARY); #if SQLITE_ENABLE_DATA_PROTECTION p->protFlags = (flags & SQLITE_OPEN_FILEPROTECTION_MASK); #endif if( fd<0 ){ mode_t openMode; /* Permissions to create file with */ uid_t uid; gid_t gid; rc = findCreateFileMode(zName, flags, &openMode, &uid, &gid); if( rc!=SQLITE_OK ){ assert( !p->pUnused ); assert( eType==SQLITE_OPEN_WAL || eType==SQLITE_OPEN_MAIN_JOURNAL ); return rc; } fd = robust_open(zName, openFlags, openMode); OSTRACE(("OPENX %-3d %s 0%o\n", fd, zName, openFlags)); if( fd<0 && errno!=EISDIR && isReadWrite && !isExclusive ){ /* Failed to open the file for read/write access. Try read-only. */ flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); openFlags &= ~(O_RDWR|O_CREAT); flags |= SQLITE_OPEN_READONLY; openFlags |= O_RDONLY; isReadonly = 1; fd = robust_open(zName, openFlags, openMode); } if( fd<0 ){ rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zName); goto open_finished; } /* if we're opening the wal or journal and running as root, set the journal uid/gid */ if( !isReadonly && (flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL)) ){ uid_t euid = geteuid(); if( euid==0 && (euid!=uid || getegid()!=gid) ){ if( fchown(fd, uid, gid) ){ rc = SQLITE_CANTOPEN_BKPT; goto open_finished; } } } } assert( fd>=0 ); if( pOutFlags ){ *pOutFlags = flags; } |
︙ | ︙ | |||
5333 5334 5335 5336 5337 5338 5339 | int useProxy = 0; /* SQLITE_FORCE_PROXY_LOCKING==1 means force always use proxy, 0 means ** never use proxy, NULL means use proxy for non-local files only. */ if( envforce!=NULL ){ useProxy = atoi(envforce)>0; }else{ | < < < < < < < < < < < < < < < < < | 5796 5797 5798 5799 5800 5801 5802 5803 5804 5805 5806 5807 5808 5809 | int useProxy = 0; /* SQLITE_FORCE_PROXY_LOCKING==1 means force always use proxy, 0 means ** never use proxy, NULL means use proxy for non-local files only. */ if( envforce!=NULL ){ useProxy = atoi(envforce)>0; }else{ useProxy = !(fsInfo.f_flags&MNT_LOCAL); } if( useProxy ){ rc = fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock, isDelete, isReadonly); if( rc==SQLITE_OK ){ /* cache the pMethod in case the transform fails */ |
︙ | ︙ | |||
5415 5416 5417 5418 5419 5420 5421 5422 5423 5424 5425 5426 5427 5428 5429 | if( fsync(fd)==-1 ) #else if( fsync(fd) ) #endif { rc = unixLogError(SQLITE_IOERR_DIR_FSYNC, "fsync", zPath); } robust_close(0, fd, __LINE__); } } #endif return rc; } /* | > > > > > > | 5861 5862 5863 5864 5865 5866 5867 5868 5869 5870 5871 5872 5873 5874 5875 5876 5877 5878 5879 5880 5881 | if( fsync(fd)==-1 ) #else if( fsync(fd) ) #endif { rc = unixLogError(SQLITE_IOERR_DIR_FSYNC, "fsync", zPath); } #if OSCLOSE_CHECK_CLOSE_IOERR if( close(fd)&&!rc ){ rc = SQLITE_IOERR_DIR_CLOSE; } #else robust_close(0, fd, __LINE__); #endif } } #endif return rc; } /* |
︙ | ︙ | |||
5881 5882 5883 5884 5885 5886 5887 5888 5889 5890 5891 5892 5893 5894 | struct proxyLockingContext { unixFile *conchFile; /* Open conch file */ char *conchFilePath; /* Name of the conch file */ unixFile *lockProxy; /* Open proxy lock file */ char *lockProxyPath; /* Name of the proxy lock file */ char *dbPath; /* Name of the open file */ int conchHeld; /* 1 if the conch is held, -1 if lockless */ void *oldLockingContext; /* Original lockingcontext to restore on close */ sqlite3_io_methods const *pOldMethod; /* Original I/O methods for close */ }; /* ** The proxy lock file path for the database at dbPath is written into lPath, ** which must point to valid, writable memory large enough for a maxLen length | > | 6333 6334 6335 6336 6337 6338 6339 6340 6341 6342 6343 6344 6345 6346 6347 | struct proxyLockingContext { unixFile *conchFile; /* Open conch file */ char *conchFilePath; /* Name of the conch file */ unixFile *lockProxy; /* Open proxy lock file */ char *lockProxyPath; /* Name of the proxy lock file */ char *dbPath; /* Name of the open file */ int conchHeld; /* 1 if the conch is held, -1 if lockless */ int nFails; /* Number of conch taking failures */ void *oldLockingContext; /* Original lockingcontext to restore on close */ sqlite3_io_methods const *pOldMethod; /* Original I/O methods for close */ }; /* ** The proxy lock file path for the database at dbPath is written into lPath, ** which must point to valid, writable memory large enough for a maxLen length |
︙ | ︙ | |||
6093 6094 6095 6096 6097 6098 6099 | /* get the host ID via gethostuuid(), pHostID must point to PROXY_HOSTIDLEN ** bytes of writable memory. */ static int proxyGetHostID(unsigned char *pHostID, int *pError){ assert(PROXY_HOSTIDLEN == sizeof(uuid_t)); memset(pHostID, 0, PROXY_HOSTIDLEN); | | < | > | 6546 6547 6548 6549 6550 6551 6552 6553 6554 6555 6556 6557 6558 6559 6560 6561 6562 6563 | /* get the host ID via gethostuuid(), pHostID must point to PROXY_HOSTIDLEN ** bytes of writable memory. */ static int proxyGetHostID(unsigned char *pHostID, int *pError){ assert(PROXY_HOSTIDLEN == sizeof(uuid_t)); memset(pHostID, 0, PROXY_HOSTIDLEN); #if HAVE_GETHOSTUUID { struct timespec timeout = {1, 0}; /* 1 sec timeout */ if( gethostuuid(pHostID, &timeout) ){ int err = errno; if( pError ){ *pError = err; } return SQLITE_IOERR; } |
︙ | ︙ | |||
6194 6195 6196 6197 6198 6199 6200 | /* Take the requested lock on the conch file and break a stale lock if the ** host id matches. */ static int proxyConchLock(unixFile *pFile, uuid_t myHostID, int lockType){ proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; unixFile *conchFile = pCtx->conchFile; int rc = SQLITE_OK; | < < > | | | | > > > > > > > > > > > > > > > | | | | 6647 6648 6649 6650 6651 6652 6653 6654 6655 6656 6657 6658 6659 6660 6661 6662 6663 6664 6665 6666 6667 6668 6669 6670 6671 6672 6673 6674 6675 6676 6677 6678 6679 6680 6681 6682 6683 6684 6685 6686 6687 6688 6689 6690 6691 6692 6693 6694 6695 6696 6697 6698 6699 6700 6701 6702 6703 6704 6705 6706 6707 6708 6709 6710 6711 6712 6713 6714 6715 6716 6717 6718 6719 6720 6721 6722 6723 6724 6725 6726 6727 6728 6729 6730 6731 6732 6733 6734 6735 6736 6737 | /* Take the requested lock on the conch file and break a stale lock if the ** host id matches. */ static int proxyConchLock(unixFile *pFile, uuid_t myHostID, int lockType){ proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; unixFile *conchFile = pCtx->conchFile; int rc = SQLITE_OK; struct timespec conchModTime; do { rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, lockType); if( rc==SQLITE_BUSY ){ pCtx->nFails ++; /* If the lock failed (busy): * 1st try: get the mod time of the conch, wait 0.5s and try again. * 2nd try: fail if the mod time changed or host id is different, wait * 10 sec and try again * 3rd try: break the lock unless the mod time has changed. */ struct stat buf; if( osFstat(conchFile->h, &buf) ){ pFile->lastErrno = errno; return SQLITE_IOERR_LOCK; } if( pCtx->nFails==1 ){ conchModTime = buf.st_mtimespec; usleep(500000); /* wait 0.5 sec and try the lock again*/ continue; } assert( pCtx->nFails>1 ); if( conchModTime.tv_sec != buf.st_mtimespec.tv_sec || conchModTime.tv_nsec != buf.st_mtimespec.tv_nsec ){ return SQLITE_BUSY; } if( pCtx->nFails==2 ){ char tBuf[PROXY_MAXCONCHLEN]; int len = osPread(conchFile->h, tBuf, PROXY_MAXCONCHLEN, 0); if( len<0 ){ pFile->lastErrno = errno; return SQLITE_IOERR_LOCK; } if( len>PROXY_PATHINDEX && tBuf[0]==(char)PROXY_CONCHVERSION){ /* don't break the lock if the host id doesn't match, but do log * an error to console so users can diagnose stale NFS locks more * easily */ if( 0!=memcmp(&tBuf[PROXY_HEADERLEN], myHostID, PROXY_HOSTIDLEN) ){ uuid_t conchUUID; uuid_string_t conchUUIDString; uuid_string_t myUUIDString; assert(PROXY_HOSTIDLEN == sizeof(uuid_t)); memcpy(conchUUID, &tBuf[PROXY_HEADERLEN], PROXY_HOSTIDLEN); uuid_unparse(conchUUID, conchUUIDString); uuid_unparse(myHostID, myUUIDString); fprintf(stderr, "ERROR: sqlite database is locked because it is in use " "by another host that holds a host-exclusive lock on %s; " "this host (UUID %s) cannot override the host-exclusive lock " "until the other host (UUID %s) releases its locks on %s\n", pFile->zPath, myUUIDString, conchUUIDString, conchFile->zPath); return SQLITE_BUSY; } }else{ /* don't break the lock on short read or a version mismatch */ return SQLITE_BUSY; } usleep(10000000); /* wait 10 sec and try the lock again */ continue; } assert( pCtx->nFails>=3 ); if( (pCtx->nFails==3)&&(0==proxyBreakConchLock(pFile, myHostID)) ){ rc = SQLITE_OK; if( lockType==EXCLUSIVE_LOCK ){ rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, SHARED_LOCK); } if( !rc ){ rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, lockType); } } } } while( rc==SQLITE_BUSY && pCtx->nFails<3 ); return rc; } /* Takes the conch by taking a shared lock and read the contents conch, if ** lockPath is non-NULL, the host ID and lock file path must match. A NULL ** lockPath means that the lockPath in the conch file will be used if the |
︙ | ︙ | |||
6375 6376 6377 6378 6379 6380 6381 | /* We are trying for an exclusive lock but another thread in this ** same process is still holding a shared lock. */ rc = SQLITE_BUSY; } else { rc = proxyConchLock(pFile, myHostID, EXCLUSIVE_LOCK); } }else{ | | | 6842 6843 6844 6845 6846 6847 6848 6849 6850 6851 6852 6853 6854 6855 6856 | /* We are trying for an exclusive lock but another thread in this ** same process is still holding a shared lock. */ rc = SQLITE_BUSY; } else { rc = proxyConchLock(pFile, myHostID, EXCLUSIVE_LOCK); } }else{ rc = proxyConchLock(pFile, myHostID, EXCLUSIVE_LOCK); } if( rc==SQLITE_OK ){ char writeBuffer[PROXY_MAXCONCHLEN]; int writeSize = 0; writeBuffer[0] = (char)PROXY_CONCHVERSION; memcpy(&writeBuffer[PROXY_HEADERLEN], myHostID, PROXY_HOSTIDLEN); |
︙ | ︙ | |||
6429 6430 6431 6432 6433 6434 6435 6436 6437 6438 6439 6440 6441 6442 6443 | } conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, SHARED_LOCK); end_takeconch: OSTRACE(("TRANSPROXY: CLOSE %d\n", pFile->h)); if( rc==SQLITE_OK && pFile->openFlags ){ if( pFile->h>=0 ){ robust_close(pFile, pFile->h, __LINE__); } pFile->h = -1; int fd = robust_open(pCtx->dbPath, pFile->openFlags, SQLITE_DEFAULT_FILE_PERMISSIONS); OSTRACE(("TRANSPROXY: OPEN %d\n", fd)); if( fd>=0 ){ pFile->h = fd; | > > > > > > > | 6896 6897 6898 6899 6900 6901 6902 6903 6904 6905 6906 6907 6908 6909 6910 6911 6912 6913 6914 6915 6916 6917 | } conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, SHARED_LOCK); end_takeconch: OSTRACE(("TRANSPROXY: CLOSE %d\n", pFile->h)); if( rc==SQLITE_OK && pFile->openFlags ){ if( pFile->h>=0 ){ #if defined(STRICT_CLOSE_ERROR) && OSCLOSE_CHECK_CLOSE_IOERR if( close(pFile->h) ){ pFile->lastErrno = errno; return SQLITE_IOERR_CLOSE; } #else robust_close(pFile, pFile->h, __LINE__); #endif } pFile->h = -1; int fd = robust_open(pCtx->dbPath, pFile->openFlags, SQLITE_DEFAULT_FILE_PERMISSIONS); OSTRACE(("TRANSPROXY: OPEN %d\n", fd)); if( fd>=0 ){ pFile->h = fd; |
︙ | ︙ |
Changes to src/pager.c.
︙ | ︙ | |||
2373 2374 2375 2376 2377 2378 2379 | ** If successful, open the master journal file for reading. */ pMaster = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile * 2); pJournal = (sqlite3_file *)(((u8 *)pMaster) + pVfs->szOsFile); if( !pMaster ){ rc = SQLITE_NOMEM; }else{ | > > > > | | 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 | ** If successful, open the master journal file for reading. */ pMaster = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile * 2); pJournal = (sqlite3_file *)(((u8 *)pMaster) + pVfs->szOsFile); if( !pMaster ){ rc = SQLITE_NOMEM; }else{ const int flags = #if SQLITE_ENABLE_DATA_PROTECTION (pPager->vfsFlags&SQLITE_OPEN_FILEPROTECTION_MASK)| #endif (SQLITE_OPEN_READONLY|SQLITE_OPEN_MASTER_JOURNAL); rc = sqlite3OsOpen(pVfs, zMaster, pMaster, flags, 0); } if( rc!=SQLITE_OK ) goto delmaster_out; /* Load the entire master journal file into space obtained from ** sqlite3_malloc() and pointed to by zMasterJournal. Also obtain ** sufficient space (in zMasterPtr) to hold the names of master |
︙ | ︙ | |||
2409 2410 2411 2412 2413 2414 2415 | } if( exists ){ /* One of the journals pointed to by the master journal exists. ** Open it and check if it points at the master journal. If ** so, return without deleting the master journal file. */ int c; | > > > > | | 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 | } if( exists ){ /* One of the journals pointed to by the master journal exists. ** Open it and check if it points at the master journal. If ** so, return without deleting the master journal file. */ int c; int flags = #if SQLITE_ENABLE_DATA_PROTECTION (pPager->vfsFlags&SQLITE_OPEN_FILEPROTECTION_MASK)| #endif (SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL); rc = sqlite3OsOpen(pVfs, zJournal, pJournal, flags, 0); if( rc!=SQLITE_OK ){ goto delmaster_out; } rc = readMasterJournal(pJournal, zMasterPtr, nMasterPtr); sqlite3OsClose(pJournal); |
︙ | ︙ | |||
3394 3395 3396 3397 3398 3399 3400 | ){ int rc; /* Return code */ #ifdef SQLITE_TEST sqlite3_opentemp_count++; /* Used for testing and analysis only */ #endif | > > > > | | 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 | ){ int rc; /* Return code */ #ifdef SQLITE_TEST sqlite3_opentemp_count++; /* Used for testing and analysis only */ #endif vfsFlags |= #if SQLITE_ENABLE_DATA_PROTECTION (pPager->vfsFlags&SQLITE_OPEN_FILEPROTECTION_MASK)| #endif SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE; rc = sqlite3OsOpen(pPager->pVfs, 0, pFile, vfsFlags, 0); assert( rc!=SQLITE_OK || isOpen(pFile) ); return rc; } /* |
︙ | ︙ | |||
4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 | pPager->changeCountDone = pPager->tempFile; pPager->memDb = (u8)memDb; pPager->readOnly = (u8)readOnly; assert( useJournal || pPager->tempFile ); pPager->noSync = pPager->tempFile; pPager->fullSync = pPager->noSync ?0:1; pPager->syncFlags = pPager->noSync ? 0 : SQLITE_SYNC_NORMAL; pPager->ckptSyncFlags = pPager->syncFlags; /* pPager->pFirst = 0; */ /* pPager->pFirstSynced = 0; */ /* pPager->pLast = 0; */ pPager->nExtra = (u16)nExtra; pPager->journalSizeLimit = SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT; assert( isOpen(pPager->fd) || tempFile ); setSectorSize(pPager); | > > > > | 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 | pPager->changeCountDone = pPager->tempFile; pPager->memDb = (u8)memDb; pPager->readOnly = (u8)readOnly; assert( useJournal || pPager->tempFile ); pPager->noSync = pPager->tempFile; pPager->fullSync = pPager->noSync ?0:1; pPager->syncFlags = pPager->noSync ? 0 : SQLITE_SYNC_NORMAL; #if SQLITE_DEFAULT_CKPTFULLFSYNC pPager->ckptSyncFlags = pPager->noSync ? 0 : SQLITE_SYNC_FULL; #else pPager->ckptSyncFlags = pPager->syncFlags; #endif /* pPager->pFirst = 0; */ /* pPager->pFirstSynced = 0; */ /* pPager->pLast = 0; */ pPager->nExtra = (u16)nExtra; pPager->journalSizeLimit = SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT; assert( isOpen(pPager->fd) || tempFile ); setSectorSize(pPager); |
︙ | ︙ | |||
4634 4635 4636 4637 4638 4639 4640 | /* The journal file exists and no other connection has a reserved ** or greater lock on the database file. Now check that there is ** at least one non-zero bytes at the start of the journal file. ** If there is, then we consider this journal to be hot. If not, ** it can be ignored. */ if( !jrnlOpen ){ | > > > > | | 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 | /* The journal file exists and no other connection has a reserved ** or greater lock on the database file. Now check that there is ** at least one non-zero bytes at the start of the journal file. ** If there is, then we consider this journal to be hot. If not, ** it can be ignored. */ if( !jrnlOpen ){ int f = #if SQLITE_ENABLE_DATA_PROTECTION (pPager->vfsFlags&SQLITE_OPEN_FILEPROTECTION_MASK)| #endif SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL; rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &f); } if( rc==SQLITE_OK ){ u8 first = 0; rc = sqlite3OsRead(pPager->jfd, (void *)&first, 1, 0); if( rc==SQLITE_IOERR_SHORT_READ ){ rc = SQLITE_OK; |
︙ | ︙ | |||
4772 4773 4774 4775 4776 4777 4778 | if( !isOpen(pPager->jfd) ){ sqlite3_vfs * const pVfs = pPager->pVfs; int bExists; /* True if journal file exists */ rc = sqlite3OsAccess( pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS, &bExists); if( rc==SQLITE_OK && bExists ){ int fout = 0; | > > > > | | 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 | if( !isOpen(pPager->jfd) ){ sqlite3_vfs * const pVfs = pPager->pVfs; int bExists; /* True if journal file exists */ rc = sqlite3OsAccess( pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS, &bExists); if( rc==SQLITE_OK && bExists ){ int fout = 0; int f = #if SQLITE_ENABLE_DATA_PROTECTION (pPager->vfsFlags&SQLITE_OPEN_FILEPROTECTION_MASK)| #endif SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_JOURNAL; assert( !pPager->tempFile ); rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &fout); assert( rc!=SQLITE_OK || isOpen(pPager->jfd) ); if( rc==SQLITE_OK && fout&SQLITE_OPEN_READONLY ){ rc = SQLITE_CANTOPEN_BKPT; sqlite3OsClose(pPager->jfd); } |
︙ | ︙ | |||
5148 5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 | /* Open the journal file if it is not already open. */ if( !isOpen(pPager->jfd) ){ if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ){ sqlite3MemJournalOpen(pPager->jfd); }else{ const int flags = /* VFS flags to open journal file */ SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE| (pPager->tempFile ? (SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL): (SQLITE_OPEN_MAIN_JOURNAL) ); #ifdef SQLITE_ENABLE_ATOMIC_WRITE rc = sqlite3JournalOpen( | > > > | 5172 5173 5174 5175 5176 5177 5178 5179 5180 5181 5182 5183 5184 5185 5186 5187 5188 | /* Open the journal file if it is not already open. */ if( !isOpen(pPager->jfd) ){ if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ){ sqlite3MemJournalOpen(pPager->jfd); }else{ const int flags = /* VFS flags to open journal file */ #if SQLITE_ENABLE_DATA_PROTECTION (pPager->vfsFlags&SQLITE_OPEN_FILEPROTECTION_MASK)| #endif SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE| (pPager->tempFile ? (SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL): (SQLITE_OPEN_MAIN_JOURNAL) ); #ifdef SQLITE_ENABLE_ATOMIC_WRITE rc = sqlite3JournalOpen( |
︙ | ︙ | |||
6706 6707 6708 6709 6710 6711 6712 | rc = pagerExclusiveLock(pPager); } /* Open the connection to the log file. If this operation fails, ** (e.g. due to malloc() failure), return an error code. */ if( rc==SQLITE_OK ){ | > | > > > | | < > | 6733 6734 6735 6736 6737 6738 6739 6740 6741 6742 6743 6744 6745 6746 6747 6748 6749 6750 6751 6752 6753 6754 | rc = pagerExclusiveLock(pPager); } /* Open the connection to the log file. If this operation fails, ** (e.g. due to malloc() failure), return an error code. */ if( rc==SQLITE_OK ){ #if SQLITE_ENABLE_DATA_PROTECTION rc = sqlite3WalOpen(pPager->pVfs, pPager->fd, pPager->zWal, pPager->exclusiveMode, pPager->journalSizeLimit, (pPager->vfsFlags & SQLITE_OPEN_FILEPROTECTION_MASK), &pPager->pWal); #else rc = sqlite3WalOpen(pPager->pVfs, pPager->fd, pPager->zWal, pPager->exclusiveMode, pPager->journalSizeLimit, 0, &pPager->pWal); #endif } return rc; } /* |
︙ | ︙ |
Changes to src/pragma.c.
︙ | ︙ | |||
437 438 439 440 441 442 443 | assert( pBt!=0 ); if( zRight ){ b = sqlite3GetBoolean(zRight); } if( pId2->n==0 && b>=0 ){ int ii; for(ii=0; ii<db->nDb; ii++){ | | | | 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 | assert( pBt!=0 ); if( zRight ){ b = sqlite3GetBoolean(zRight); } if( pId2->n==0 && b>=0 ){ int ii; for(ii=0; ii<db->nDb; ii++){ sqlite3BtreeSecureDelete(db->aDb[ii].pBt, (int)b); } } b = (int)sqlite3BtreeSecureDelete(pBt, (int)b); returnSingleInt(pParse, "secure_delete", &b); }else /* ** PRAGMA [database.]max_page_count ** PRAGMA [database.]max_page_count=N ** |
︙ | ︙ | |||
560 561 562 563 564 565 566 567 568 569 570 571 572 573 | } } if( eMode==PAGER_JOURNALMODE_QUERY && pId2->n==0 ){ /* Convert "PRAGMA journal_mode" into "PRAGMA main.journal_mode" */ iDb = 0; pId2->n = 1; } for(ii=db->nDb-1; ii>=0; ii--){ if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){ sqlite3VdbeUsesBtree(v, ii); sqlite3VdbeAddOp3(v, OP_JournalMode, ii, 1, eMode); } } sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); | > > > > > > > > | 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 | } } if( eMode==PAGER_JOURNALMODE_QUERY && pId2->n==0 ){ /* Convert "PRAGMA journal_mode" into "PRAGMA main.journal_mode" */ iDb = 0; pId2->n = 1; } #ifdef SQLITE_DEFAULT_WAL_SAFETYLEVEL if (eMode == PAGER_JOURNALMODE_WAL) { /* when entering wal mode, immediately switch the safety_level * so that a query to pragma synchronous returns the correct value */ pDb->safety_level = SQLITE_DEFAULT_WAL_SAFETYLEVEL; } #endif /* SQLITE_DEFAULT_WAL_SAFETYLEVEL */ for(ii=db->nDb-1; ii>=0; ii--){ if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){ sqlite3VdbeUsesBtree(v, ii); sqlite3VdbeAddOp3(v, OP_JournalMode, ii, 1, eMode); } } sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); |
︙ | ︙ |
Changes to src/select.c.
︙ | ︙ | |||
4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 | sqlite3DbFree(db, sAggInfo.aCol); sqlite3DbFree(db, sAggInfo.aFunc); return rc; } #if defined(SQLITE_DEBUG) /* ******************************************************************************* ** The following code is used for testing and debugging only. The code ** that follows does not appear in normal builds. ** ** These routines are used to print out the content of all or part of a ** parse structures such as Select or Expr. Such printouts are useful | > > > | 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 4383 | sqlite3DbFree(db, sAggInfo.aCol); sqlite3DbFree(db, sAggInfo.aFunc); return rc; } #if defined(SQLITE_DEBUG) void sqlite3PrintExpr(Expr *p); void sqlite3PrintExprList(ExprList *pList); void sqlite3PrintSelect(Select *p, int indent); /* ******************************************************************************* ** The following code is used for testing and debugging only. The code ** that follows does not appear in normal builds. ** ** These routines are used to print out the content of all or part of a ** parse structures such as Select or Expr. Such printouts are useful |
︙ | ︙ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
60 61 62 63 64 65 66 67 68 69 70 71 72 73 | ** would generate warning messages when they were used. But that ** compiler magic ended up generating such a flurry of bug reports ** that we have taken it all out and gone back to using simple ** noop macros. */ #define SQLITE_DEPRECATED #define SQLITE_EXPERIMENTAL /* ** Ensure these symbols were not defined by some previous header file. */ #ifdef SQLITE_VERSION # undef SQLITE_VERSION #endif | > > > | 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | ** would generate warning messages when they were used. But that ** compiler magic ended up generating such a flurry of bug reports ** that we have taken it all out and gone back to using simple ** noop macros. */ #define SQLITE_DEPRECATED #define SQLITE_EXPERIMENTAL #ifndef __OSX_AVAILABLE_BUT_DEPRECATED #define __OSX_AVAILABLE_BUT_DEPRECATED(MacOSAvailable, MacOSDeprecated, iPhoneOSAvailable, iPhoneOSDeprecated) #endif /* ** Ensure these symbols were not defined by some previous header file. */ #ifdef SQLITE_VERSION # undef SQLITE_VERSION #endif |
︙ | ︙ | |||
479 480 481 482 483 484 485 486 487 488 489 490 491 492 | #define SQLITE_OPEN_SUBJOURNAL 0x00002000 /* VFS only */ #define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */ #define SQLITE_OPEN_NOMUTEX 0x00008000 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_SHAREDCACHE 0x00020000 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_PRIVATECACHE 0x00040000 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_WAL 0x00080000 /* VFS only */ /* Reserved: 0x00F00000 */ /* ** CAPI3REF: Device Characteristics ** ** The xDeviceCharacteristics method of the [sqlite3_io_methods] | > | 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 | #define SQLITE_OPEN_SUBJOURNAL 0x00002000 /* VFS only */ #define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */ #define SQLITE_OPEN_NOMUTEX 0x00008000 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_SHAREDCACHE 0x00020000 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_PRIVATECACHE 0x00040000 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_WAL 0x00080000 /* VFS only */ #define SQLITE_OPEN_FILEPROTECTION_MASK 0x00700000 /* Reserved: 0x00F00000 */ /* ** CAPI3REF: Device Characteristics ** ** The xDeviceCharacteristics method of the [sqlite3_io_methods] |
︙ | ︙ | |||
4451 4452 4453 4454 4455 4456 4457 4458 4459 | ** ^(This routine returns [SQLITE_OK] if shared cache was enabled or disabled ** successfully. An [error code] is returned otherwise.)^ ** ** ^Shared cache is disabled by default. But this might change in ** future releases of SQLite. Applications that care about shared ** cache setting should set it explicitly. ** ** See Also: [SQLite Shared-Cache Mode] */ | > > > > > | | 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 | ** ^(This routine returns [SQLITE_OK] if shared cache was enabled or disabled ** successfully. An [error code] is returned otherwise.)^ ** ** ^Shared cache is disabled by default. But this might change in ** future releases of SQLite. Applications that care about shared ** cache setting should set it explicitly. ** ** ^Note: This method is deprecated on MacOS X 10.7 and iOS version 5.0 ** and will always return SQLITE_MISUSE, instead of calling this function ** shared cache mode should be enabled per-database connection via ** sqlite3_open_v2 with SQLITE_OPEN_SHAREDCACHE instead. ** ** See Also: [SQLite Shared-Cache Mode] */ int sqlite3_enable_shared_cache(int) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_7, __IPHONE_2_0, __IPHONE_5_0); /* ** CAPI3REF: Attempt To Free Heap Memory ** ** ^The sqlite3_release_memory() interface attempts to free N bytes ** of heap memory by deallocating non-essential memory allocations ** held by the database library. Memory used to cache database |
︙ | ︙ |
Changes to src/sqlite3_private.h.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | /* * sqlite3_private.h */ #ifndef _SQLITE3_PRIVATE_H #define _SQLITE3_PRIVATE_H /* ** Pass the SQLITE_TRUNCATE_DATABASE operation code to sqlite3_file_control() ** to truncate a database and its associated journal file to zero length. */ #define SQLITE_TRUNCATE_DATABASE 101 /* | > > > > > > > > > > > > > > > > > > > > > > | 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 | /* * sqlite3_private.h */ #ifndef _SQLITE3_PRIVATE_H #define _SQLITE3_PRIVATE_H #define SQLITE_LOCKSTATE_OFF 0 #define SQLITE_LOCKSTATE_ON 1 #define SQLITE_LOCKSTATE_NOTADB 2 #define SQLITE_LOCKSTATE_ERROR -1 #define SQLITE_LOCKSTATE_ANYPID -1 /* ** Test a file path for sqlite locks held by a process ID (-1 = any PID). ** Returns one of the following integer codes: ** ** SQLITE_LOCKSTATE_OFF no active sqlite file locks match the specified pid ** SQLITE_LOCKSTATE_ON active sqlite file locks match the specified pid ** SQLITE_LOCKSTATE_NOTADB path points to a file that is not an sqlite db file ** SQLITE_LOCKSTATE_ERROR path was not vaild or was unreadable ** ** There is no support for identifying db files encrypted via SEE encryption ** currently. Zero byte files are tested for sqlite locks, but if no sqlite ** locks are present then SQLITE_LOCKSTATE_NOTADB is returned. */ extern int _sqlite3_lockstate(const char *path, pid_t pid); /* ** Pass the SQLITE_TRUNCATE_DATABASE operation code to sqlite3_file_control() ** to truncate a database and its associated journal file to zero length. */ #define SQLITE_TRUNCATE_DATABASE 101 /* |
︙ | ︙ |
Changes to src/test1.c.
︙ | ︙ | |||
4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 | Tcl_AppendResult(interp, "Unexpected non-zero errno: ", Tcl_GetStringFromObj(Tcl_NewIntObj(iArg), 0), " ", 0); return TCL_ERROR; } return TCL_OK; } /* ** tclcmd: file_control_chunksize_test DB DBNAME SIZE ** ** This TCL command runs the sqlite3_file_control interface and ** verifies correct operation of the SQLITE_GET_LOCKPROXYFILE and ** SQLITE_SET_LOCKPROXYFILE verbs. */ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010 5011 5012 5013 5014 5015 5016 5017 5018 5019 5020 5021 5022 5023 5024 5025 5026 5027 5028 5029 5030 5031 5032 5033 5034 5035 5036 5037 5038 5039 5040 5041 5042 5043 5044 5045 5046 5047 5048 5049 5050 5051 5052 5053 5054 | Tcl_AppendResult(interp, "Unexpected non-zero errno: ", Tcl_GetStringFromObj(Tcl_NewIntObj(iArg), 0), " ", 0); return TCL_ERROR; } return TCL_OK; } #ifdef __APPLE__ /* From sqlite3_priavet.h */ # ifndef SQLITE_TRUNCATE_DATABASE # define SQLITE_TRUNCATE_DATABASE 101 # endif # ifndef SQLITE_REPLACE_DATABASE # define SQLITE_REPLACE_DATABASE 102 # endif /* ** tclcmd: file_control_truncate_test DB ** ** This TCL command runs the sqlite3_file_control interface and ** verifies correct operation of the SQLITE_TRUNCATE_DATABASE verb. */ static int file_control_truncate_test( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ Tcl_Obj *CONST objv[] /* Command arguments */ ){ sqlite3 *db; int rc; if( objc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetStringFromObj(objv[0], 0), " DB", 0); return TCL_ERROR; } if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){ return TCL_ERROR; } rc = sqlite3_file_control(db, NULL, SQLITE_TRUNCATE_DATABASE, 0); if( rc ){ Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); return TCL_ERROR; } return TCL_OK; } /* ** tclcmd: file_control_replace_test DB ** ** This TCL command runs the sqlite3_file_control interface and ** verifies correct operation of the SQLITE_REPLACE_DATABASE verb. */ static int file_control_replace_test( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ Tcl_Obj *CONST objv[] /* Command arguments */ ){ int iArg = 0; sqlite3 *src_db; sqlite3 *dst_db; int rc; if( objc!=3 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetStringFromObj(objv[0], 0), " DST_DB SRC_DB", 0); return TCL_ERROR; } if( getDbPointer(interp, Tcl_GetString(objv[1]), &dst_db) ){ return TCL_ERROR; } if( getDbPointer(interp, Tcl_GetString(objv[2]), &src_db) ){ return TCL_ERROR; } rc = sqlite3_file_control(dst_db, NULL, SQLITE_REPLACE_DATABASE, src_db); if( rc ){ Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); return TCL_ERROR; } return TCL_OK; } #endif /* __APPLE__ */ /* ** tclcmd: file_control_chunksize_test DB DBNAME SIZE ** ** This TCL command runs the sqlite3_file_control interface and ** verifies correct operation of the SQLITE_GET_LOCKPROXYFILE and ** SQLITE_SET_LOCKPROXYFILE verbs. */ |
︙ | ︙ | |||
5907 5908 5909 5910 5911 5912 5913 5914 5915 5916 5917 5918 5919 5920 | { "vfs_unlink_test", vfs_unlink_test, 0 }, { "vfs_initfail_test", vfs_initfail_test, 0 }, { "vfs_unregister_all", vfs_unregister_all, 0 }, { "vfs_reregister_all", vfs_reregister_all, 0 }, { "file_control_test", file_control_test, 0 }, { "file_control_lasterrno_test", file_control_lasterrno_test, 0 }, { "file_control_lockproxy_test", file_control_lockproxy_test, 0 }, { "file_control_chunksize_test", file_control_chunksize_test, 0 }, { "file_control_sizehint_test", file_control_sizehint_test, 0 }, { "sqlite3_vfs_list", vfs_list, 0 }, { "sqlite3_create_function_v2", test_create_function_v2, 0 }, { "path_is_local", path_is_local, 0 }, { "path_is_dos", path_is_dos, 0 }, | > > > > | 5984 5985 5986 5987 5988 5989 5990 5991 5992 5993 5994 5995 5996 5997 5998 5999 6000 6001 | { "vfs_unlink_test", vfs_unlink_test, 0 }, { "vfs_initfail_test", vfs_initfail_test, 0 }, { "vfs_unregister_all", vfs_unregister_all, 0 }, { "vfs_reregister_all", vfs_reregister_all, 0 }, { "file_control_test", file_control_test, 0 }, { "file_control_lasterrno_test", file_control_lasterrno_test, 0 }, { "file_control_lockproxy_test", file_control_lockproxy_test, 0 }, #ifdef __APPLE__ { "file_control_truncate_test", file_control_truncate_test, 0 }, { "file_control_replace_test", file_control_replace_test, 0 }, #endif { "file_control_chunksize_test", file_control_chunksize_test, 0 }, { "file_control_sizehint_test", file_control_sizehint_test, 0 }, { "sqlite3_vfs_list", vfs_list, 0 }, { "sqlite3_create_function_v2", test_create_function_v2, 0 }, { "path_is_local", path_is_local, 0 }, { "path_is_dos", path_is_dos, 0 }, |
︙ | ︙ |
Changes to src/test_config.c.
︙ | ︙ | |||
431 432 433 434 435 436 437 | Tcl_SetVar2(interp,"sqlite_options","lock_proxy_pragmas","0",TCL_GLOBAL_ONLY); #endif #if defined(SQLITE_PREFER_PROXY_LOCKING) && defined(__APPLE__) Tcl_SetVar2(interp,"sqlite_options","prefer_proxy_locking","1",TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp,"sqlite_options","prefer_proxy_locking","0",TCL_GLOBAL_ONLY); #endif | | > > > > > > > > > > | 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 | Tcl_SetVar2(interp,"sqlite_options","lock_proxy_pragmas","0",TCL_GLOBAL_ONLY); #endif #if defined(SQLITE_PREFER_PROXY_LOCKING) && defined(__APPLE__) Tcl_SetVar2(interp,"sqlite_options","prefer_proxy_locking","1",TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp,"sqlite_options","prefer_proxy_locking","0",TCL_GLOBAL_ONLY); #endif #if SQLITE_DEFAULT_CKPTFULLFSYNC Tcl_SetVar2(interp,"sqlite_options","default_ckptfullfsync","1",TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp,"sqlite_options","default_ckptfullfsync","0",TCL_GLOBAL_ONLY); #endif #if SQLITE_DEFAULT_WAL_SAFETYLEVEL Tcl_SetVar2(interp,"sqlite_options","default_wal_safetylevel", STRINGVALUE(SQLITE_DEFAULT_WAL_SAFETYLEVEL),TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp,"sqlite_options","default_wal_safetylevel","0",TCL_GLOBAL_ONLY); #endif #ifdef SQLITE_OMIT_SHARED_CACHE Tcl_SetVar2(interp, "sqlite_options", "shared_cache", "0", TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp, "sqlite_options", "shared_cache", "1", TCL_GLOBAL_ONLY); #endif |
︙ | ︙ |
Changes to src/test_rtree.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing all sorts of SQLite interfaces. This code ** is not included in the SQLite library. */ | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing all sorts of SQLite interfaces. This code ** is not included in the SQLite library. */ #include "sqlite3.h" /* Solely for the UNUSED_PARAMETER() macro. */ #include "sqliteInt.h" /* ** Type used to cache parameter information for the "circle" r-tree geometry ** callback. |
︙ | ︙ |
Changes to src/test_superlock.c.
︙ | ︙ | |||
14 15 16 17 18 19 20 | ** mode database files. The interface to the example code in this file ** consists of the following two functions: ** ** sqlite3demo_superlock() ** sqlite3demo_superunlock() */ | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | ** mode database files. The interface to the example code in this file ** consists of the following two functions: ** ** sqlite3demo_superlock() ** sqlite3demo_superunlock() */ #include "sqlite3.h" #include <string.h> /* memset(), strlen() */ #include <assert.h> /* assert() */ /* ** A structure to collect a busy-handler callback and argument and a count ** of the number of times it has been invoked. */ |
︙ | ︙ | |||
144 145 146 147 148 149 150 | } /* ** Release a superlock held on a database file. The argument passed to ** this function must have been obtained from a successful call to ** sqlite3demo_superlock(). */ | | | 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | } /* ** Release a superlock held on a database file. The argument passed to ** this function must have been obtained from a successful call to ** sqlite3demo_superlock(). */ static void sqlite3demo_superunlock(void *pLock){ Superlock *p = (Superlock *)pLock; if( p->bWal ){ int rc; /* Return code */ int flags = SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE; sqlite3_file *fd = 0; rc = sqlite3_file_control(p->db, "main", SQLITE_FCNTL_FILE_POINTER, (void *)&fd); if( rc==SQLITE_OK ){ |
︙ | ︙ | |||
175 176 177 178 179 180 181 | ** ** If a required lock cannot be obtained immediately and the xBusy parameter ** to this function is not NULL, then xBusy is invoked in the same way ** as a busy-handler registered with SQLite (using sqlite3_busy_handler()) ** until either the lock can be obtained or the busy-handler function returns ** 0 (indicating "give up"). */ | | > | | 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 | ** ** If a required lock cannot be obtained immediately and the xBusy parameter ** to this function is not NULL, then xBusy is invoked in the same way ** as a busy-handler registered with SQLite (using sqlite3_busy_handler()) ** until either the lock can be obtained or the busy-handler function returns ** 0 (indicating "give up"). */ static int sqlite3demo_superlock( const char *zPath, /* Path to database file to lock */ const char *zVfs, /* VFS to use to access database file */ int flags, /* Additional flags to pass to sqlite3_open_v2 */ int (*xBusy)(void*,int), /* Busy handler callback */ void *pBusyArg, /* Context arg for busy handler */ void **ppLock /* OUT: Context to pass to superunlock() */ ){ SuperlockBusy busy = {0, 0, 0}; /* Busy handler wrapper object */ int rc; /* Return code */ Superlock *pLock; pLock = sqlite3_malloc(sizeof(Superlock)); if( !pLock ) return SQLITE_NOMEM; memset(pLock, 0, sizeof(Superlock)); /* Open a database handle on the file to superlock. */ rc = sqlite3_open_v2( zPath, &pLock->db, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|flags, zVfs ); /* Install a busy-handler and execute a BEGIN EXCLUSIVE. If this is not ** a WAL database, this is all we need to do. ** ** A wrapper function is used to invoke the busy-handler instead of ** registering the busy-handler function supplied by the user directly |
︙ | ︙ | |||
327 328 329 330 331 332 333 | } if( objc>4 ){ busy.interp = interp; busy.pScript = objv[4]; xBusy = superlock_busy; } | | | 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 | } if( objc>4 ){ busy.interp = interp; busy.pScript = objv[4]; xBusy = superlock_busy; } rc = sqlite3demo_superlock(zPath, zVfs, 0, xBusy, &busy, &pLock); assert( rc==SQLITE_OK || pLock==0 ); assert( rc!=SQLITE_OK || pLock!=0 ); if( rc!=SQLITE_OK ){ extern const char *sqlite3ErrStr(int); Tcl_ResetResult(interp); Tcl_AppendResult(interp, sqlite3ErrStr(rc), 0); |
︙ | ︙ |
Changes to src/vdbetrace.c.
︙ | ︙ | |||
79 80 81 82 83 84 85 86 87 | db = p->db; sqlite3StrAccumInit(&out, zBase, sizeof(zBase), db->aLimit[SQLITE_LIMIT_LENGTH]); out.db = db; if( db->vdbeExecCnt>1 ){ while( *zRawSql ){ const char *zStart = zRawSql; while( *(zRawSql++)!='\n' && *zRawSql ); sqlite3StrAccumAppend(&out, "-- ", 3); | > > > | | 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | db = p->db; sqlite3StrAccumInit(&out, zBase, sizeof(zBase), db->aLimit[SQLITE_LIMIT_LENGTH]); out.db = db; if( db->vdbeExecCnt>1 ){ while( *zRawSql ){ const char *zStart = zRawSql; sqlite_int64 iStart = SQLITE_PTR_TO_INT(zRawSql); sqlite_int64 iCurrent; while( *(zRawSql++)!='\n' && *zRawSql ); sqlite3StrAccumAppend(&out, "-- ", 3); iCurrent = SQLITE_PTR_TO_INT(zRawSql); sqlite3StrAccumAppend(&out, zStart, (int)(iCurrent-iStart)); } }else{ while( zRawSql[0] ){ n = findNextHostParameter(zRawSql, &nToken); assert( n>0 ); sqlite3StrAccumAppend(&out, zRawSql, n); zRawSql += n; |
︙ | ︙ |
Changes to src/wal.c.
︙ | ︙ | |||
1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 | */ int sqlite3WalOpen( sqlite3_vfs *pVfs, /* vfs module to open wal and wal-index */ sqlite3_file *pDbFd, /* The open database file */ const char *zWalName, /* Name of the WAL file */ int bNoShm, /* True to run in heap-memory mode */ i64 mxWalSize, /* Truncate WAL to this size on reset */ Wal **ppWal /* OUT: Allocated Wal handle */ ){ int rc; /* Return Code */ Wal *pRet; /* Object to allocate and return */ | > | | 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 | */ int sqlite3WalOpen( sqlite3_vfs *pVfs, /* vfs module to open wal and wal-index */ sqlite3_file *pDbFd, /* The open database file */ const char *zWalName, /* Name of the WAL file */ int bNoShm, /* True to run in heap-memory mode */ i64 mxWalSize, /* Truncate WAL to this size on reset */ int flags, /* VFS file protection flags */ Wal **ppWal /* OUT: Allocated Wal handle */ ){ int rc; /* Return Code */ Wal *pRet; /* Object to allocate and return */ int vfsFlags; /* Flags passed to OsOpen() */ assert( zWalName && zWalName[0] ); assert( pDbFd ); /* In the amalgamation, the os_unix.c and os_win.c source files come before ** this source file. Verify that the #defines of the locking byte offsets ** in os_unix.c and os_win.c agree with the WALINDEX_LOCK_OFFSET value. |
︙ | ︙ | |||
1280 1281 1282 1283 1284 1285 1286 | pRet->pDbFd = pDbFd; pRet->readLock = -1; pRet->mxWalSize = mxWalSize; pRet->zWalName = zWalName; pRet->exclusiveMode = (bNoShm ? WAL_HEAPMEMORY_MODE: WAL_NORMAL_MODE); /* Open file handle on the write-ahead log file. */ | | | | | 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 | pRet->pDbFd = pDbFd; pRet->readLock = -1; pRet->mxWalSize = mxWalSize; pRet->zWalName = zWalName; pRet->exclusiveMode = (bNoShm ? WAL_HEAPMEMORY_MODE: WAL_NORMAL_MODE); /* Open file handle on the write-ahead log file. */ vfsFlags = flags | (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_WAL); rc = sqlite3OsOpen(pVfs, zWalName, pRet->pWalFd, vfsFlags, &vfsFlags); if( rc==SQLITE_OK && vfsFlags&SQLITE_OPEN_READONLY ){ pRet->readOnly = WAL_RDONLY; } if( rc!=SQLITE_OK ){ walIndexClose(pRet, 0); sqlite3OsClose(pRet->pWalFd); sqlite3_free(pRet); |
︙ | ︙ |
Changes to src/wal.h.
︙ | ︙ | |||
43 44 45 46 47 48 49 | /* Connection to a write-ahead log (WAL) file. ** There is one object of this type for each pager. */ typedef struct Wal Wal; /* Open and close a connection to a write-ahead log. */ | | | 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | /* Connection to a write-ahead log (WAL) file. ** There is one object of this type for each pager. */ typedef struct Wal Wal; /* Open and close a connection to a write-ahead log. */ int sqlite3WalOpen(sqlite3_vfs*, sqlite3_file*, const char *, int, i64, int, Wal**); int sqlite3WalClose(Wal *pWal, int sync_flags, int, u8 *); /* Set the limiting size of a WAL file. */ void sqlite3WalLimit(Wal*, i64); /* Used by readers to open (lock) and close (unlock) a snapshot. A ** snapshot is like a read-transaction. It is the state of the database |
︙ | ︙ |
Changes to test/fallocate.test.
︙ | ︙ | |||
77 78 79 80 81 82 83 84 85 86 87 88 89 90 | }] ifcapable !wal { set skipwaltests 1 } if {![wal_is_ok]} { set skipwaltests 1 } if {!$skipwaltests} { db close file delete -force test.db sqlite3 db test.db file_control_chunksize_test db main [expr 32*1024] do_test fallocate-2.1 { execsql { PRAGMA page_size = 1024; PRAGMA journal_mode = WAL; | > | 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | }] ifcapable !wal { set skipwaltests 1 } if {![wal_is_ok]} { set skipwaltests 1 } if {!$skipwaltests} { db close file delete -force test.db if {[forced_proxy_locking]} { file delete -force .test.db-conch } sqlite3 db test.db file_control_chunksize_test db main [expr 32*1024] do_test fallocate-2.1 { execsql { PRAGMA page_size = 1024; PRAGMA journal_mode = WAL; |
︙ | ︙ |
Changes to test/incrblob3.test.
︙ | ︙ | |||
256 257 258 259 260 261 262 | set dbversion [hexio_get_int [hexio_read test.db 24 4]] incr dbversion hexio_write test.db 24 [hexio_render_int32 $dbversion] return "" } | > > > > | | | | | | > | 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 | set dbversion [hexio_get_int [hexio_read test.db 24 4]] incr dbversion hexio_write test.db 24 [hexio_render_int32 $dbversion] return "" } #set sqlite_os_trace 1 # AFP asserts because the "db incrblob blobs v 1" clears the file locks and the unlock fails (HFS doesn't care about a failed unlock) if {[path_is_local "."]} { do_test incrblob3-7.2 { sqlite3 db test.db sqlite3_db_config_lookaside db 0 0 0 list [catch {db incrblob blobs v 1} msg] $msg } {1 {database schema has changed}} db close } tvfs delete finish_test |
Changes to test/multiplex.test.
︙ | ︙ | |||
9 10 11 12 13 14 15 16 17 18 19 20 21 22 | # #*********************************************************************** # set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/malloc_common.tcl set g_chunk_size [ expr ($::SQLITE_MAX_PAGE_SIZE*16384) ] set g_max_chunks 32 # This handles appending the chunk number # to the end of the filename. if # SQLITE_MULTIPLEX_EXT_OVWR is defined, then | > > > > > > | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | # #*********************************************************************** # set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/malloc_common.tcl # AFP doesn't like multiplex db tests if { ![path_is_local "."] } { finish_test return } set g_chunk_size [ expr ($::SQLITE_MAX_PAGE_SIZE*16384) ] set g_max_chunks 32 # This handles appending the chunk number # to the end of the filename. if # SQLITE_MULTIPLEX_EXT_OVWR is defined, then |
︙ | ︙ |
Changes to test/pager1.test.
︙ | ︙ | |||
530 531 532 533 534 535 536 537 538 539 540 541 542 543 | set ::mj_filename_length [string length $filename] faultsim_save } return SQLITE_OK } set pwd [pwd] foreach {tn1 tcl} { 1 { set prefix "test.db" } 2 { # This test depends on the underlying VFS being able to open paths # 512 bytes in length. The idea is to create a hot-journal file that # contains a master-journal pointer so large that it could contain # a valid page record (if the file page-size is 512 bytes). So as to | > > | 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 | set ::mj_filename_length [string length $filename] faultsim_save } return SQLITE_OK } set pwd [pwd] if {![forced_proxy_locking]} { # proxy locking uses can't deal with auto proxy file paths longer than MAXPATHLEN foreach {tn1 tcl} { 1 { set prefix "test.db" } 2 { # This test depends on the underlying VFS being able to open paths # 512 bytes in length. The idea is to create a hot-journal file that # contains a master-journal pointer so large that it could contain # a valid page record (if the file page-size is 512 bytes). So as to |
︙ | ︙ | |||
661 662 663 664 665 666 667 668 669 670 671 672 673 674 | } cd $pwd } db close tv delete file delete -force $dirname # Set up a VFS to make a copy of the file-system just before deleting a # journal file to commit a transaction. The transaction modifies exactly # two database pages (and page 1 - the change counter). # testvfs tv -default 1 | > | 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 | } cd $pwd } db close tv delete file delete -force $dirname } # Set up a VFS to make a copy of the file-system just before deleting a # journal file to commit a transaction. The transaction modifies exactly # two database pages (and page 1 - the change counter). # testvfs tv -default 1 |
︙ | ︙ | |||
2004 2005 2006 2007 2008 2009 2010 | testvfs tv -default 1 tv filter xSync tv script xSyncCb proc xSyncCb {args} {incr ::synccount} set ::synccount 0 sqlite3 db test.db execsql { | < > | 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 | testvfs tv -default 1 tv filter xSync tv script xSyncCb proc xSyncCb {args} {incr ::synccount} set ::synccount 0 sqlite3 db test.db execsql { PRAGMA journal_mode = WAL; PRAGMA synchronous = off; INSERT INTO ko DEFAULT VALUES; } execsql { PRAGMA wal_checkpoint } set synccount } {0} db close tv delete |
︙ | ︙ |
Changes to test/pragma.test.
︙ | ︙ | |||
1344 1345 1346 1347 1348 1349 1350 | sqlite3 db2 test.db execsql "PRAGMA lock_proxy_file='$lpp2'" db2 catchsql { select * from sqlite_master; } db2 } {1 {database is locked}} | | | 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 | sqlite3 db2 test.db execsql "PRAGMA lock_proxy_file='$lpp2'" db2 catchsql { select * from sqlite_master; } db2 } {1 {database is locked}} set lpp3 [exec mktemp -t "proxy3"] # lock proxy file can be renamed if no other connections are active do_test pragma-16.4 { db2 close db close sqlite3 db2 test.db execsql "PRAGMA lock_proxy_file='$lpp3'" db2 |
︙ | ︙ | |||
1400 1401 1402 1403 1404 1405 1406 | list [catch { sqlite3 db test2.db execsql { select * from sqlite_master } } msg] $msg } {1 {database is locked}} db2 close | | | 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 | list [catch { sqlite3 db test2.db execsql { select * from sqlite_master } } msg] $msg } {1 {database is locked}} db2 close set lpp4 [exec mktemp -t "proxy4"] # check that db is unlocked after first host connection closes do_test pragma-16.8.1 { execsql "PRAGMA lock_proxy_file='$lpp4'" execsql "select * from sqlite_master" execsql "PRAGMA lock_proxy_file" } $lpp4 |
︙ | ︙ | |||
1429 1430 1431 1432 1433 1434 1435 | PRAGMA lock_proxy_file=":auto:"; PRAGMA lock_proxy_file; } db] string match "*proxytest.db:auto:" $lockpath2 } {1} # ensure creating directories for a lock proxy file works | | > < | | | < | > | | | | | 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 | PRAGMA lock_proxy_file=":auto:"; PRAGMA lock_proxy_file; } db] string match "*proxytest.db:auto:" $lockpath2 } {1} # ensure creating directories for a lock proxy file works set lpp5d [exec mktemp -d -t "proxy5"] set lpp5 $lpp5d/sub/dir/lock db close do_test pragma-16.10.1 { sqlite3 db proxytest.db execsql "PRAGMA lock_proxy_file='$lpp5'" set lockpath2 [execsql { PRAGMA lock_proxy_file; } db] string match "*sub/dir/lock" $lockpath2 } {1} # ensure that after deleting the path, setting ":auto:" works correctly db close file delete -force $lpp5d do_test pragma-16.10.2 { sqlite3 db proxytest.db set lockpath3 [execsql { PRAGMA lock_proxy_file=":auto:"; create table if not exists pt(y); PRAGMA lock_proxy_file; } db] string match "*sub/dir/lock" $lockpath3 } {1} # ensure that if the path can not be created (file instead of dir) # setting :auto: deals with it by creating a new autonamed lock file db close file delete -force $lpp5d close [open "$lpp5d" a] do_test pragma-16.10.3 { sqlite3 db proxytest.db set lockpath2 [execsql { PRAGMA lock_proxy_file=":auto:"; create table if not exists zz(y); PRAGMA lock_proxy_file; } db] string match "*proxytest.db:auto:" $lockpath2 } {1} # make sure we can deal with ugly file paths correctly db close file delete -force $lpp5d set lpp6 [exec mktemp -d -t "proxy6"]/./././////./proxytest/../proxytest/sub/dir/lock do_test pragma-16.10.4 { sqlite3 db proxytest.db execsql "PRAGMA lock_proxy_file='$lpp6'" set lockpath4 [execsql { create table if not exists aa(bb); PRAGMA lock_proxy_file; } db] string match "*proxytest/sub/dir/lock" $lockpath4 } {1} # ensure that if the path can not be created (perm), setting :auto: deals db close file delete -force $lpp5d do_test pragma-16.10.5 { sqlite3 db proxytest.db execsql "PRAGMA lock_proxy_file='$lpp5'" execsql { create table if not exists bb(bb); } db close file delete -force $lpp5d file mkdir $lpp5d file attributes $lpp5d -permission 0000 sqlite3 db proxytest.db set lockpath5 [execsql { PRAGMA lock_proxy_file=":auto:"; create table if not exists cc(bb); PRAGMA lock_proxy_file; } db] string match "*proxytest.db:auto:" $lockpath5 |
︙ | ︙ | |||
1517 1518 1519 1520 1521 1522 1523 | catchsql { create table if not exists faily(y); PRAGMA lock_proxy_file; } db } {1 {database is locked}} db close | | | | 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 | catchsql { create table if not exists faily(y); PRAGMA lock_proxy_file; } db } {1 {database is locked}} db close file attributes $lpp5d -permission 0777 file delete -force $lpp5d set env(SQLITE_FORCE_PROXY_LOCKING) $using_proxy set sqlite_hostid_num 0 } # Parsing of auto_vacuum settings. # |
︙ | ︙ |
Changes to test/superlock.test.
︙ | ︙ | |||
47 48 49 50 51 52 53 54 55 56 57 58 59 60 | INSERT INTO t1 VALUES(1, 2); PRAGMA journal_mode = DELETE; } {delete} do_test 1.2 { sqlite3demo_superlock unlock test.db } {unlock} do_catchsql_test 1.3 { SELECT * FROM t1 } {1 {database is locked}} do_test 1.4 { unlock } {} do_execsql_test 2.1 { INSERT INTO t1 VALUES(3, 4); PRAGMA journal_mode = WAL; } {wal} do_test 2.2 { sqlite3demo_superlock unlock test.db } {unlock} | > > > > > > | 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | INSERT INTO t1 VALUES(1, 2); PRAGMA journal_mode = DELETE; } {delete} do_test 1.2 { sqlite3demo_superlock unlock test.db } {unlock} do_catchsql_test 1.3 { SELECT * FROM t1 } {1 {database is locked}} do_test 1.4 { unlock } {} ifcapable !wal {finish_test ; return } if { ![wal_is_ok] } { finish_test return } do_execsql_test 2.1 { INSERT INTO t1 VALUES(3, 4); PRAGMA journal_mode = WAL; } {wal} do_test 2.2 { sqlite3demo_superlock unlock test.db } {unlock} |
︙ | ︙ |
Changes to test/tester.tcl.
︙ | ︙ | |||
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 | } # Update the soft-heap-limit each time this script is run. In that # way if an individual test file changes the soft-heap-limit, it # will be reset at the start of the next test file. # sqlite3_soft_heap_limit $cmdlinearg(soft-heap-limit) # Create a test database # proc reset_db {} { catch {db close} file delete -force test.db file delete -force test.db-journal file delete -force test.db-wal sqlite3 db ./test.db set ::DB [sqlite3_connection_pointer db] if {[info exists ::SETUP_SQL]} { db eval $::SETUP_SQL } } reset_db | > > > > > > > > > > > > > > > > > > > > > > > > > | 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 283 | } # Update the soft-heap-limit each time this script is run. In that # way if an individual test file changes the soft-heap-limit, it # will be reset at the start of the next test file. # sqlite3_soft_heap_limit $cmdlinearg(soft-heap-limit) proc forced_proxy_locking {} { if $::sqlite_options(lock_proxy_pragmas)&&$::sqlite_options(prefer_proxy_locking) { set force_proxy_value 0 set force_key "SQLITE_FORCE_PROXY_LOCKING=" foreach {env_pair} [exec env] { if { [string first $force_key $env_pair] == 0} { set force_proxy_value [string range $env_pair [string length $force_key] end] } } if { "$force_proxy_value " == "1 " } { return 1 } } return 0 } # Create a test database # proc reset_db {} { catch {db close} file delete -force test.db file delete -force test.db-journal file delete -force test.db-wal if {[forced_proxy_locking]} { sqlite3 db ./test.db set lock_proxy_path [db eval "PRAGMA lock_proxy_file;"] catch {db close} # puts "deleting $lock_proxy_path" file delete -force $lock_proxy_path file delete -force test.db } sqlite3 db ./test.db set ::DB [sqlite3_connection_pointer db] if {[info exists ::SETUP_SQL]} { db eval $::SETUP_SQL } } reset_db |
︙ | ︙ | |||
1330 1331 1332 1333 1334 1335 1336 | } proc presql {} { set presql "" catch {set presql $::G(perm:presql)} set presql } | < < < < < < < < < < < < < < < < | 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 | } proc presql {} { set presql "" catch {set presql $::G(perm:presql)} set presql } proc wal_is_ok {} { if { [forced_proxy_locking] } { return 1 } if { ![path_is_local "."] } { return 0 } |
︙ | ︙ |
Changes to test/wal2.test.
︙ | ︙ | |||
1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 | # Test that "PRAGMA checkpoint_fullsync" appears to be working. # foreach {tn sql reslist} { 1 { } {8 0 3 0 5 0} 2 { PRAGMA checkpoint_fullfsync = 1 } {8 4 3 2 5 2} 3 { PRAGMA checkpoint_fullfsync = 0 } {8 0 3 0 5 0} } { faultsim_delete_and_reopen execsql {PRAGMA auto_vacuum = 0} execsql $sql do_execsql_test wal2-14.$tn.1 { PRAGMA journal_mode = WAL } {wal} set sqlite_sync_count 0 | > > > > > | 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 | # Test that "PRAGMA checkpoint_fullsync" appears to be working. # foreach {tn sql reslist} { 1 { } {8 0 3 0 5 0} 2 { PRAGMA checkpoint_fullfsync = 1 } {8 4 3 2 5 2} 3 { PRAGMA checkpoint_fullfsync = 0 } {8 0 3 0 5 0} } { if { $::sqlite_options(default_ckptfullfsync) && $tn == 1} { # checkpoint_fullfsync on by default set reslist {8 4 3 2 5 2} } faultsim_delete_and_reopen execsql {PRAGMA auto_vacuum = 0} execsql $sql do_execsql_test wal2-14.$tn.1 { PRAGMA journal_mode = WAL } {wal} set sqlite_sync_count 0 |
︙ | ︙ |
Changes to test/wal3.test.
︙ | ︙ | |||
202 203 204 205 206 207 208 209 210 211 212 213 214 215 | 1 off {} 2 normal {test.db-wal normal test.db normal} 3 full {test.db-wal normal test.db-wal normal test.db-wal normal test.db normal} } { proc sync_counter {args} { foreach {method filename id flags} $args break lappend ::syncs [file tail $filename] $flags } do_test wal3-3.$tn { file delete -force test.db test.db-wal test.db-journal | > > > > > > > > > > | 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 | 1 off {} 2 normal {test.db-wal normal test.db normal} 3 full {test.db-wal normal test.db-wal normal test.db-wal normal test.db normal} } { if { $::sqlite_options(default_ckptfullfsync) } { # checkpoint_fullfsync on by default if { $tn == 2} { set synccount {test.db-wal full test.db full} } if { $tn == 3} { set synccount {test.db-wal normal test.db-wal normal test.db-wal full test.db full} } } proc sync_counter {args} { foreach {method filename id flags} $args break lappend ::syncs [file tail $filename] $flags } do_test wal3-3.$tn { file delete -force test.db test.db-wal test.db-journal |
︙ | ︙ |
Changes to test/wal6.test.
︙ | ︙ | |||
15 16 17 18 19 20 21 22 23 24 25 26 27 28 | set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/lock_common.tcl source $testdir/wal_common.tcl source $testdir/malloc_common.tcl ifcapable !wal {finish_test ; return } #------------------------------------------------------------------------- # Changing to WAL mode in one connection forces the change in others. # db close forcedelete test.db | > > | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/lock_common.tcl source $testdir/wal_common.tcl source $testdir/malloc_common.tcl ifcapable !wal {finish_test ; return } if { ![wal_is_ok] } {finish_test ; return } #------------------------------------------------------------------------- # Changing to WAL mode in one connection forces the change in others. # db close forcedelete test.db |
︙ | ︙ |
Changes to test/walcrash2.test.
︙ | ︙ | |||
12 13 14 15 16 17 18 | set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/lock_common.tcl source $testdir/wal_common.tcl ifcapable !wal {finish_test ; return } | | < < < | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/lock_common.tcl source $testdir/wal_common.tcl ifcapable !wal {finish_test ; return } if { ![wal_is_ok] } { finish_test ; return } #------------------------------------------------------------------------- # This test case demonstrates a flaw in the wal-index manipulation that # existed at one point: If a process crashes mid-transaction, it may have # already added some entries to one of the hash-tables in the wal-index. # If the transaction were to be explicitly rolled back at this point, the |
︙ | ︙ |
Changes to test/walro.test.
︙ | ︙ | |||
19 20 21 22 23 24 25 26 27 28 29 30 31 32 | # These tests are only going to work on unix. # if {$::tcl_platform(platform) != "unix"} { finish_test return } do_multiclient_test tn { # Do not run tests with the connections in the same process. # if {$tn==2} continue # Close all connections and delete the database. | > > > > > > > | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | # These tests are only going to work on unix. # if {$::tcl_platform(platform) != "unix"} { finish_test return } # these tests can't deal with the location of the -shm file under proxy locking # if {[forced_proxy_locking]} { finish_test return } do_multiclient_test tn { # Do not run tests with the connections in the same process. # if {$tn==2} continue # Close all connections and delete the database. |
︙ | ︙ |