1
0
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:
drh
2008-11-29 00:56:52 +00:00
parent 734c9864cb
commit 7708e9720b
5 changed files with 431 additions and 426 deletions

View File

@@ -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

View File

@@ -1 +1 @@
7825cd63e5cb390a9c2c05957ebc9b189612f04a 1017d2fb1935a278ef442030bf7bdf5e112c566a

View File

@@ -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++){

View File

@@ -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;

View File

@@ -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