mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
Continuing work on the os_unix.c refactoring. Removed all of the
LOCKING_STYLE_* constants and instead pass around pointers to the underlying sqlite3_io_method objects. (CVS 5966) FossilOrigin-Name: 1017d2fb1935a278ef442030bf7bdf5e112c566a
This commit is contained in:
16
manifest
16
manifest
@@ -1,5 +1,5 @@
|
|||||||
C First\sstep\sin\srefactoring\sos_unix.c.\s\sThis\sis\swork\sin\sprogress.\s\sThe\scode\ncompiles\sand\sruns\son\sLinux\sand\sMacOSX\s(as\slong\sas\sSQLITE_ENABLE_LOCKING_STYLE\nis\sturned\soff),\sbut\sthere\sare\sa\sfew\stest\sfailures.\s(CVS\s5965)
|
C Continuing\swork\son\sthe\sos_unix.c\srefactoring.\s\sRemoved\sall\sof\sthe\nLOCKING_STYLE_*\sconstants\sand\sinstead\spass\saround\spointers\sto\sthe\nunderlying\ssqlite3_io_method\sobjects.\s(CVS\s5966)
|
||||||
D 2008-11-28T15:37:20
|
D 2008-11-29T00:56:53
|
||||||
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
||||||
F Makefile.in 0aa7bbe3be6acc4045706e3bb3fd0b8f38f4a3b5
|
F Makefile.in 0aa7bbe3be6acc4045706e3bb3fd0b8f38f4a3b5
|
||||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||||
@@ -137,7 +137,7 @@ F src/os.c 0b411644b87ad689d7250bbfd1834d99b81a3df4
|
|||||||
F src/os.h ef8abeb9afc694b82dbd169a91c9b7e26db3c892
|
F src/os.h ef8abeb9afc694b82dbd169a91c9b7e26db3c892
|
||||||
F src/os_common.h 24525d8b7bce66c374dfc1810a6c9043f3359b60
|
F src/os_common.h 24525d8b7bce66c374dfc1810a6c9043f3359b60
|
||||||
F src/os_os2.c 36196e71292a44bf2d393413cd8c86199694b8b4
|
F src/os_os2.c 36196e71292a44bf2d393413cd8c86199694b8b4
|
||||||
F src/os_unix.c 26f4b3dde5bac6ba8c8dc86a547a4053d5f9cfc3
|
F src/os_unix.c 9c5269d610ec2d43a19733e964e89f3e61323b29
|
||||||
F src/os_win.c 3dff41670fb9798a869c636626bb7d6d8b6a45bb
|
F src/os_win.c 3dff41670fb9798a869c636626bb7d6d8b6a45bb
|
||||||
F src/pager.c 2e9182e181bbd3d758436d9ccce2a3910400dd30
|
F src/pager.c 2e9182e181bbd3d758436d9ccce2a3910400dd30
|
||||||
F src/pager.h a02ef8e6cc7e78b54874166e5ce786c9d4c489bf
|
F src/pager.h a02ef8e6cc7e78b54874166e5ce786c9d4c489bf
|
||||||
@@ -159,7 +159,7 @@ F src/sqliteLimit.h f435e728c6b620ef7312814d660a81f9356eb5c8
|
|||||||
F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76
|
F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76
|
||||||
F src/table.c 22744786199c9195720c15a7a42cb97b2e2728d8
|
F src/table.c 22744786199c9195720c15a7a42cb97b2e2728d8
|
||||||
F src/tclsqlite.c 96049bd454f1547abff0a57c45f0dfa57701e076
|
F src/tclsqlite.c 96049bd454f1547abff0a57c45f0dfa57701e076
|
||||||
F src/test1.c f407faafb17ad328057fe86800518a64046e2766
|
F src/test1.c 737638299302ef85e34f6d04c40d8155db251736
|
||||||
F src/test2.c 897528183edf2839c2a3c991d415905db56f1240
|
F src/test2.c 897528183edf2839c2a3c991d415905db56f1240
|
||||||
F src/test3.c 88a246b56b824275300e6c899634fbac1dc94b14
|
F src/test3.c 88a246b56b824275300e6c899634fbac1dc94b14
|
||||||
F src/test4.c f79ab52d27ff49b784b631a42e2ccd52cfd5c84c
|
F src/test4.c f79ab52d27ff49b784b631a42e2ccd52cfd5c84c
|
||||||
@@ -171,7 +171,7 @@ F src/test9.c 904ebe0ed1472d6bad17a81e2ecbfc20017dc237
|
|||||||
F src/test_async.c 45024094ed7cf780c5d5dccda645145f95cf78ef
|
F src/test_async.c 45024094ed7cf780c5d5dccda645145f95cf78ef
|
||||||
F src/test_autoext.c f53b0cdf7bf5f08100009572a5d65cdb540bd0ad
|
F src/test_autoext.c f53b0cdf7bf5f08100009572a5d65cdb540bd0ad
|
||||||
F src/test_btree.c d7b8716544611c323860370ee364e897c861f1b0
|
F src/test_btree.c d7b8716544611c323860370ee364e897c861f1b0
|
||||||
F src/test_config.c 47c66ced0faa6b18fbab72cbe77098ee04789722
|
F src/test_config.c 4fcc391cbd5d2334c67cf3ec643c2c2bcc3025fa
|
||||||
F src/test_devsym.c 802d10e65b4217208cb47059b84adf46318bcdf4
|
F src/test_devsym.c 802d10e65b4217208cb47059b84adf46318bcdf4
|
||||||
F src/test_func.c a55c4d5479ff2eb5c0a22d4d88e9528ab59c953b
|
F src/test_func.c a55c4d5479ff2eb5c0a22d4d88e9528ab59c953b
|
||||||
F src/test_hexio.c 2f1122aa3f012fa0142ee3c36ce5c902a70cd12f
|
F src/test_hexio.c 2f1122aa3f012fa0142ee3c36ce5c902a70cd12f
|
||||||
@@ -662,7 +662,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
|
|||||||
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||||
P f9c7359065829b016d8cd04304c02509c254fe05
|
P 7825cd63e5cb390a9c2c05957ebc9b189612f04a
|
||||||
R f18bbe219fdf4c9d3849fc41eab92317
|
R 2259cba8f622d2dabcb4ffff89e3fb5a
|
||||||
U drh
|
U drh
|
||||||
Z 31ecaef0fd8fa5ecc70a0ec198476cc9
|
Z 276dfeea88fd39cbd9c4b8d08e052ab2
|
||||||
|
@@ -1 +1 @@
|
|||||||
7825cd63e5cb390a9c2c05957ebc9b189612f04a
|
1017d2fb1935a278ef442030bf7bdf5e112c566a
|
678
src/os_unix.c
678
src/os_unix.c
@@ -40,7 +40,7 @@
|
|||||||
** * sqlite3_file methods not associated with locking
|
** * sqlite3_file methods not associated with locking
|
||||||
** * Implementations of sqlite3_os_init() and sqlite3_os_end()
|
** * Implementations of sqlite3_os_init() and sqlite3_os_end()
|
||||||
**
|
**
|
||||||
** $Id: os_unix.c,v 1.222 2008/11/28 15:37:20 drh Exp $
|
** $Id: os_unix.c,v 1.223 2008/11/29 00:56:53 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#if SQLITE_OS_UNIX /* This file is used on unix only */
|
#if SQLITE_OS_UNIX /* This file is used on unix only */
|
||||||
@@ -156,49 +156,6 @@
|
|||||||
*/
|
*/
|
||||||
#define MAX_PATHNAME 512
|
#define MAX_PATHNAME 512
|
||||||
|
|
||||||
/*
|
|
||||||
** The locking styles are associated with the different file locking
|
|
||||||
** capabilities supported by different file systems.
|
|
||||||
**
|
|
||||||
** POSIX support for shared and exclusive byte-range locks
|
|
||||||
**
|
|
||||||
** NONE no locking will be attempted, this is only used for
|
|
||||||
** read-only file systems currently
|
|
||||||
**
|
|
||||||
** DOTLOCK isn't a true locking style, it refers to the use of a special
|
|
||||||
** file named the same as the database file with a '.lock'
|
|
||||||
** extension, this can be used on file systems that do not
|
|
||||||
** offer any reliable file locking
|
|
||||||
**
|
|
||||||
** FLOCK only a single file-global exclusive lock (Not on VxWorks)
|
|
||||||
**
|
|
||||||
** NAMEDSEM similar to DOTLOCK but uses a named semaphore instead of an
|
|
||||||
** indicator file. (VxWorks only)
|
|
||||||
**
|
|
||||||
** AFP support exclusive byte-range locks (MacOSX only)
|
|
||||||
**
|
|
||||||
** PROXY uses a second file to represent the lock state of the database
|
|
||||||
** file which is never actually locked, a third file controls
|
|
||||||
** access to the proxy (MacOSX only)
|
|
||||||
**
|
|
||||||
** Note that because FLOCK and NAMEDSEM are never used together, they
|
|
||||||
** share the same code number (3). The locking mode numbering is
|
|
||||||
** chosen so that a set of locking modes that are contiguous integers
|
|
||||||
** from 1 to N. On generic unix systems without flock() support,
|
|
||||||
** the modes are 1..3. On generic unix with flock() support, the modes
|
|
||||||
** are 1..4. On VxWorks, the modes are 1..4. On MacOSX the modes
|
|
||||||
** are 1..6.
|
|
||||||
*/
|
|
||||||
#define LOCKING_STYLE_POSIX 1
|
|
||||||
#define LOCKING_STYLE_NONE 2
|
|
||||||
#define LOCKING_STYLE_DOTFILE 3
|
|
||||||
#define LOCKING_STYLE_FLOCK 4
|
|
||||||
#define LOCKING_STYLE_NAMEDSEM 4
|
|
||||||
#define LOCKING_STYLE_AFP 5
|
|
||||||
#define LOCKING_STYLE_PROXY 6
|
|
||||||
|
|
||||||
#define LOCKING_STYLE_AUTOMATIC 0 /* Choose lock style automatically */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Only set the lastErrno if the error code is a real error and not
|
** Only set the lastErrno if the error code is a real error and not
|
||||||
** a normal expected return code of SQLITE_BUSY or SQLITE_OK
|
** a normal expected return code of SQLITE_BUSY or SQLITE_OK
|
||||||
@@ -863,57 +820,6 @@ static void testThreadLockingBehavior(int fd_orig){
|
|||||||
}
|
}
|
||||||
#endif /* SQLITE_THERADSAFE && defined(__linux__) */
|
#endif /* SQLITE_THERADSAFE && defined(__linux__) */
|
||||||
|
|
||||||
/*
|
|
||||||
** If we are currently in a different thread than the thread that the
|
|
||||||
** unixFile argument belongs to, then transfer ownership of the unixFile
|
|
||||||
** over to the current thread.
|
|
||||||
**
|
|
||||||
** A unixFile is only owned by a thread on systems where one thread is
|
|
||||||
** unable to override locks created by a different thread. RedHat9 is
|
|
||||||
** an example of such a system.
|
|
||||||
**
|
|
||||||
** Ownership transfer is only allowed if the unixFile is currently unlocked.
|
|
||||||
** If the unixFile is locked and an ownership is wrong, then return
|
|
||||||
** SQLITE_MISUSE. SQLITE_OK is returned if everything works.
|
|
||||||
*/
|
|
||||||
#if SQLITE_THREADSAFE && defined(__linux__)
|
|
||||||
static int transferOwnership(unixFile *pFile){
|
|
||||||
int rc;
|
|
||||||
pthread_t hSelf;
|
|
||||||
if( threadsOverrideEachOthersLocks ){
|
|
||||||
/* Ownership transfers not needed on this system */
|
|
||||||
return SQLITE_OK;
|
|
||||||
}
|
|
||||||
hSelf = pthread_self();
|
|
||||||
if( pthread_equal(pFile->tid, hSelf) ){
|
|
||||||
/* We are still in the same thread */
|
|
||||||
OSTRACE1("No-transfer, same thread\n");
|
|
||||||
return SQLITE_OK;
|
|
||||||
}
|
|
||||||
if( pFile->locktype!=NO_LOCK ){
|
|
||||||
/* We cannot change ownership while we are holding a lock! */
|
|
||||||
return SQLITE_MISUSE;
|
|
||||||
}
|
|
||||||
OSTRACE4("Transfer ownership of %d from %d to %d\n",
|
|
||||||
pFile->h, pFile->tid, hSelf);
|
|
||||||
pFile->tid = hSelf;
|
|
||||||
if (pFile->pLock != NULL) {
|
|
||||||
releaseLockInfo(pFile->pLock);
|
|
||||||
rc = findLockInfo(pFile, &pFile->pLock, 0);
|
|
||||||
OSTRACE5("LOCK %d is now %s(%s,%d)\n", pFile->h,
|
|
||||||
locktypeName(pFile->locktype),
|
|
||||||
locktypeName(pFile->pLock->locktype), pFile->pLock->cnt);
|
|
||||||
return rc;
|
|
||||||
} else {
|
|
||||||
return SQLITE_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else /* if not SQLITE_THREADSAFE */
|
|
||||||
/* On single-threaded builds, ownership transfer is a no-op */
|
|
||||||
# define transferOwnership(X) SQLITE_OK
|
|
||||||
#endif /* SQLITE_THREADSAFE */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Release a unixLockInfo structure previously allocated by findLockInfo().
|
** Release a unixLockInfo structure previously allocated by findLockInfo().
|
||||||
*/
|
*/
|
||||||
@@ -1087,6 +993,54 @@ exit_findlockinfo:
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** If we are currently in a different thread than the thread that the
|
||||||
|
** unixFile argument belongs to, then transfer ownership of the unixFile
|
||||||
|
** over to the current thread.
|
||||||
|
**
|
||||||
|
** A unixFile is only owned by a thread on systems that use LinuxThreads.
|
||||||
|
**
|
||||||
|
** Ownership transfer is only allowed if the unixFile is currently unlocked.
|
||||||
|
** If the unixFile is locked and an ownership is wrong, then return
|
||||||
|
** SQLITE_MISUSE. SQLITE_OK is returned if everything works.
|
||||||
|
*/
|
||||||
|
#if SQLITE_THREADSAFE && defined(__linux__)
|
||||||
|
static int transferOwnership(unixFile *pFile){
|
||||||
|
int rc;
|
||||||
|
pthread_t hSelf;
|
||||||
|
if( threadsOverrideEachOthersLocks ){
|
||||||
|
/* Ownership transfers not needed on this system */
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
hSelf = pthread_self();
|
||||||
|
if( pthread_equal(pFile->tid, hSelf) ){
|
||||||
|
/* We are still in the same thread */
|
||||||
|
OSTRACE1("No-transfer, same thread\n");
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
if( pFile->locktype!=NO_LOCK ){
|
||||||
|
/* We cannot change ownership while we are holding a lock! */
|
||||||
|
return SQLITE_MISUSE;
|
||||||
|
}
|
||||||
|
OSTRACE4("Transfer ownership of %d from %d to %d\n",
|
||||||
|
pFile->h, pFile->tid, hSelf);
|
||||||
|
pFile->tid = hSelf;
|
||||||
|
if (pFile->pLock != NULL) {
|
||||||
|
releaseLockInfo(pFile->pLock);
|
||||||
|
rc = findLockInfo(pFile, &pFile->pLock, 0);
|
||||||
|
OSTRACE5("LOCK %d is now %s(%s,%d)\n", pFile->h,
|
||||||
|
locktypeName(pFile->locktype),
|
||||||
|
locktypeName(pFile->pLock->locktype), pFile->pLock->cnt);
|
||||||
|
return rc;
|
||||||
|
} else {
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else /* if not SQLITE_THREADSAFE */
|
||||||
|
/* On single-threaded builds, ownership transfer is a no-op */
|
||||||
|
# define transferOwnership(X) SQLITE_OK
|
||||||
|
#endif /* SQLITE_THREADSAFE */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** This routine checks if there is a RESERVED lock held on the specified
|
** This routine checks if there is a RESERVED lock held on the specified
|
||||||
@@ -1646,6 +1600,11 @@ static int nolockClose(sqlite3_file *id) {
|
|||||||
**
|
**
|
||||||
** Nevertheless, a dotlock is an appropriate locking mode for use if no
|
** Nevertheless, a dotlock is an appropriate locking mode for use if no
|
||||||
** other locking strategy is available.
|
** other locking strategy is available.
|
||||||
|
**
|
||||||
|
** Dotfile locking works by creating a file in the same directory as the
|
||||||
|
** database and with the same name but with a ".lock" extension added.
|
||||||
|
** The existance of a lock file implies an EXCLUSIVE lock. All other lock
|
||||||
|
** types (SHARED, RESERVED, PENDING) are mapped into EXCLUSIVE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1654,8 +1613,16 @@ static int nolockClose(sqlite3_file *id) {
|
|||||||
*/
|
*/
|
||||||
#define DOTLOCK_SUFFIX ".lock"
|
#define DOTLOCK_SUFFIX ".lock"
|
||||||
|
|
||||||
/* Dotlock-style reserved lock checking following the behavior of
|
/*
|
||||||
** unixCheckReservedLock, see the unixCheckReservedLock function comments */
|
** This routine checks if there is a RESERVED lock held on the specified
|
||||||
|
** file by this or any other process. If such a lock is held, set *pResOut
|
||||||
|
** to a non-zero value otherwise *pResOut is set to zero. The return value
|
||||||
|
** is set to SQLITE_OK unless an I/O error occurs during lock checking.
|
||||||
|
**
|
||||||
|
** In dotfile locking, either a lock exists or it does not. So in this
|
||||||
|
** variation of CheckReservedLock(), *pResOut is set to true if any lock
|
||||||
|
** is held on the file and false if the file is unlocked.
|
||||||
|
*/
|
||||||
static int dotlockCheckReservedLock(sqlite3_file *id, int *pResOut) {
|
static int dotlockCheckReservedLock(sqlite3_file *id, int *pResOut) {
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
int reserved = 0;
|
int reserved = 0;
|
||||||
@@ -1667,55 +1634,63 @@ static int dotlockCheckReservedLock(sqlite3_file *id, int *pResOut) {
|
|||||||
|
|
||||||
/* Check if a thread in this process holds such a lock */
|
/* Check if a thread in this process holds such a lock */
|
||||||
if( pFile->locktype>SHARED_LOCK ){
|
if( pFile->locktype>SHARED_LOCK ){
|
||||||
reserved = 1;
|
/* Either this connection or some other connection in the same process
|
||||||
}
|
** holds a lock on the file. No need to check further. */
|
||||||
|
|
||||||
/* Otherwise see if some other process holds it. */
|
|
||||||
if( !reserved ){
|
|
||||||
char *zLockFile = (char *)pFile->lockingContext;
|
|
||||||
struct stat statBuf;
|
|
||||||
|
|
||||||
if( lstat(zLockFile, &statBuf)==0 ){
|
|
||||||
/* file exists, someone else has the lock */
|
|
||||||
reserved = 1;
|
reserved = 1;
|
||||||
}else{
|
}else{
|
||||||
/* file does not exist, we could have it if we want it */
|
/* The lock is held if and only if the lockfile exists */
|
||||||
int tErrno = errno;
|
const char *zLockFile = (const char*)pFile->lockingContext;
|
||||||
if( ENOENT != tErrno ){
|
reserved = access(zLockFile, 0)==0;
|
||||||
rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_CHECKRESERVEDLOCK);
|
|
||||||
pFile->lastErrno = tErrno;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
OSTRACE4("TEST WR-LOCK %d %d %d\n", pFile->h, rc, reserved);
|
OSTRACE4("TEST WR-LOCK %d %d %d\n", pFile->h, rc, reserved);
|
||||||
|
|
||||||
*pResOut = reserved;
|
*pResOut = reserved;
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Lock the file with the lock specified by parameter locktype - one
|
||||||
|
** of the following:
|
||||||
|
**
|
||||||
|
** (1) SHARED_LOCK
|
||||||
|
** (2) RESERVED_LOCK
|
||||||
|
** (3) PENDING_LOCK
|
||||||
|
** (4) EXCLUSIVE_LOCK
|
||||||
|
**
|
||||||
|
** Sometimes when requesting one lock state, additional lock states
|
||||||
|
** are inserted in between. The locking might fail on one of the later
|
||||||
|
** transitions leaving the lock state different from what it started but
|
||||||
|
** still short of its goal. The following chart shows the allowed
|
||||||
|
** transitions and the inserted intermediate states:
|
||||||
|
**
|
||||||
|
** UNLOCKED -> SHARED
|
||||||
|
** SHARED -> RESERVED
|
||||||
|
** SHARED -> (PENDING) -> EXCLUSIVE
|
||||||
|
** RESERVED -> (PENDING) -> EXCLUSIVE
|
||||||
|
** PENDING -> EXCLUSIVE
|
||||||
|
**
|
||||||
|
** This routine will only increase a lock. Use the sqlite3OsUnlock()
|
||||||
|
** routine to lower a locking level.
|
||||||
|
**
|
||||||
|
** With dotfile locking, we really only support state (4): EXCLUSIVE.
|
||||||
|
** But we track the other locking levels internally.
|
||||||
|
*/
|
||||||
static int dotlockLock(sqlite3_file *id, int locktype) {
|
static int dotlockLock(sqlite3_file *id, int locktype) {
|
||||||
unixFile *pFile = (unixFile*)id;
|
unixFile *pFile = (unixFile*)id;
|
||||||
int fd;
|
int fd;
|
||||||
char *zLockFile = (char *)pFile->lockingContext;
|
char *zLockFile = (char *)pFile->lockingContext;
|
||||||
int rc=SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
|
|
||||||
/* if we already have a lock, it is exclusive.
|
|
||||||
** Just adjust level and punt on outta here. */
|
/* If we have any lock, then the lock file already exists. All we have
|
||||||
if (pFile->locktype > NO_LOCK) {
|
** to do is adjust our internal record of the lock level.
|
||||||
|
*/
|
||||||
|
if( pFile->locktype > NO_LOCK ){
|
||||||
pFile->locktype = locktype;
|
pFile->locktype = locktype;
|
||||||
#if !OS_VXWORKS
|
#if !OS_VXWORKS
|
||||||
/* Always update the timestamp on the old file */
|
/* Always update the timestamp on the old file */
|
||||||
utimes(zLockFile, NULL);
|
utimes(zLockFile, NULL);
|
||||||
#endif
|
#endif
|
||||||
rc = SQLITE_OK;
|
return SQLITE_OK;
|
||||||
goto dotlock_end_lock;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check to see if lock file already exists */
|
|
||||||
struct stat statBuf;
|
|
||||||
if (lstat(zLockFile,&statBuf) == 0){
|
|
||||||
rc = SQLITE_BUSY; /* it does, busy */
|
|
||||||
goto dotlock_end_lock;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* grab an exclusive lock */
|
/* grab an exclusive lock */
|
||||||
@@ -1731,7 +1706,7 @@ static int dotlockLock(sqlite3_file *id, int locktype) {
|
|||||||
pFile->lastErrno = tErrno;
|
pFile->lastErrno = tErrno;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
goto dotlock_end_lock;
|
return rc;
|
||||||
}
|
}
|
||||||
if( close(fd) ){
|
if( close(fd) ){
|
||||||
pFile->lastErrno = errno;
|
pFile->lastErrno = errno;
|
||||||
@@ -1740,11 +1715,18 @@ static int dotlockLock(sqlite3_file *id, int locktype) {
|
|||||||
|
|
||||||
/* got it, set the type and return ok */
|
/* got it, set the type and return ok */
|
||||||
pFile->locktype = locktype;
|
pFile->locktype = locktype;
|
||||||
|
|
||||||
dotlock_end_lock:
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Lower the locking level on file descriptor pFile to locktype. locktype
|
||||||
|
** must be either NO_LOCK or SHARED_LOCK.
|
||||||
|
**
|
||||||
|
** If the locking level of the file descriptor is already at or below
|
||||||
|
** the requested locking level, this routine is a no-op.
|
||||||
|
**
|
||||||
|
** When the locking level reaches NO_LOCK, delete the lock file.
|
||||||
|
*/
|
||||||
static int dotlockUnlock(sqlite3_file *id, int locktype) {
|
static int dotlockUnlock(sqlite3_file *id, int locktype) {
|
||||||
unixFile *pFile = (unixFile*)id;
|
unixFile *pFile = (unixFile*)id;
|
||||||
char *zLockFile = (char *)pFile->lockingContext;
|
char *zLockFile = (char *)pFile->lockingContext;
|
||||||
@@ -1759,14 +1741,17 @@ static int dotlockUnlock(sqlite3_file *id, int locktype) {
|
|||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* shared can just be set because we always have an exclusive */
|
/* To downgrade to shared, simply update our internal notion of the
|
||||||
if (locktype==SHARED_LOCK) {
|
** lock state. No need to mess with the file on disk.
|
||||||
pFile->locktype = locktype;
|
*/
|
||||||
|
if( locktype==SHARED_LOCK ){
|
||||||
|
pFile->locktype = SHARED_LOCK;
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* no, really, unlock. */
|
/* To fully unlock the database, delete the lock file */
|
||||||
if (unlink(zLockFile) ) {
|
assert( locktype==NO_LOCK );
|
||||||
|
if( unlink(zLockFile) ){
|
||||||
int rc, tErrno = errno;
|
int rc, tErrno = errno;
|
||||||
if( ENOENT != tErrno ){
|
if( ENOENT != tErrno ){
|
||||||
rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK);
|
rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK);
|
||||||
@@ -1807,6 +1792,7 @@ static int dotlockClose(sqlite3_file *id) {
|
|||||||
** compiling for VXWORKS.
|
** compiling for VXWORKS.
|
||||||
*/
|
*/
|
||||||
#if SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS
|
#if SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS
|
||||||
|
#include <sys/file.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** The flockLockingContext is not used
|
** The flockLockingContext is not used
|
||||||
@@ -1870,7 +1856,6 @@ static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){
|
|||||||
|
|
||||||
static int flockLock(sqlite3_file *id, int locktype) {
|
static int flockLock(sqlite3_file *id, int locktype) {
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
int lrc;
|
|
||||||
unixFile *pFile = (unixFile*)id;
|
unixFile *pFile = (unixFile*)id;
|
||||||
|
|
||||||
assert( pFile );
|
assert( pFile );
|
||||||
@@ -2629,39 +2614,12 @@ static int afpClose(sqlite3_file *id) {
|
|||||||
|
|
||||||
static int getDbPathForUnixFile(unixFile *pFile, char *dbPath);
|
static int getDbPathForUnixFile(unixFile *pFile, char *dbPath);
|
||||||
static int getLockPath(const char *dbPath, char *lPath, size_t maxLen);
|
static int getLockPath(const char *dbPath, char *lPath, size_t maxLen);
|
||||||
static sqlite3_io_methods *ioMethodForLockingStyle(int style);
|
|
||||||
static int createProxyUnixFile(const char *path, unixFile **ppFile);
|
static int createProxyUnixFile(const char *path, unixFile **ppFile);
|
||||||
static int fillInUnixFile(sqlite3_vfs *pVfs, int h, int dirfd, sqlite3_file *pId, const char *zFilename, int noLock, int isDelete);
|
static int fillInUnixFile(sqlite3_vfs *pVfs, int h, int dirfd, sqlite3_file *pId, const char *zFilename, int noLock, int isDelete);
|
||||||
static int takeConch(unixFile *pFile);
|
static int takeConch(unixFile *pFile);
|
||||||
static int releaseConch(unixFile *pFile);
|
static int releaseConch(unixFile *pFile);
|
||||||
static int unixRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf);
|
static int unixRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf);
|
||||||
|
|
||||||
/*
|
|
||||||
** Tests a byte-range locking query to see if byte range locks are
|
|
||||||
** supported, if not we fall back to dotlockLockingStyle.
|
|
||||||
** On vxWorks we fall back to semLockingStyle.
|
|
||||||
*/
|
|
||||||
static int testLockingStyle(int fd){
|
|
||||||
struct flock lockInfo;
|
|
||||||
|
|
||||||
/* Test byte-range lock using fcntl(). If the call succeeds,
|
|
||||||
** assume that the file-system supports POSIX style locks.
|
|
||||||
*/
|
|
||||||
lockInfo.l_len = 1;
|
|
||||||
lockInfo.l_start = 0;
|
|
||||||
lockInfo.l_whence = SEEK_SET;
|
|
||||||
lockInfo.l_type = F_RDLCK;
|
|
||||||
if( fcntl(fd, F_GETLK, &lockInfo)!=-1 ) {
|
|
||||||
return LOCKING_STYLE_POSIX;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Testing for flock() can give false positives. So if if the above
|
|
||||||
** test fails, then we fall back to using dot-file style locking (or
|
|
||||||
** named-semaphore locking on vxworks).
|
|
||||||
*/
|
|
||||||
return (OS_VXWORKS ? LOCKING_STYLE_NAMEDSEM : LOCKING_STYLE_DOTFILE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef SQLITE_TEST
|
#ifdef SQLITE_TEST
|
||||||
/* simulate multiple hosts by creating unique hostid file paths */
|
/* simulate multiple hosts by creating unique hostid file paths */
|
||||||
@@ -3022,8 +2980,7 @@ end_takeconch:
|
|||||||
|
|
||||||
if( tLockPath ){
|
if( tLockPath ){
|
||||||
pCtx->lockProxyPath = sqlite3DbStrDup(0, tLockPath);
|
pCtx->lockProxyPath = sqlite3DbStrDup(0, tLockPath);
|
||||||
if( pCtx->lockProxy->pMethod ==
|
if( pCtx->lockProxy->pMethod == &afpIoMethods ){
|
||||||
ioMethodForLockingStyle(LOCKING_STYLE_AFP) ){
|
|
||||||
((afpLockingContext *)pCtx->lockProxy->lockingContext)->dbPath =
|
((afpLockingContext *)pCtx->lockProxy->lockingContext)->dbPath =
|
||||||
pCtx->lockProxyPath;
|
pCtx->lockProxyPath;
|
||||||
}
|
}
|
||||||
@@ -3212,7 +3169,7 @@ end_transform_file:
|
|||||||
pCtx->oldLockingContext = pFile->lockingContext;
|
pCtx->oldLockingContext = pFile->lockingContext;
|
||||||
pFile->lockingContext = pCtx;
|
pFile->lockingContext = pCtx;
|
||||||
pCtx->pOldMethod = pFile->pMethod;
|
pCtx->pOldMethod = pFile->pMethod;
|
||||||
pFile->pMethod = ioMethodForLockingStyle(LOCKING_STYLE_PROXY);
|
pFile->pMethod = &proxyIoMethods;
|
||||||
}else{
|
}else{
|
||||||
if( pCtx->conchFile ){
|
if( pCtx->conchFile ){
|
||||||
rc = pCtx->conchFile->pMethod->xClose((sqlite3_file *)pCtx->conchFile);
|
rc = pCtx->conchFile->pMethod->xClose((sqlite3_file *)pCtx->conchFile);
|
||||||
@@ -3646,10 +3603,14 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
|
|||||||
*(int*)pArg = ((unixFile*)id)->locktype;
|
*(int*)pArg = ((unixFile*)id)->locktype;
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
case SQLITE_LAST_ERRNO: {
|
||||||
|
*(int*)pArg = ((unixFile*)id)->lastErrno;
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
#if SQLITE_ENABLE_LOCKING_STYLE && defined(__DARWIN__)
|
||||||
case SQLITE_GET_LOCKPROXYFILE: {
|
case SQLITE_GET_LOCKPROXYFILE: {
|
||||||
#if SQLITE_ENABLE_LOCKING_STYLE
|
|
||||||
unixFile *pFile = (unixFile*)id;
|
unixFile *pFile = (unixFile*)id;
|
||||||
if( pFile->pMethod == ioMethodForLockingStyle(LOCKING_STYLE_PROXY) ){
|
if( pFile->pMethod == &proxyIoMethods ){
|
||||||
proxyLockingContext *pCtx = (proxyLockingContext*)pFile->lockingContext;
|
proxyLockingContext *pCtx = (proxyLockingContext*)pFile->lockingContext;
|
||||||
takeConch(pFile);
|
takeConch(pFile);
|
||||||
if( pCtx->lockProxyPath ){
|
if( pCtx->lockProxyPath ){
|
||||||
@@ -3660,22 +3621,18 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
|
|||||||
} else {
|
} else {
|
||||||
*(const char **)pArg = NULL;
|
*(const char **)pArg = NULL;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
*(void**)pArg = NULL;
|
|
||||||
#endif
|
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
case SQLITE_SET_LOCKPROXYFILE: {
|
case SQLITE_SET_LOCKPROXYFILE: {
|
||||||
#if SQLITE_ENABLE_LOCKING_STYLE
|
|
||||||
unixFile *pFile = (unixFile*)id;
|
unixFile *pFile = (unixFile*)id;
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
int isProxyStyle = (pFile->pMethod == ioMethodForLockingStyle(LOCKING_STYLE_PROXY));
|
int isProxyStyle = (pFile->pMethod == &proxyIoMethods);
|
||||||
if( pArg==NULL || (const char *)pArg==0 ){
|
if( pArg==NULL || (const char *)pArg==0 ){
|
||||||
if( isProxyStyle ){
|
if( isProxyStyle ){
|
||||||
// turn off proxy locking - not supported
|
/* turn off proxy locking - not supported */
|
||||||
rc = SQLITE_ERROR /*SQLITE_PROTOCOL? SQLITE_MISUSE?*/;
|
rc = SQLITE_ERROR /*SQLITE_PROTOCOL? SQLITE_MISUSE?*/;
|
||||||
}else{
|
}else{
|
||||||
// turn off proxy locking - already off - NOOP
|
/* turn off proxy locking - already off - NOOP */
|
||||||
rc = SQLITE_OK;
|
rc = SQLITE_OK;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
@@ -3683,26 +3640,22 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
|
|||||||
if( isProxyStyle ){
|
if( isProxyStyle ){
|
||||||
proxyLockingContext *pCtx =
|
proxyLockingContext *pCtx =
|
||||||
(proxyLockingContext*)pFile->lockingContext;
|
(proxyLockingContext*)pFile->lockingContext;
|
||||||
if( !strcmp(pArg, ":auto:") || (pCtx->lockProxyPath && !strncmp(pCtx->lockProxyPath, proxyPath, MAXPATHLEN)) ){
|
if( !strcmp(pArg, ":auto:")
|
||||||
|
|| (pCtx->lockProxyPath &&
|
||||||
|
!strncmp(pCtx->lockProxyPath, proxyPath, MAXPATHLEN))
|
||||||
|
){
|
||||||
rc = SQLITE_OK;
|
rc = SQLITE_OK;
|
||||||
}else{
|
}else{
|
||||||
rc = switchLockProxyPath(pFile, proxyPath);
|
rc = switchLockProxyPath(pFile, proxyPath);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
// turn on proxy file locking
|
/* turn on proxy file locking */
|
||||||
rc = transformUnixFileForLockProxy(pFile, proxyPath);
|
rc = transformUnixFileForLockProxy(pFile, proxyPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
#else
|
}
|
||||||
return SQLITE_ERROR /*SQLITE_PROTOCOL? SQLITE_MISUSE?*/;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
case SQLITE_LAST_ERRNO: {
|
|
||||||
*(int*)pArg = ((unixFile*)id)->lastErrno;
|
|
||||||
return SQLITE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return SQLITE_ERROR;
|
return SQLITE_ERROR;
|
||||||
}
|
}
|
||||||
@@ -3737,46 +3690,173 @@ static int unixDeviceCharacteristics(sqlite3_file *NotUsed){
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** The following constant array describes all of the methods for the
|
** Each instance of this macro generates two objects:
|
||||||
** sqlite3_file object for each of the various locking modes.
|
|
||||||
**
|
**
|
||||||
** The order in which the methods are defined is important and must
|
** * A constant sqlite3_io_methods object call METHOD that has locking
|
||||||
** agree with the numeric values of the method identifier constants.
|
** methods CLOSE, LOCK, UNLOCK, CKRESLOCK.
|
||||||
** For example, LOCKING_STYLE_UNIX has a numeric value of zero, so
|
**
|
||||||
** it must be the 0-th entry in the array.
|
** * An I/O method finder function called FINDER that returns a pointer
|
||||||
|
** to the METHOD object in the previous bullet.
|
||||||
*/
|
*/
|
||||||
#define IOMETHODS(xClose, xLock, xUnlock, xCheckReservedLock) { \
|
#define IOMETHODS(FINDER, METHOD, CLOSE, LOCK, UNLOCK, CKLOCK) \
|
||||||
|
static const sqlite3_io_methods METHOD = { \
|
||||||
1, /* iVersion */ \
|
1, /* iVersion */ \
|
||||||
xClose, /* xClose */ \
|
CLOSE, /* xClose */ \
|
||||||
unixRead, /* xRead */ \
|
unixRead, /* xRead */ \
|
||||||
unixWrite, /* xWrite */ \
|
unixWrite, /* xWrite */ \
|
||||||
unixTruncate, /* xTruncate */ \
|
unixTruncate, /* xTruncate */ \
|
||||||
unixSync, /* xSync */ \
|
unixSync, /* xSync */ \
|
||||||
unixFileSize, /* xFileSize */ \
|
unixFileSize, /* xFileSize */ \
|
||||||
xLock, /* xLock */ \
|
LOCK, /* xLock */ \
|
||||||
xUnlock, /* xUnlock */ \
|
UNLOCK, /* xUnlock */ \
|
||||||
xCheckReservedLock, /* xCheckReservedLock */ \
|
CKLOCK, /* xCheckReservedLock */ \
|
||||||
unixFileControl, /* xFileControl */ \
|
unixFileControl, /* xFileControl */ \
|
||||||
unixSectorSize, /* xSectorSize */ \
|
unixSectorSize, /* xSectorSize */ \
|
||||||
unixDeviceCharacteristics /* xDeviceCapabilities */ \
|
unixDeviceCharacteristics /* xDeviceCapabilities */ \
|
||||||
|
}; \
|
||||||
|
static const sqlite3_io_methods *FINDER(const char *z, int h){ \
|
||||||
|
UNUSED_PARAMETER(z); UNUSED_PARAMETER(h); \
|
||||||
|
return &METHOD; \
|
||||||
}
|
}
|
||||||
static sqlite3_io_methods aIoMethod[] = {
|
|
||||||
IOMETHODS(unixClose, unixLock, unixUnlock, unixCheckReservedLock),
|
/*
|
||||||
IOMETHODS(nolockClose, nolockLock, nolockUnlock, nolockCheckReservedLock),
|
** Here are all of the sqlite3_io_methods objects for each of the
|
||||||
IOMETHODS(dotlockClose, dotlockLock, dotlockUnlock,dotlockCheckReservedLock),
|
** locking strategies. Functions that return pointers to these methods
|
||||||
|
** are also created.
|
||||||
|
*/
|
||||||
|
IOMETHODS(
|
||||||
|
posixIoFinder, /* Finder function name */
|
||||||
|
posixIoMethods, /* sqlite3_io_methods object name */
|
||||||
|
unixClose, /* xClose method */
|
||||||
|
unixLock, /* xLock method */
|
||||||
|
unixUnlock, /* xUnlock method */
|
||||||
|
unixCheckReservedLock /* xCheckReservedLock method */
|
||||||
|
);
|
||||||
|
IOMETHODS(
|
||||||
|
nolockIoFinder, /* Finder function name */
|
||||||
|
nolockIoMethods, /* sqlite3_io_methods object name */
|
||||||
|
nolockClose, /* xClose method */
|
||||||
|
nolockLock, /* xLock method */
|
||||||
|
nolockUnlock, /* xUnlock method */
|
||||||
|
nolockCheckReservedLock /* xCheckReservedLock method */
|
||||||
|
);
|
||||||
|
IOMETHODS(
|
||||||
|
dotlockIoFinder, /* Finder function name */
|
||||||
|
dotlockIoMethods, /* sqlite3_io_methods object name */
|
||||||
|
dotlockClose, /* xClose method */
|
||||||
|
dotlockLock, /* xLock method */
|
||||||
|
dotlockUnlock, /* xUnlock method */
|
||||||
|
dotlockCheckReservedLock /* xCheckReservedLock method */
|
||||||
|
);
|
||||||
|
|
||||||
|
#if SQLITE_ENABLE_LOCKING_STYLE
|
||||||
|
IOMETHODS(
|
||||||
|
flockIoFinder, /* Finder function name */
|
||||||
|
flockIoMethods, /* sqlite3_io_methods object name */
|
||||||
|
flockClose, /* xClose method */
|
||||||
|
flockLock, /* xLock method */
|
||||||
|
flockUnlock, /* xUnlock method */
|
||||||
|
flockCheckReservedLock /* xCheckReservedLock method */
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if OS_VXWORKS
|
#if OS_VXWORKS
|
||||||
IOMETHODS(semClose, semLock, semUnlock, semCheckReservedLock),
|
IOMETHODS(
|
||||||
#elif SQLITE_ENABLE_LOCKING_STYLE
|
semIoFinder, /* Finder function name */
|
||||||
IOMETHODS(flockClose, flockLock, flockUnlock, flockCheckReservedLock),
|
semIoMethods, /* sqlite3_io_methods object name */
|
||||||
|
semClose, /* xClose method */
|
||||||
|
semLock, /* xLock method */
|
||||||
|
semUnlock, /* xUnlock method */
|
||||||
|
semCheckReservedLock /* xCheckReservedLock method */
|
||||||
|
);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__DARWIN__) && SQLITE_ENABLE_LOCKING_STYLE
|
#if defined(__DARWIN__) && SQLITE_ENABLE_LOCKING_STYLE
|
||||||
IOMETHODS(afpClose, afpLock, afpUnlock, afpCheckReservedLock),
|
IOMETHODS(
|
||||||
IOMETHODS(proxyClose, proxyLock, proxyUnlock, proxyCheckReservedLock),
|
afpIoFinder, /* Finder function name */
|
||||||
|
afpIoMethods, /* sqlite3_io_methods object name */
|
||||||
|
afpClose, /* xClose method */
|
||||||
|
afpLock, /* xLock method */
|
||||||
|
afpUnlock, /* xUnlock method */
|
||||||
|
afpCheckReservedLock /* xCheckReservedLock method */
|
||||||
|
);
|
||||||
|
IOMETHODS(
|
||||||
|
proxyIoFinder, /* Finder function name */
|
||||||
|
proxyIoMethods, /* sqlite3_io_methods object name */
|
||||||
|
proxyClose, /* xClose method */
|
||||||
|
proxyLock, /* xLock method */
|
||||||
|
proxyUnlock, /* xUnlock method */
|
||||||
|
proxyCheckReservedLock /* xCheckReservedLock method */
|
||||||
|
);
|
||||||
#endif
|
#endif
|
||||||
/* The order of the IOMETHODS macros above is important. It must be the
|
|
||||||
** same order as the LOCKING_STYLE numbers
|
|
||||||
|
#if defined(__DARWIN__) && SQLITE_ENABLE_LOCKING_STYLE
|
||||||
|
/*
|
||||||
|
** This procedure attempts to determine the best locking strategy for
|
||||||
|
** the given database file. It then returns the sqlite3_io_methods
|
||||||
|
** object that implements that strategy.
|
||||||
|
**
|
||||||
|
** This is for MacOSX only.
|
||||||
|
*/
|
||||||
|
static const sqlite3_io_methods *autolockIoFinder(
|
||||||
|
const char *filePath, /* name of the database file */
|
||||||
|
int fd /* file descriptor open on the database file */
|
||||||
|
){
|
||||||
|
static const struct Mapping {
|
||||||
|
const char *zFilesystem;
|
||||||
|
const sqlite3_io_methods *pMethods;
|
||||||
|
} aMap[] = {
|
||||||
|
{ "hfs", &posixIoMethods },
|
||||||
|
{ "ufs", &posixIoMethods },
|
||||||
|
{ "afpfs", &afpIoMethods },
|
||||||
|
#ifdef SQLITE_ENABLE_AFP_LOCKING_SMB
|
||||||
|
{ "smbfs", &afpIoMethods },
|
||||||
|
#else
|
||||||
|
{ "smbfs", &flockIoMethods },
|
||||||
|
#endif
|
||||||
|
{ "webdav", &nolockIoMethods },
|
||||||
|
{ 0, 0 }
|
||||||
|
};
|
||||||
|
int i;
|
||||||
|
struct statfs fsInfo;
|
||||||
|
struct flock lockInfo;
|
||||||
|
|
||||||
|
if( !filePath ){
|
||||||
|
return &nolockIoMethods;
|
||||||
|
}
|
||||||
|
if( statfs(filePath, &fsInfo) != -1 ){
|
||||||
|
if( fsInfo.f_flags & MNT_RDONLY ){
|
||||||
|
return &nolockIoMethods;
|
||||||
|
}
|
||||||
|
for(i=0; aMap[i].zFilesystem; i++){
|
||||||
|
if( strcmp(fsInfo.f_fstypename, aMap[i].zFilesystem)==0 ){
|
||||||
|
return aMap[i].pMethods;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Default case. Handles, amongst others, "nfs".
|
||||||
|
** Test byte-range lock using fcntl(). If the call succeeds,
|
||||||
|
** assume that the file-system supports POSIX style locks.
|
||||||
*/
|
*/
|
||||||
};
|
lockInfo.l_len = 1;
|
||||||
|
lockInfo.l_start = 0;
|
||||||
|
lockInfo.l_whence = SEEK_SET;
|
||||||
|
lockInfo.l_type = F_RDLCK;
|
||||||
|
if( fcntl(fd, F_GETLK, &lockInfo)!=-1 ) {
|
||||||
|
return &posixIoMethods;
|
||||||
|
}else{
|
||||||
|
return &dotlockIoMethods;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* defined(__DARWIN__) && SQLITE_ENABLE_LOCKING_STYLE */
|
||||||
|
|
||||||
|
/*
|
||||||
|
** An abstract type for a pointer to a IO method finder function:
|
||||||
|
*/
|
||||||
|
typedef const sqlite3_io_methods *(*finder_type)(const char*,int);
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**************************** sqlite3_vfs methods ****************************
|
**************************** sqlite3_vfs methods ****************************
|
||||||
@@ -3785,87 +3865,8 @@ static sqlite3_io_methods aIoMethod[] = {
|
|||||||
** sqlite3_vfs object.
|
** sqlite3_vfs object.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
** If SQLITE_ENABLE_LOCKING_STYLE is defined, this function Examines the
|
|
||||||
** f_fstypename entry in the statfs structure as returned by stat() for
|
|
||||||
** the file system hosting the database file and selects the appropriate
|
|
||||||
** locking style based on its value. These values and assignments are
|
|
||||||
** based on Darwin/OSX behavior and have not been thoroughly tested on
|
|
||||||
** other systems.
|
|
||||||
**
|
|
||||||
** If SQLITE_ENABLE_LOCKING_STYLE is not defined, this function always
|
|
||||||
** returns LOCKING_STYLE_POSIX.
|
|
||||||
*/
|
|
||||||
#if SQLITE_ENABLE_LOCKING_STYLE
|
|
||||||
static int detectLockingStyle(
|
|
||||||
sqlite3_vfs *pVfs,
|
|
||||||
const char *filePath,
|
|
||||||
int fd
|
|
||||||
){
|
|
||||||
#if OS_VXWORKS
|
|
||||||
if( !filePath ){
|
|
||||||
return LOCKING_STYLE_NONE;
|
|
||||||
}
|
|
||||||
if( pVfs->pAppData ){
|
|
||||||
return SQLITE_PTR_TO_INT(pVfs->pAppData);
|
|
||||||
}
|
|
||||||
if (access(filePath, 0) != -1){
|
|
||||||
return testLockingStyle(fd);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
struct Mapping {
|
|
||||||
const char *zFilesystem;
|
|
||||||
int eLockingStyle;
|
|
||||||
} aMap[] = {
|
|
||||||
{ "hfs", LOCKING_STYLE_POSIX },
|
|
||||||
{ "ufs", LOCKING_STYLE_POSIX },
|
|
||||||
{ "afpfs", LOCKING_STYLE_AFP },
|
|
||||||
#ifdef SQLITE_ENABLE_AFP_LOCKING_SMB
|
|
||||||
{ "smbfs", LOCKING_STYLE_AFP },
|
|
||||||
#else
|
|
||||||
{ "smbfs", LOCKING_STYLE_FLOCK },
|
|
||||||
#endif
|
|
||||||
{ "webdav", LOCKING_STYLE_NONE },
|
|
||||||
{ 0, 0 }
|
|
||||||
};
|
|
||||||
int i;
|
|
||||||
struct statfs fsInfo;
|
|
||||||
|
|
||||||
if( !filePath ){
|
|
||||||
return LOCKING_STYLE_NONE;
|
|
||||||
}
|
|
||||||
if( pVfs && pVfs->pAppData ){
|
|
||||||
return SQLITE_PTR_TO_INT(pVfs->pAppData);
|
|
||||||
}
|
|
||||||
|
|
||||||
if( statfs(filePath, &fsInfo) != -1 ){
|
|
||||||
if( fsInfo.f_flags & MNT_RDONLY ){
|
|
||||||
return LOCKING_STYLE_NONE;
|
|
||||||
}
|
|
||||||
for(i=0; aMap[i].zFilesystem; i++){
|
|
||||||
if( strcmp(fsInfo.f_fstypename, aMap[i].zFilesystem)==0 ){
|
|
||||||
return aMap[i].eLockingStyle;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Default case. Handles, amongst others, "nfs". */
|
|
||||||
return testLockingStyle(fd);
|
|
||||||
#endif /* if OS_VXWORKS */
|
|
||||||
return LOCKING_STYLE_POSIX;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#define detectLockingStyle(x,y,z) LOCKING_STYLE_POSIX
|
|
||||||
#endif /* if SQLITE_ENABLE_LOCKING_STYLE */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Initialize the contents of the unixFile structure pointed to by pId.
|
** Initialize the contents of the unixFile structure pointed to by pId.
|
||||||
**
|
|
||||||
** When locking extensions are enabled, the filepath and locking style
|
|
||||||
** are needed to determine the unixFile pMethod to use for locking operations.
|
|
||||||
** The locking-style specific lockingContext data structure is created
|
|
||||||
** and assigned here also.
|
|
||||||
*/
|
*/
|
||||||
static int fillInUnixFile(
|
static int fillInUnixFile(
|
||||||
sqlite3_vfs *pVfs, /* Pointer to vfs object */
|
sqlite3_vfs *pVfs, /* Pointer to vfs object */
|
||||||
@@ -3876,7 +3877,7 @@ static int fillInUnixFile(
|
|||||||
int noLock, /* Omit locking if true */
|
int noLock, /* Omit locking if true */
|
||||||
int isDelete /* Delete on close if true */
|
int isDelete /* Delete on close if true */
|
||||||
){
|
){
|
||||||
int eLockingStyle;
|
const sqlite3_io_methods *pLockingStyle;
|
||||||
unixFile *pNew = (unixFile *)pId;
|
unixFile *pNew = (unixFile *)pId;
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
|
|
||||||
@@ -3887,9 +3888,15 @@ static int fillInUnixFile(
|
|||||||
** used if ENABLE_LOCKING_STYLE is defined. Express this explicitly
|
** used if ENABLE_LOCKING_STYLE is defined. Express this explicitly
|
||||||
** here to prevent compiler warnings about unused parameters.
|
** here to prevent compiler warnings about unused parameters.
|
||||||
*/
|
*/
|
||||||
if( !OS_VXWORKS ) UNUSED_PARAMETER(isDelete);
|
#if !OS_VXWORKS
|
||||||
if( !SQLITE_ENABLE_LOCKING_STYLE ) UNUSED_PARAMETER(pVfs);
|
UNUSED_PARAMETER(isDelete);
|
||||||
if( !OS_VXWORKS && !SQLITE_ENABLE_LOCKING_STYLE ) UNUSED_PARAMETER(zFilename);
|
#endif
|
||||||
|
#if !SQLITE_ENABLE_LOCKING_STYLE
|
||||||
|
UNUSED_PARAMETER(pVfs);
|
||||||
|
#endif
|
||||||
|
#if !OS_VXWORKS && !SQLITE_ENABLE_LOCKING_STYLE
|
||||||
|
UNUSED_PARAMETER(zFilename);
|
||||||
|
#endif
|
||||||
|
|
||||||
OSTRACE3("OPEN %-3d %s\n", h, zFilename);
|
OSTRACE3("OPEN %-3d %s\n", h, zFilename);
|
||||||
pNew->h = h;
|
pNew->h = h;
|
||||||
@@ -3905,9 +3912,9 @@ static int fillInUnixFile(
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if( noLock ){
|
if( noLock ){
|
||||||
eLockingStyle = LOCKING_STYLE_NONE;
|
pLockingStyle = &nolockIoMethods;
|
||||||
}else{
|
}else{
|
||||||
eLockingStyle = detectLockingStyle(pVfs, zFilename, h);
|
pLockingStyle = (*(finder_type)pVfs->pAppData)(zFilename, h);
|
||||||
#if SQLITE_ENABLE_LOCKING_STYLE
|
#if SQLITE_ENABLE_LOCKING_STYLE
|
||||||
/* Cache zFilename in the locking context (AFP and dotlock override) for
|
/* Cache zFilename in the locking context (AFP and dotlock override) for
|
||||||
** proxyLock activation is possible (remote proxy is based on db name)
|
** proxyLock activation is possible (remote proxy is based on db name)
|
||||||
@@ -3916,20 +3923,14 @@ static int fillInUnixFile(
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( pLockingStyle == &posixIoMethods ){
|
||||||
switch( eLockingStyle ){
|
|
||||||
|
|
||||||
case LOCKING_STYLE_POSIX: {
|
|
||||||
unixEnterMutex();
|
unixEnterMutex();
|
||||||
rc = findLockInfo(pNew, &pNew->pLock, &pNew->pOpen);
|
rc = findLockInfo(pNew, &pNew->pLock, &pNew->pOpen);
|
||||||
unixLeaveMutex();
|
unixLeaveMutex();
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SQLITE_ENABLE_LOCKING_STYLE
|
#if SQLITE_ENABLE_LOCKING_STYLE && defined(__DARWIN__)
|
||||||
|
else if( pLockingStyle == &apfIoMethods ){
|
||||||
#if !OS_VXWORKS
|
|
||||||
case LOCKING_STYLE_AFP: {
|
|
||||||
/* AFP locking uses the file path so it needs to be included in
|
/* AFP locking uses the file path so it needs to be included in
|
||||||
** the afpLockingContext.
|
** the afpLockingContext.
|
||||||
*/
|
*/
|
||||||
@@ -3947,11 +3948,11 @@ static int fillInUnixFile(
|
|||||||
rc = findLockInfo(pNew, NULL, &pNew->pOpen);
|
rc = findLockInfo(pNew, NULL, &pNew->pOpen);
|
||||||
unixLeaveMutex();
|
unixLeaveMutex();
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case LOCKING_STYLE_DOTFILE: {
|
#if SQLITE_ENABLE_LOCKING_STYLE
|
||||||
|
else if( pLockingStyle == &dotlockIoMethods ){
|
||||||
/* Dotfile locking uses the file path so it needs to be included in
|
/* Dotfile locking uses the file path so it needs to be included in
|
||||||
** the dotlockLockingContext
|
** the dotlockLockingContext
|
||||||
*/
|
*/
|
||||||
@@ -3965,11 +3966,11 @@ static int fillInUnixFile(
|
|||||||
sqlite3_snprintf(nFilename, zLockFile, "%s" DOTLOCK_SUFFIX, zFilename);
|
sqlite3_snprintf(nFilename, zLockFile, "%s" DOTLOCK_SUFFIX, zFilename);
|
||||||
}
|
}
|
||||||
pNew->lockingContext = zLockFile;
|
pNew->lockingContext = zLockFile;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if OS_VXWORKS
|
#if OS_VXWORKS
|
||||||
case LOCKING_STYLE_NAMEDSEM: {
|
else if( pLockingStyle == &semIoMethods ){
|
||||||
/* Named semaphore locking uses the file path so it needs to be
|
/* Named semaphore locking uses the file path so it needs to be
|
||||||
** included in the semLockingContext
|
** included in the semLockingContext
|
||||||
*/
|
*/
|
||||||
@@ -3989,16 +3990,9 @@ static int fillInUnixFile(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
unixLeaveMutex();
|
unixLeaveMutex();
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case LOCKING_STYLE_FLOCK:
|
|
||||||
case LOCKING_STYLE_NONE:
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
pNew->lastErrno = 0;
|
pNew->lastErrno = 0;
|
||||||
#if OS_VXWORKS
|
#if OS_VXWORKS
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
@@ -4011,34 +4005,32 @@ static int fillInUnixFile(
|
|||||||
if( dirfd>=0 ) close(dirfd); /* silent leak if fail, already in error */
|
if( dirfd>=0 ) close(dirfd); /* silent leak if fail, already in error */
|
||||||
close(h);
|
close(h);
|
||||||
}else{
|
}else{
|
||||||
pNew->pMethod = &aIoMethod[eLockingStyle-1];
|
pNew->pMethod = pLockingStyle;
|
||||||
OpenCounter(+1);
|
OpenCounter(+1);
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SQLITE_ENABLE_LOCKING_STYLE
|
#if SQLITE_ENABLE_LOCKING_STYLE
|
||||||
static sqlite3_io_methods *ioMethodForLockingStyle(int style){
|
|
||||||
return &aIoMethod[style];
|
|
||||||
}
|
|
||||||
|
|
||||||
static int getDbPathForUnixFile(unixFile *pFile, char *dbPath){
|
static int getDbPathForUnixFile(unixFile *pFile, char *dbPath){
|
||||||
if( pFile->pMethod==ioMethodForLockingStyle(LOCKING_STYLE_AFP) ){
|
#if defined(__DARWIN__)
|
||||||
|
if( pFile->pMethod == &afpIoMethods ){
|
||||||
/* afp style keeps a reference to the db path in the filePath field
|
/* afp style keeps a reference to the db path in the filePath field
|
||||||
** of the struct */
|
** of the struct */
|
||||||
strlcpy(dbPath, ((afpLockingContext *)pFile->lockingContext)->dbPath,
|
assert( strlen((char*)pFile->lockingContext)<=MAXPATHLEN );
|
||||||
MAXPATHLEN);
|
strcpy(dbPath, ((afpLockingContext *)pFile->lockingContext)->dbPath)
|
||||||
return SQLITE_OK;
|
}else
|
||||||
}
|
#endif
|
||||||
if( pFile->pMethod==ioMethodForLockingStyle(LOCKING_STYLE_DOTFILE) ){
|
if( pFile->pMethod == &dotlockIoMethods ){
|
||||||
/* dot lock style uses the locking context to store the dot lock
|
/* dot lock style uses the locking context to store the dot lock
|
||||||
** file path */
|
** file path */
|
||||||
int len = strlen((char *)pFile->lockingContext) - strlen(DOTLOCK_SUFFIX);
|
int len = strlen((char *)pFile->lockingContext) - strlen(DOTLOCK_SUFFIX);
|
||||||
strlcpy(dbPath, (char *)pFile->lockingContext, len + 1);
|
memcpy(dbPath, (char *)pFile->lockingContext, len + 1);
|
||||||
return SQLITE_OK;
|
}else{
|
||||||
}
|
|
||||||
/* all other styles use the locking context to store the db file path */
|
/* all other styles use the locking context to store the db file path */
|
||||||
strlcpy(dbPath, (char *)pFile->lockingContext, MAXPATHLEN);
|
assert( strlen((char*)pFile->lockingContext)<=MAXPATHLEN );
|
||||||
|
strcpy(dbPath, (char *)pFile->lockingContext);
|
||||||
|
}
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -4595,13 +4587,13 @@ int sqlite3_os_init(void){
|
|||||||
** the sqlite3_vfs.zName and sqlite3_vfs.pAppData fields, respectively.
|
** the sqlite3_vfs.zName and sqlite3_vfs.pAppData fields, respectively.
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
#define UNIXVFS(zVfsName, pVfsAppData) { \
|
#define UNIXVFS(VFSNAME, FINDER) { \
|
||||||
1, /* iVersion */ \
|
1, /* iVersion */ \
|
||||||
sizeof(unixFile), /* szOsFile */ \
|
sizeof(unixFile), /* szOsFile */ \
|
||||||
MAX_PATHNAME, /* mxPathname */ \
|
MAX_PATHNAME, /* mxPathname */ \
|
||||||
0, /* pNext */ \
|
0, /* pNext */ \
|
||||||
zVfsName, /* zName */ \
|
VFSNAME, /* zName */ \
|
||||||
(void *)pVfsAppData, /* pAppData */ \
|
(void*)FINDER, /* pAppData */ \
|
||||||
unixOpen, /* xOpen */ \
|
unixOpen, /* xOpen */ \
|
||||||
unixDelete, /* xDelete */ \
|
unixDelete, /* xDelete */ \
|
||||||
unixAccess, /* xAccess */ \
|
unixAccess, /* xAccess */ \
|
||||||
@@ -4616,21 +4608,25 @@ int sqlite3_os_init(void){
|
|||||||
unixGetLastError /* xGetLastError */ \
|
unixGetLastError /* xGetLastError */ \
|
||||||
}
|
}
|
||||||
|
|
||||||
int i;
|
unsigned int i;
|
||||||
static sqlite3_vfs aVfs[] = {
|
static sqlite3_vfs aVfs[] = {
|
||||||
UNIXVFS("unix", LOCKING_STYLE_AUTOMATIC),
|
#if SQLITE_ENABLE_LOCKING_STYLE && defined(__DARWIN__)
|
||||||
UNIXVFS("unix-posix", LOCKING_STYLE_POSIX),
|
UNIXVFS("unix", autolockIoFinder ),
|
||||||
UNIXVFS("unix-none", LOCKING_STYLE_NONE),
|
#else
|
||||||
UNIXVFS("unix-dotfile", LOCKING_STYLE_DOTFILE),
|
UNIXVFS("unix", posixIoFinder ),
|
||||||
|
#endif
|
||||||
|
UNIXVFS("unix-none", nolockIoFinder ),
|
||||||
|
UNIXVFS("unix-dotfile", dotlockIoFinder ),
|
||||||
#if OS_VXWORKS
|
#if OS_VXWORKS
|
||||||
UNIXVFS("unix-namedsem",LOCKING_STYLE_NAMEDSEM),
|
UNIXVFS("unix-namedsem", semIoFinder ),
|
||||||
#endif
|
#endif
|
||||||
#if SQLITE_ENABLE_LOCKING_STYLE
|
#if SQLITE_ENABLE_LOCKING_STYLE
|
||||||
UNIXVFS("unix-flock", LOCKING_STYLE_FLOCK),
|
UNIXVFS("unix-posix", posixIoFinder ),
|
||||||
|
UNIXVFS("unix-flock", flockIoFinder ),
|
||||||
#endif
|
#endif
|
||||||
#if SQLITE_ENABLE_LOCKING_STYLE && defined(__DARWIN__)
|
#if SQLITE_ENABLE_LOCKING_STYLE && defined(__DARWIN__)
|
||||||
UNIXVFS("unix-afp", LOCKING_STYLE_AFP),
|
UNIXVFS("unix-afp", afpIoFinder ),
|
||||||
UNIXVFS("unix-proxy", LOCKING_STYLE_PROXY)
|
UNIXVFS("unix-proxy", proxyIoFinder ),
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
|
for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
|
||||||
|
21
src/test1.c
21
src/test1.c
@@ -13,7 +13,7 @@
|
|||||||
** is not included in the SQLite library. It is used for automated
|
** is not included in the SQLite library. It is used for automated
|
||||||
** testing of the SQLite library.
|
** testing of the SQLite library.
|
||||||
**
|
**
|
||||||
** $Id: test1.c,v 1.332 2008/11/28 15:37:20 drh Exp $
|
** $Id: test1.c,v 1.333 2008/11/29 00:56:53 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "tcl.h"
|
#include "tcl.h"
|
||||||
@@ -4527,20 +4527,29 @@ static int file_control_lockproxy_test(
|
|||||||
}
|
}
|
||||||
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
|
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
|
||||||
|
|
||||||
#ifdef SQLITE_ENABLE_LOCKING_STYLE
|
#if defined(SQLITE_ENABLE_LOCKING_STYLE) && defined(__DARWIN__)
|
||||||
{
|
{
|
||||||
char *proxyPath = "test.proxy";
|
char *proxyPath = "test.proxy";
|
||||||
char *testPath;
|
char *testPath;
|
||||||
rc = sqlite3_file_control(db, NULL, SQLITE_SET_LOCKPROXYFILE, proxyPath);
|
rc = sqlite3_file_control(db, NULL, SQLITE_SET_LOCKPROXYFILE, proxyPath);
|
||||||
if( rc ) { Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); return TCL_ERROR; }
|
if( rc ){
|
||||||
|
Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); return TCL_ERROR;
|
||||||
|
}
|
||||||
rc = sqlite3_file_control(db, NULL, SQLITE_GET_LOCKPROXYFILE, &testPath);
|
rc = sqlite3_file_control(db, NULL, SQLITE_GET_LOCKPROXYFILE, &testPath);
|
||||||
if( strncmp(proxyPath,testPath,11) ) {
|
if( strncmp(proxyPath,testPath,11) ) {
|
||||||
Tcl_AppendResult(interp, "Lock proxy file did not match the previously assigned value", 0);
|
Tcl_AppendResult(interp, "Lock proxy file did not match the "
|
||||||
|
"previously assigned value", 0);
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
if( rc ){
|
||||||
|
Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
|
||||||
return TCL_ERROR;
|
return TCL_ERROR;
|
||||||
}
|
}
|
||||||
if( rc ) { Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); return TCL_ERROR; }
|
|
||||||
rc = sqlite3_file_control(db, NULL, SQLITE_SET_LOCKPROXYFILE, proxyPath);
|
rc = sqlite3_file_control(db, NULL, SQLITE_SET_LOCKPROXYFILE, proxyPath);
|
||||||
if( rc ) { Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); return TCL_ERROR; }
|
if( rc ){
|
||||||
|
Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return TCL_OK;
|
return TCL_OK;
|
||||||
|
@@ -16,7 +16,7 @@
|
|||||||
** The focus of this file is providing the TCL testing layer
|
** The focus of this file is providing the TCL testing layer
|
||||||
** access to compile-time constants.
|
** access to compile-time constants.
|
||||||
**
|
**
|
||||||
** $Id: test_config.c,v 1.43 2008/11/21 00:10:35 aswift Exp $
|
** $Id: test_config.c,v 1.44 2008/11/29 00:56:54 drh Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "sqliteLimit.h"
|
#include "sqliteLimit.h"
|
||||||
@@ -392,10 +392,10 @@ Tcl_SetVar2(interp, "sqlite_options", "long_double",
|
|||||||
Tcl_SetVar2(interp, "sqlite_options", "schema_version", "1", TCL_GLOBAL_ONLY);
|
Tcl_SetVar2(interp, "sqlite_options", "schema_version", "1", TCL_GLOBAL_ONLY);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef SQLITE_ENABLE_LOCKING_STYLE
|
#if defined(SQLITE_ENABLE_LOCKING_STYLE) && defined(__DARWIN__)
|
||||||
Tcl_SetVar2(interp, "sqlite_options", "lock_proxy_pragmas", "1", TCL_GLOBAL_ONLY);
|
Tcl_SetVar2(interp,"sqlite_options","lock_proxy_pragmas","1",TCL_GLOBAL_ONLY);
|
||||||
#else
|
#else
|
||||||
Tcl_SetVar2(interp, "sqlite_options", "lock_proxy_pragmas", "0", TCL_GLOBAL_ONLY);
|
Tcl_SetVar2(interp,"sqlite_options","lock_proxy_pragmas","0",TCL_GLOBAL_ONLY);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user