mirror of
https://github.com/sqlite/sqlite.git
synced 2025-10-27 08:52:26 +03:00
Unix version of sqlite3OsLock(). (CVS 1520)
FossilOrigin-Name: 023d1760c1a720632b25c98d14bf521ab91861e2
This commit is contained in:
18
manifest
18
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Fix\stypo\son\shomepage\s(CVS\s1519)
|
C Unix\sversion\sof\ssqlite3OsLock().\s(CVS\s1520)
|
||||||
D 2004-06-01T12:59:50
|
D 2004-06-01T14:09:29
|
||||||
F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a
|
F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a
|
||||||
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
|
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
|
||||||
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
|
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
|
||||||
@@ -39,11 +39,11 @@ F src/insert.c 4268d9e3959cc845ea243fb4ec7507269404dad9
|
|||||||
F src/legacy.c ad23746f15f67e34577621b1875f639c94839e1f
|
F src/legacy.c ad23746f15f67e34577621b1875f639c94839e1f
|
||||||
F src/main.c 66c6c35e94f57a7505f7f44b5a9504fb60ca0730
|
F src/main.c 66c6c35e94f57a7505f7f44b5a9504fb60ca0730
|
||||||
F src/md5.c 4302e84ae516c616bb079c4e6d038c0addb33481
|
F src/md5.c 4302e84ae516c616bb079c4e6d038c0addb33481
|
||||||
F src/os.h ab42f4a7c4c716f26b988e759b6e12085a3bfc67
|
F src/os.h 833b9639720d1602d9bfa4ca69c615ec2bfe625a
|
||||||
F src/os_common.h 744286a27de55c52f1b18921e8d17abbf7fafc0f
|
F src/os_common.h 744286a27de55c52f1b18921e8d17abbf7fafc0f
|
||||||
F src/os_mac.c b823874690615ace0dd520d3ad1fe8bfd864b7e0
|
F src/os_mac.c b823874690615ace0dd520d3ad1fe8bfd864b7e0
|
||||||
F src/os_mac.h 51d2445f47e182ed32d3bd6937f81070c6fd9bd4
|
F src/os_mac.h 51d2445f47e182ed32d3bd6937f81070c6fd9bd4
|
||||||
F src/os_unix.c 585665eccd31a9bb4dc090bc6b5e29d8d42899f0
|
F src/os_unix.c 3dc2868d7ff477323f2eaedda0e05921afb6f124
|
||||||
F src/os_unix.h 426e1480f0847a7f8ba22aa9ac5115520875610b
|
F src/os_unix.h 426e1480f0847a7f8ba22aa9ac5115520875610b
|
||||||
F src/os_win.c 92b51a38437b98d8aa3ac05b57c71e1d1092e5be
|
F src/os_win.c 92b51a38437b98d8aa3ac05b57c71e1d1092e5be
|
||||||
F src/os_win.h 5d41af24caaef6c13a2d8e2399caa1c57d45c84d
|
F src/os_win.h 5d41af24caaef6c13a2d8e2399caa1c57d45c84d
|
||||||
@@ -59,7 +59,7 @@ F src/sqlite.h.in d8222d4a1f76468560b60f2b7f5b592995ebd5cf
|
|||||||
F src/sqliteInt.h 8a3a6dc8ef5141563698a3b7a62fca7158cff1f5
|
F src/sqliteInt.h 8a3a6dc8ef5141563698a3b7a62fca7158cff1f5
|
||||||
F src/table.c af14284fa36c8d41f6829e3f2819dce07d3e2de2
|
F src/table.c af14284fa36c8d41f6829e3f2819dce07d3e2de2
|
||||||
F src/tclsqlite.c ed8663e7703346ace72ca3899dba15dbfc0883d7
|
F src/tclsqlite.c ed8663e7703346ace72ca3899dba15dbfc0883d7
|
||||||
F src/test1.c 42c494918ecfab5a86586a28a66a73968312aad1
|
F src/test1.c 4a3cc1b628a29f24c0a43227a035d0f2a96eb634
|
||||||
F src/test2.c 6195a1ca2c8d0d2d93644e86da3289b403486872
|
F src/test2.c 6195a1ca2c8d0d2d93644e86da3289b403486872
|
||||||
F src/test3.c 86117b74ec7353d76f5cd85c144c7cda23a7e11b
|
F src/test3.c 86117b74ec7353d76f5cd85c144c7cda23a7e11b
|
||||||
F src/test4.c caf675e443460ec76b04d78e1688986c17c82cec
|
F src/test4.c caf675e443460ec76b04d78e1688986c17c82cec
|
||||||
@@ -214,7 +214,7 @@ F www/support.tcl 67682848d6ddd283370451dc3da2e56cded9fc9a
|
|||||||
F www/tclsqlite.tcl 19191cf2a1010eaeff74c51d83fd5f5a4d899075
|
F www/tclsqlite.tcl 19191cf2a1010eaeff74c51d83fd5f5a4d899075
|
||||||
F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
|
F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
|
||||||
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
|
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
|
||||||
P 915cba57123f859c7f128bd52580573877c502ba
|
P a84ece250035d02e399ec208aded524c20c12737
|
||||||
R 869771be1ad6b0ff5d2cfdaa96e9bfc9
|
R 3b5d7842c2050c5f20aa6a72a163fd62
|
||||||
U drh
|
U danielk1977
|
||||||
Z b8d78d36bfca5048d38c8cf79e8d6789
|
Z e93eb17e32e32c7486f10dc44fff52c2
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
a84ece250035d02e399ec208aded524c20c12737
|
023d1760c1a720632b25c98d14bf521ab91861e2
|
||||||
9
src/os.h
9
src/os.h
@@ -80,6 +80,14 @@
|
|||||||
# define TEMP_FILE_PREFIX "sqlite_"
|
# define TEMP_FILE_PREFIX "sqlite_"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
** The following values may be passed as the second argument to
|
||||||
|
** sqlite3OsLock().
|
||||||
|
*/
|
||||||
|
#define SHARED_LOCK 1
|
||||||
|
#define RESERVED_LOCK 2
|
||||||
|
#define PENDING_LOCK 3
|
||||||
|
#define EXCLUSIVE_LOCK 4
|
||||||
|
|
||||||
int sqlite3OsDelete(const char*);
|
int sqlite3OsDelete(const char*);
|
||||||
int sqlite3OsFileExists(const char*);
|
int sqlite3OsFileExists(const char*);
|
||||||
@@ -105,5 +113,6 @@ int sqlite3OsCurrentTime(double*);
|
|||||||
void sqlite3OsEnterMutex(void);
|
void sqlite3OsEnterMutex(void);
|
||||||
void sqlite3OsLeaveMutex(void);
|
void sqlite3OsLeaveMutex(void);
|
||||||
char *sqlite3OsFullPathname(const char*);
|
char *sqlite3OsFullPathname(const char*);
|
||||||
|
int sqlite3OsLock(OsFile*, int);
|
||||||
|
|
||||||
#endif /* _SQLITE_OS_H_ */
|
#endif /* _SQLITE_OS_H_ */
|
||||||
|
|||||||
169
src/os_unix.c
169
src/os_unix.c
@@ -172,6 +172,7 @@ struct lockKey {
|
|||||||
struct lockInfo {
|
struct lockInfo {
|
||||||
struct lockKey key; /* The lookup key */
|
struct lockKey key; /* The lookup key */
|
||||||
int cnt; /* 0: unlocked. -1: write lock. 1...: read lock. */
|
int cnt; /* 0: unlocked. -1: write lock. 1...: read lock. */
|
||||||
|
int locktype; /* One of SHARED_LOCK, RESERVED_LOCK etc. */
|
||||||
int nRef; /* Number of pointers to this structure */
|
int nRef; /* Number of pointers to this structure */
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -265,6 +266,7 @@ int findLockInfo(
|
|||||||
pLock->key = key1;
|
pLock->key = key1;
|
||||||
pLock->nRef = 1;
|
pLock->nRef = 1;
|
||||||
pLock->cnt = 0;
|
pLock->cnt = 0;
|
||||||
|
pLock->locktype = 0;
|
||||||
pOld = sqlite3HashInsert(&lockHash, &pLock->key, sizeof(key1), pLock);
|
pOld = sqlite3HashInsert(&lockHash, &pLock->key, sizeof(key1), pLock);
|
||||||
if( pOld!=0 ){
|
if( pOld!=0 ){
|
||||||
assert( pOld==pLock );
|
assert( pOld==pLock );
|
||||||
@@ -648,36 +650,7 @@ int sqlite3OsFileSize(OsFile *id, off_t *pSize){
|
|||||||
*/
|
*/
|
||||||
int sqlite3OsReadLock(OsFile *id){
|
int sqlite3OsReadLock(OsFile *id){
|
||||||
int rc;
|
int rc;
|
||||||
sqlite3OsEnterMutex();
|
return sqlite3OsLock(id, SHARED_LOCK);
|
||||||
if( id->pLock->cnt>0 ){
|
|
||||||
if( !id->locked ){
|
|
||||||
id->pLock->cnt++;
|
|
||||||
id->locked = 1;
|
|
||||||
id->pOpen->nLock++;
|
|
||||||
}
|
|
||||||
rc = SQLITE_OK;
|
|
||||||
}else if( id->locked || id->pLock->cnt==0 ){
|
|
||||||
struct flock lock;
|
|
||||||
int s;
|
|
||||||
lock.l_type = F_RDLCK;
|
|
||||||
lock.l_whence = SEEK_SET;
|
|
||||||
lock.l_start = lock.l_len = 0L;
|
|
||||||
s = fcntl(id->fd, F_SETLK, &lock);
|
|
||||||
if( s!=0 ){
|
|
||||||
rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY;
|
|
||||||
}else{
|
|
||||||
rc = SQLITE_OK;
|
|
||||||
if( !id->locked ){
|
|
||||||
id->pOpen->nLock++;
|
|
||||||
id->locked = 1;
|
|
||||||
}
|
|
||||||
id->pLock->cnt = 1;
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
rc = SQLITE_BUSY;
|
|
||||||
}
|
|
||||||
sqlite3OsLeaveMutex();
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -688,27 +661,132 @@ int sqlite3OsReadLock(OsFile *id){
|
|||||||
*/
|
*/
|
||||||
int sqlite3OsWriteLock(OsFile *id){
|
int sqlite3OsWriteLock(OsFile *id){
|
||||||
int rc;
|
int rc;
|
||||||
|
return sqlite3OsLock(id, EXCLUSIVE_LOCK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Lock the file with the lock specified by parameter locktype - one
|
||||||
|
** of the following:
|
||||||
|
**
|
||||||
|
** SHARED_LOCK
|
||||||
|
** RESERVED_LOCK
|
||||||
|
** PENDING_LOCK
|
||||||
|
** EXCLUSIVE_LOCK
|
||||||
|
*/
|
||||||
|
int sqlite3OsLock(OsFile *id, int locktype){
|
||||||
|
int rc = SQLITE_OK;
|
||||||
|
struct lockInfo *pLock = id->pLock;
|
||||||
|
struct flock lock;
|
||||||
|
int s;
|
||||||
|
|
||||||
|
/* It is an error to request any kind of lock before a shared lock */
|
||||||
|
if( locktype>SHARED_LOCK && id->locked==0 ){
|
||||||
|
rc = sqlite3OsLock(id, SHARED_LOCK);
|
||||||
|
if( rc!=SQLITE_OK ) return rc;
|
||||||
|
}
|
||||||
|
assert( locktype==SHARED_LOCK || id->locked!=0 );
|
||||||
|
|
||||||
|
/* If there is already a lock of this type or more restrictive on the
|
||||||
|
** OsFile, do nothing. Don't use the end_lock: exit path, as
|
||||||
|
** sqlite3OsEnterMutex() hasn't been called yet.
|
||||||
|
*/
|
||||||
|
if( id->locked>=locktype ){
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
sqlite3OsEnterMutex();
|
sqlite3OsEnterMutex();
|
||||||
if( id->pLock->cnt==0 || (id->pLock->cnt==1 && id->locked==1) ){
|
|
||||||
struct flock lock;
|
/* If some thread using this PID has a lock via a different OsFile*
|
||||||
int s;
|
** handle that precludes the requested lock, return BUSY.
|
||||||
lock.l_type = F_WRLCK;
|
*/
|
||||||
lock.l_whence = SEEK_SET;
|
if( (id->locked!=pLock->locktype &&
|
||||||
lock.l_start = lock.l_len = 0L;
|
(pLock->locktype>RESERVED_LOCK || locktype!=SHARED_LOCK)) ||
|
||||||
|
(locktype>RESERVED_LOCK && pLock->cnt>1)
|
||||||
|
){
|
||||||
|
rc = SQLITE_BUSY;
|
||||||
|
goto end_lock;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If a SHARED lock is requested, and some thread using this PID already
|
||||||
|
** has a SHARED or RESERVED lock, then increment reference counts and
|
||||||
|
** return SQLITE_OK.
|
||||||
|
*/
|
||||||
|
if( locktype==SHARED_LOCK &&
|
||||||
|
(pLock->locktype==SHARED_LOCK || pLock->locktype==RESERVED_LOCK) ){
|
||||||
|
assert( locktype==SHARED_LOCK );
|
||||||
|
assert( id->locked==0 );
|
||||||
|
id->locked = SHARED_LOCK;
|
||||||
|
pLock->cnt++;
|
||||||
|
id->pOpen->nLock++;
|
||||||
|
goto end_lock;
|
||||||
|
}
|
||||||
|
|
||||||
|
lock.l_len = 1L;
|
||||||
|
lock.l_whence = SEEK_SET;
|
||||||
|
|
||||||
|
/* If control gets to this point, then actually go ahead and make
|
||||||
|
** operating system calls for the specified lock.
|
||||||
|
*/
|
||||||
|
if( locktype==SHARED_LOCK ){
|
||||||
|
assert( pLock->cnt==0 );
|
||||||
|
assert( id->pOpen->nLock==0 );
|
||||||
|
assert( pLock->locktype==0 );
|
||||||
|
|
||||||
|
/* Grab a read-lock on byte 2. This ensures that no other process
|
||||||
|
** has a PENDING lock.
|
||||||
|
*/
|
||||||
|
lock.l_type = F_RDLCK;
|
||||||
|
lock.l_start = 2;
|
||||||
s = fcntl(id->fd, F_SETLK, &lock);
|
s = fcntl(id->fd, F_SETLK, &lock);
|
||||||
if( s!=0 ){
|
if( s ){
|
||||||
|
rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY;
|
||||||
|
goto end_lock;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now get a read-lock on byte 0 and renege on the byte 2 lock. */
|
||||||
|
lock.l_start = 0;
|
||||||
|
s = fcntl(id->fd, F_SETLK, &lock);
|
||||||
|
lock.l_start = 2;
|
||||||
|
lock.l_type = F_UNLCK;
|
||||||
|
fcntl(id->fd, F_SETLK, &lock);
|
||||||
|
if( s ){
|
||||||
rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY;
|
rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY;
|
||||||
}else{
|
}else{
|
||||||
rc = SQLITE_OK;
|
id->locked = SHARED_LOCK;
|
||||||
if( !id->locked ){
|
id->pOpen->nLock = 1;
|
||||||
id->pOpen->nLock++;
|
pLock->cnt = 1;
|
||||||
id->locked = 1;
|
|
||||||
}
|
|
||||||
id->pLock->cnt = -1;
|
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
rc = SQLITE_BUSY;
|
/* The request was for a RESERVED, PENDING or EXCLUSIVE lock. It is
|
||||||
|
** assumed that there is a SHARED or greater lock on the file
|
||||||
|
** already.
|
||||||
|
*/
|
||||||
|
assert( 0!=id->locked );
|
||||||
|
lock.l_type = F_WRLCK;
|
||||||
|
switch( locktype ){
|
||||||
|
case RESERVED_LOCK:
|
||||||
|
lock.l_start = 1;
|
||||||
|
break;
|
||||||
|
case PENDING_LOCK:
|
||||||
|
lock.l_start = 2;
|
||||||
|
break;
|
||||||
|
case EXCLUSIVE_LOCK:
|
||||||
|
lock.l_start = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
s = fcntl(id->fd, F_SETLK, &lock);
|
||||||
|
if( s ){
|
||||||
|
rc = (errno==EINVAL) ? SQLITE_NOLFS : SQLITE_BUSY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
id->locked = locktype;
|
||||||
|
pLock->locktype = locktype;
|
||||||
|
assert(pLock->locktype==RESERVED_LOCK||(id->pOpen->nLock==1&&pLock->cnt==1));
|
||||||
|
|
||||||
|
end_lock:
|
||||||
sqlite3OsLeaveMutex();
|
sqlite3OsLeaveMutex();
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -725,6 +803,7 @@ int sqlite3OsUnlock(OsFile *id){
|
|||||||
sqlite3OsEnterMutex();
|
sqlite3OsEnterMutex();
|
||||||
assert( id->pLock->cnt!=0 );
|
assert( id->pLock->cnt!=0 );
|
||||||
if( id->pLock->cnt>1 ){
|
if( id->pLock->cnt>1 ){
|
||||||
|
id->locked = 0;
|
||||||
id->pLock->cnt--;
|
id->pLock->cnt--;
|
||||||
rc = SQLITE_OK;
|
rc = SQLITE_OK;
|
||||||
}else{
|
}else{
|
||||||
@@ -739,6 +818,8 @@ int sqlite3OsUnlock(OsFile *id){
|
|||||||
}else{
|
}else{
|
||||||
rc = SQLITE_OK;
|
rc = SQLITE_OK;
|
||||||
id->pLock->cnt = 0;
|
id->pLock->cnt = 0;
|
||||||
|
id->pLock->locktype = 0;
|
||||||
|
id->locked = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
|
|||||||
160
src/test1.c
160
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.68 2004/05/31 23:56:43 danielk1977 Exp $
|
** $Id: test1.c,v 1.69 2004/06/01 14:09:29 danielk1977 Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "tcl.h"
|
#include "tcl.h"
|
||||||
@@ -117,6 +117,21 @@ static int getStmtPointer(
|
|||||||
return TCL_OK;
|
return TCL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Decode a pointer to an sqlite3_stmt object.
|
||||||
|
*/
|
||||||
|
static int getFilePointer(
|
||||||
|
Tcl_Interp *interp,
|
||||||
|
const char *zArg,
|
||||||
|
OsFile **ppFile
|
||||||
|
){
|
||||||
|
if( sscanf(zArg, PTR_FMT, (void**)ppFile)!=1 ){
|
||||||
|
Tcl_AppendResult(interp, "\"", zArg, "\" is not a valid pointer value", 0);
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
return TCL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Generate a text representation of a pointer that can be understood
|
** Generate a text representation of a pointer that can be understood
|
||||||
** by the getDbPointer and getVmPointer routines above.
|
** by the getDbPointer and getVmPointer routines above.
|
||||||
@@ -1677,7 +1692,144 @@ static int test_stmt_int(
|
|||||||
return TCL_OK;
|
return TCL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Usage: sqlite3OsOpenReadWrite <filename>
|
||||||
|
*/
|
||||||
|
static int test_sqlite3OsOpenReadWrite(
|
||||||
|
void * clientData,
|
||||||
|
Tcl_Interp *interp,
|
||||||
|
int objc,
|
||||||
|
Tcl_Obj *CONST objv[]
|
||||||
|
){
|
||||||
|
OsFile * pFile;
|
||||||
|
int rc;
|
||||||
|
int dummy;
|
||||||
|
char zBuf[100];
|
||||||
|
|
||||||
|
if( objc!=2 ){
|
||||||
|
Tcl_AppendResult(interp, "wrong # args: should be \"",
|
||||||
|
Tcl_GetString(objv[0]), " filename", 0);
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
pFile = sqliteMalloc(sizeof(OsFile));
|
||||||
|
rc = sqlite3OsOpenReadWrite(Tcl_GetString(objv[1]), pFile, &dummy);
|
||||||
|
if( rc!=SQLITE_OK ){
|
||||||
|
sqliteFree(pFile);
|
||||||
|
Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC);
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
makePointerStr(interp, zBuf, pFile);
|
||||||
|
Tcl_SetResult(interp, zBuf, 0);
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Usage: sqlite3OsClose <file handle>
|
||||||
|
*/
|
||||||
|
static int test_sqlite3OsClose(
|
||||||
|
void * clientData,
|
||||||
|
Tcl_Interp *interp,
|
||||||
|
int objc,
|
||||||
|
Tcl_Obj *CONST objv[]
|
||||||
|
){
|
||||||
|
OsFile * pFile;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if( objc!=2 ){
|
||||||
|
Tcl_AppendResult(interp, "wrong # args: should be \"",
|
||||||
|
Tcl_GetString(objv[0]), " filehandle", 0);
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( getFilePointer(interp, Tcl_GetString(objv[1]), &pFile) ){
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
rc = sqlite3OsClose(pFile);
|
||||||
|
if( rc!=SQLITE_OK ){
|
||||||
|
Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC);
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
sqliteFree(pFile);
|
||||||
|
return TCL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Usage: sqlite3OsLock <file handle> <locktype>
|
||||||
|
*/
|
||||||
|
static int test_sqlite3OsLock(
|
||||||
|
void * clientData,
|
||||||
|
Tcl_Interp *interp,
|
||||||
|
int objc,
|
||||||
|
Tcl_Obj *CONST objv[]
|
||||||
|
){
|
||||||
|
OsFile * pFile;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if( objc!=3 ){
|
||||||
|
Tcl_AppendResult(interp, "wrong # args: should be \"",
|
||||||
|
Tcl_GetString(objv[0]),
|
||||||
|
" filehandle (SHARED|RESERVED|PENDING|EXCLUSIVE)", 0);
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( getFilePointer(interp, Tcl_GetString(objv[1]), &pFile) ){
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( 0==strcmp("SHARED", Tcl_GetString(objv[2])) ){
|
||||||
|
rc = sqlite3OsLock(pFile, SHARED_LOCK);
|
||||||
|
}
|
||||||
|
else if( 0==strcmp("RESERVED", Tcl_GetString(objv[2])) ){
|
||||||
|
rc = sqlite3OsLock(pFile, RESERVED_LOCK);
|
||||||
|
}
|
||||||
|
else if( 0==strcmp("PENDING", Tcl_GetString(objv[2])) ){
|
||||||
|
rc = sqlite3OsLock(pFile, PENDING_LOCK);
|
||||||
|
}
|
||||||
|
else if( 0==strcmp("EXCLUSIVE", Tcl_GetString(objv[2])) ){
|
||||||
|
rc = sqlite3OsLock(pFile, EXCLUSIVE_LOCK);
|
||||||
|
}else{
|
||||||
|
Tcl_AppendResult(interp, "wrong # args: should be \"",
|
||||||
|
Tcl_GetString(objv[0]),
|
||||||
|
" filehandle (SHARED|RESERVED|PENDING|EXCLUSIVE)", 0);
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( rc!=SQLITE_OK ){
|
||||||
|
Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC);
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
return TCL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Usage: sqlite3OsUnlock <file handle>
|
||||||
|
*/
|
||||||
|
static int test_sqlite3OsUnlock(
|
||||||
|
void * clientData,
|
||||||
|
Tcl_Interp *interp,
|
||||||
|
int objc,
|
||||||
|
Tcl_Obj *CONST objv[]
|
||||||
|
){
|
||||||
|
OsFile * pFile;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if( objc!=2 ){
|
||||||
|
Tcl_AppendResult(interp, "wrong # args: should be \"",
|
||||||
|
Tcl_GetString(objv[0]), " filehandle", 0);
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( getFilePointer(interp, Tcl_GetString(objv[1]), &pFile) ){
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
rc = sqlite3OsUnlock(pFile);
|
||||||
|
if( rc!=SQLITE_OK ){
|
||||||
|
Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC);
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
return TCL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Register commands with the TCL interpreter.
|
** Register commands with the TCL interpreter.
|
||||||
@@ -1753,6 +1905,12 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
|||||||
{ "sqlite3_column_decltype16", test_stmt_utf16,sqlite3_column_decltype16},
|
{ "sqlite3_column_decltype16", test_stmt_utf16,sqlite3_column_decltype16},
|
||||||
{ "sqlite3_column_name16", test_stmt_utf16, sqlite3_column_name16},
|
{ "sqlite3_column_name16", test_stmt_utf16, sqlite3_column_name16},
|
||||||
|
|
||||||
|
/* Functions from os.h */
|
||||||
|
{ "sqlite3OsOpenReadWrite",test_sqlite3OsOpenReadWrite, 0 },
|
||||||
|
{ "sqlite3OsClose", test_sqlite3OsClose, 0 },
|
||||||
|
{ "sqlite3OsLock", test_sqlite3OsLock, 0 },
|
||||||
|
{ "sqlite3OsUnlock", test_sqlite3OsUnlock, 0 },
|
||||||
|
|
||||||
};
|
};
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user