Update the locking-style code in os_unix.c. The updates are as yet untested. (CVS 4244)
FossilOrigin-Name: 41f2175b1ed7eccf271b687ee5c3ea262a0cd096
This commit is contained in:
parent
f036aef061
commit
ad94b58a5e
12
manifest
12
manifest
@ -1,5 +1,5 @@
|
||||
C Fix\sfull_fsync()\srelated\sfunctionality\sbroken\sas\spart\sof\sthe\smigration\sto\ssqlite3_vfs.\s(CVS\s4243)
|
||||
D 2007-08-20T05:36:51
|
||||
C Update\sthe\slocking-style\scode\sin\sos_unix.c.\sThe\supdates\sare\sas\syet\suntested.\s(CVS\s4244)
|
||||
D 2007-08-20T06:44:22
|
||||
F Makefile.in 0c0e53720f658c7a551046442dd7afba0b72bfbe
|
||||
F Makefile.linux-gcc 65241babba6faf1152bf86574477baab19190499
|
||||
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
||||
@ -98,7 +98,7 @@ F src/os_os2.c cba4e96fadb949076c717108fe0599d1a3c2e446
|
||||
F src/os_os2.h e5f17dd69333632bbc3112881ea407c37d245eb3
|
||||
F src/os_test.c 49833426101f99aee4bb5f6a44b7c4b2029fda1c
|
||||
F src/os_test.h 903c93554c23d88f34f667f1979e4a1cee792af3
|
||||
F src/os_unix.c bf192a86b9aa5ca3889613fde9bac084274f5eed
|
||||
F src/os_unix.c dc726e5fa18f114c4a7e0a0205af0ea898b85374
|
||||
F src/os_unix.h 5768d56d28240d3fe4537fac08cc85e4fb52279e
|
||||
F src/os_win.c d868d5f9e95ec9c1b9e2a30c54c996053db6dddd
|
||||
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
|
||||
@ -529,7 +529,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
|
||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
||||
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
|
||||
P a258c4ec240f96bccfe493e98d0827ec7dd12e67
|
||||
R 92a15d078029bdab5b614dc93495e5a2
|
||||
P cb24cda179c2b526c5ac48be75e372d2b9db808c
|
||||
R a091562a0f5306b5cbde266cfb56849b
|
||||
U danielk1977
|
||||
Z 04438648939c1033589e63dd0eec6b5f
|
||||
Z fa00070b2e6492f7113b7bd3fe1e6225
|
||||
|
@ -1 +1 @@
|
||||
cb24cda179c2b526c5ac48be75e372d2b9db808c
|
||||
41f2175b1ed7eccf271b687ee5c3ea262a0cd096
|
628
src/os_unix.c
628
src/os_unix.c
@ -81,7 +81,7 @@
|
||||
|
||||
|
||||
/*
|
||||
** The unixFile structure is subclass of OsFile specific for the unix
|
||||
** The unixFile structure is subclass of sqlite3_file specific for the unix
|
||||
** protability layer.
|
||||
*/
|
||||
typedef struct unixFile unixFile;
|
||||
@ -98,7 +98,7 @@ struct unixFile {
|
||||
int dirfd; /* File descriptor for the directory */
|
||||
i64 offset; /* Seek offset */
|
||||
#ifdef SQLITE_UNIX_THREADS
|
||||
pthread_t tid; /* The thread that "owns" this OsFile */
|
||||
pthread_t tid; /* The thread that "owns" this unixFile */
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -134,7 +134,6 @@ struct unixFile {
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_DISKIO
|
||||
|
||||
|
||||
/*
|
||||
** Define various macros that are missing from some systems.
|
||||
*/
|
||||
@ -173,18 +172,18 @@ struct unixFile {
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Set or check the OsFile.tid field. This field is set when an OsFile
|
||||
** is first opened. All subsequent uses of the OsFile verify that the
|
||||
** same thread is operating on the OsFile. Some operating systems do
|
||||
** Set or check the unixFile.tid field. This field is set when an unixFile
|
||||
** is first opened. All subsequent uses of the unixFile verify that the
|
||||
** same thread is operating on the unixFile. Some operating systems do
|
||||
** not allow locks to be overridden by other threads and that restriction
|
||||
** means that sqlite3* database handles cannot be moved from one thread
|
||||
** to another. This logic makes sure a user does not try to do that
|
||||
** by mistake.
|
||||
**
|
||||
** Version 3.3.1 (2006-01-15): OsFiles can be moved from one thread to
|
||||
** Version 3.3.1 (2006-01-15): unixFile can be moved from one thread to
|
||||
** another as long as we are running on a system that supports threads
|
||||
** overriding each others locks (which now the most common behavior)
|
||||
** or if no locks are held. But the OsFile.pLock field needs to be
|
||||
** or if no locks are held. But the unixFile.pLock field needs to be
|
||||
** recomputed because its key includes the thread-id. See the
|
||||
** transferOwnership() function below for additional information
|
||||
*/
|
||||
@ -232,11 +231,11 @@ struct unixFile {
|
||||
** locks to see if another thread has previously set a lock on that same
|
||||
** inode.
|
||||
**
|
||||
** The OsFile structure for POSIX is no longer just an integer file
|
||||
** The sqlite3_file structure for POSIX is no longer just an integer file
|
||||
** descriptor. It is now a structure that holds the integer file
|
||||
** descriptor and a pointer to a structure that describes the internal
|
||||
** locks on the corresponding inode. There is one locking structure
|
||||
** per inode, so if the same inode is opened twice, both OsFile structures
|
||||
** per inode, so if the same inode is opened twice, both unixFile structures
|
||||
** point to the same locking structure. The locking structure keeps
|
||||
** a reference count (so we will know when to delete it) and a "cnt"
|
||||
** field that tells us its internal lock status. cnt==0 means the
|
||||
@ -255,11 +254,11 @@ struct unixFile {
|
||||
**
|
||||
** If you close a file descriptor that points to a file that has locks,
|
||||
** all locks on that file that are owned by the current process are
|
||||
** released. To work around this problem, each OsFile structure contains
|
||||
** released. To work around this problem, each unixFile structure contains
|
||||
** a pointer to an openCnt structure. There is one openCnt structure
|
||||
** per open inode, which means that multiple OsFiles can point to a single
|
||||
** openCnt. When an attempt is made to close an OsFile, if there are
|
||||
** other OsFiles open on the same inode that are holding locks, the call
|
||||
** per open inode, which means that multiple unixFile can point to a single
|
||||
** openCnt. When an attempt is made to close an unixFile, if there are
|
||||
** other unixFile open on the same inode that are holding locks, the call
|
||||
** to close() the file descriptor is deferred until all of the locks clear.
|
||||
** The openCnt structure keeps a list of file descriptors that need to
|
||||
** be closed and that list is walked (and cleared) when the last lock
|
||||
@ -319,9 +318,9 @@ struct lockKey {
|
||||
** inode on each thread with a different process ID. (Threads have
|
||||
** different process IDs on linux, but not on most other unixes.)
|
||||
**
|
||||
** A single inode can have multiple file descriptors, so each OsFile
|
||||
** A single inode can have multiple file descriptors, so each unixFile
|
||||
** structure contains a pointer to an instance of this object and this
|
||||
** object keeps a count of the number of OsFiles pointing to it.
|
||||
** object keeps a count of the number of unixFile pointing to it.
|
||||
*/
|
||||
struct lockInfo {
|
||||
struct lockKey key; /* The lookup key */
|
||||
@ -389,6 +388,9 @@ typedef enum {
|
||||
} sqlite3LockingStyle;
|
||||
#endif /* SQLITE_ENABLE_LOCKING_STYLE */
|
||||
|
||||
/*
|
||||
** Helper functions to obtain and relinquish the global mutex.
|
||||
*/
|
||||
static void enterMutex(){
|
||||
sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_GLOBAL));
|
||||
}
|
||||
@ -567,8 +569,10 @@ static void releaseOpenCnt(struct openCnt *pOpen){
|
||||
** Tests a byte-range locking query to see if byte range locks are
|
||||
** supported, if not we fall back to dotlockLockingStyle.
|
||||
*/
|
||||
static sqlite3LockingStyle sqlite3TestLockingStyle(const char *filePath,
|
||||
int fd) {
|
||||
static sqlite3LockingStyle sqlite3TestLockingStyle(
|
||||
const char *filePath,
|
||||
int fd
|
||||
){
|
||||
/* test byte-range lock using fcntl */
|
||||
struct flock lockInfo;
|
||||
|
||||
@ -577,7 +581,7 @@ static sqlite3LockingStyle sqlite3TestLockingStyle(const char *filePath,
|
||||
lockInfo.l_whence = SEEK_SET;
|
||||
lockInfo.l_type = F_RDLCK;
|
||||
|
||||
if (fcntl(fd, F_GETLK, &lockInfo) != -1) {
|
||||
if( fcntl(fd, F_GETLK, &lockInfo)!=-1 ) {
|
||||
return posixLockingStyle;
|
||||
}
|
||||
|
||||
@ -594,8 +598,10 @@ static sqlite3LockingStyle sqlite3TestLockingStyle(const char *filePath,
|
||||
** assignments are based on Darwin/OSX behavior and have not been tested on
|
||||
** other systems.
|
||||
*/
|
||||
static sqlite3LockingStyle sqlite3DetectLockingStyle(const char *filePath,
|
||||
int fd) {
|
||||
static sqlite3LockingStyle sqlite3DetectLockingStyle(
|
||||
const char *filePath,
|
||||
int fd
|
||||
){
|
||||
|
||||
#ifdef SQLITE_FIXED_LOCKING_STYLE
|
||||
return (sqlite3LockingStyle)SQLITE_FIXED_LOCKING_STYLE;
|
||||
@ -790,178 +796,6 @@ static int transferOwnership(unixFile *pFile){
|
||||
# define transferOwnership(X) SQLITE_OK
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Delete the named file
|
||||
*/
|
||||
int sqlite3UnixDelete(const char *zFilename){
|
||||
SimulateIOError(return SQLITE_IOERR_DELETE);
|
||||
unlink(zFilename);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return TRUE if the named file exists.
|
||||
*/
|
||||
int sqlite3UnixFileExists(const char *zFilename){
|
||||
return access(zFilename, 0)==0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Attempt to open a file for both reading and writing. If that
|
||||
** fails, try opening it read-only. If the file does not exist,
|
||||
** try to create it.
|
||||
**
|
||||
** On success, a handle for the open file is written to *id
|
||||
** and *pReadonly is set to 0 if the file was opened for reading and
|
||||
** writing or 1 if the file was opened read-only. The function returns
|
||||
** SQLITE_OK.
|
||||
**
|
||||
** On failure, the function returns SQLITE_CANTOPEN and leaves
|
||||
** *id and *pReadonly unchanged.
|
||||
*/
|
||||
#if 0
|
||||
int sqlite3UnixOpenReadWrite(
|
||||
const char *zFilename,
|
||||
sqlite3_file **pId,
|
||||
int *pReadonly
|
||||
){
|
||||
int h;
|
||||
|
||||
assert( 0==*pId );
|
||||
h = open(zFilename, O_RDWR|O_CREAT|O_LARGEFILE|O_BINARY,
|
||||
SQLITE_DEFAULT_FILE_PERMISSIONS);
|
||||
if( h<0 ){
|
||||
#ifdef EISDIR
|
||||
if( errno==EISDIR ){
|
||||
return SQLITE_CANTOPEN;
|
||||
}
|
||||
#endif
|
||||
h = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY);
|
||||
if( h<0 ){
|
||||
return SQLITE_CANTOPEN;
|
||||
}
|
||||
*pReadonly = 1;
|
||||
}else{
|
||||
*pReadonly = 0;
|
||||
}
|
||||
|
||||
return CRASH_TEST_OVERRIDE(
|
||||
zFilename, pId, allocateUnixFile(h, pId, zFilename, 0)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Attempt to open a new file for exclusive access by this process.
|
||||
** The file will be opened for both reading and writing. To avoid
|
||||
** a potential security problem, we do not allow the file to have
|
||||
** previously existed. Nor do we allow the file to be a symbolic
|
||||
** link.
|
||||
**
|
||||
** If delFlag is true, then make arrangements to automatically delete
|
||||
** the file when it is closed.
|
||||
**
|
||||
** On success, write the file handle into *id and return SQLITE_OK.
|
||||
**
|
||||
** On failure, return SQLITE_CANTOPEN.
|
||||
*/
|
||||
int sqlite3UnixOpenExclusive(
|
||||
const char *zFilename,
|
||||
sqlite3_file **pId,
|
||||
int delFlag
|
||||
){
|
||||
int h;
|
||||
|
||||
assert( 0==*pId );
|
||||
h = open(zFilename,
|
||||
O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW|O_LARGEFILE|O_BINARY,
|
||||
delFlag ? 0600 : SQLITE_DEFAULT_FILE_PERMISSIONS);
|
||||
if( h<0 ){
|
||||
return SQLITE_CANTOPEN;
|
||||
}
|
||||
return CRASH_TEST_OVERRIDE(
|
||||
zFilename, pId, allocateUnixFile(h, pId, zFilename, delFlag)
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
** Attempt to open a new file for read-only access.
|
||||
**
|
||||
** On success, write the file handle into *id and return SQLITE_OK.
|
||||
**
|
||||
** On failure, return SQLITE_CANTOPEN.
|
||||
*/
|
||||
int sqlite3UnixOpenReadOnly(const char *zFilename, sqlite3_file **pId){
|
||||
int h;
|
||||
|
||||
assert( 0==*pId );
|
||||
h = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY);
|
||||
if( h<0 ){
|
||||
return SQLITE_CANTOPEN;
|
||||
}
|
||||
return CRASH_TEST_OVERRIDE(
|
||||
zFilename, pId, allocateUnixFile(h, pId, zFilename, 0)
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Attempt to open a file descriptor for the directory that contains a
|
||||
** file. This file descriptor can be used to fsync() the directory
|
||||
** in order to make sure the creation of a new file is actually written
|
||||
** to disk.
|
||||
**
|
||||
** This routine is only meaningful for Unix. It is a no-op under
|
||||
** windows since windows does not support hard links.
|
||||
**
|
||||
** If FULL_FSYNC is enabled, this function is not longer useful,
|
||||
** a FULL_FSYNC sync applies to all pending disk operations.
|
||||
**
|
||||
** On success, a handle for a previously open file at *id is
|
||||
** updated with the new directory file descriptor and SQLITE_OK is
|
||||
** returned.
|
||||
**
|
||||
** On failure, the function returns SQLITE_CANTOPEN and leaves
|
||||
** *id unchanged.
|
||||
*/
|
||||
#if 0
|
||||
static int unixOpenDirectory(
|
||||
OsFile *id,
|
||||
const char *zDirname
|
||||
){
|
||||
int h;
|
||||
unixFile *pFile = (unixFile*)id;
|
||||
assert( pFile!=0 );
|
||||
SET_THREADID(pFile);
|
||||
assert( pFile->dirfd<0 );
|
||||
pFile->dirfd = h = open(zDirname, O_RDONLY|O_BINARY, 0);
|
||||
if( h<0 ){
|
||||
return SQLITE_CANTOPEN;
|
||||
}
|
||||
#ifdef FD_CLOEXEC
|
||||
fcntl(h, F_SETFD, fcntl(h, F_GETFD, 0) | FD_CLOEXEC);
|
||||
#endif
|
||||
OSTRACE3("OPENDIR %-3d %s\n", h, zDirname);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Check that a given pathname is a directory and is writable
|
||||
**
|
||||
*/
|
||||
int sqlite3UnixIsDirWritable(char *zBuf){
|
||||
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
|
||||
struct stat buf;
|
||||
if( zBuf==0 ) return 0;
|
||||
if( zBuf[0]==0 ) return 0;
|
||||
if( stat(zBuf, &buf) ) return 0;
|
||||
if( !S_ISDIR(buf.st_mode) ) return 0;
|
||||
if( access(zBuf, 07) ) return 0;
|
||||
#endif /* SQLITE_OMIT_PAGER_PRAGMAS */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
** Seek to the offset in id->offset then read cnt bytes into pBuf.
|
||||
** Return the number of bytes actually read. Update the offset.
|
||||
@ -1214,36 +1048,6 @@ static int unixSync(sqlite3_file *id, int flags){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Sync the directory zDirname. This is a no-op on operating systems other
|
||||
** than UNIX.
|
||||
**
|
||||
** This is used to make sure the master journal file has truely been deleted
|
||||
** before making changes to individual journals on a multi-database commit.
|
||||
** The F_FULLFSYNC option is not needed here.
|
||||
*/
|
||||
int sqlite3UnixSyncDirectory(const char *zDirname){
|
||||
#ifdef SQLITE_DISABLE_DIRSYNC
|
||||
return SQLITE_OK;
|
||||
#else
|
||||
int fd;
|
||||
int r;
|
||||
fd = open(zDirname, O_RDONLY|O_BINARY, 0);
|
||||
OSTRACE3("DIRSYNC %-3d (%s)\n", fd, zDirname);
|
||||
if( fd<0 ){
|
||||
return SQLITE_CANTOPEN;
|
||||
}
|
||||
r = fsync(fd);
|
||||
close(fd);
|
||||
SimulateIOError( r=1 );
|
||||
if( r ){
|
||||
return SQLITE_IOERR_DIR_FSYNC;
|
||||
}else{
|
||||
return SQLITE_OK;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
** Truncate an open file to a specified size
|
||||
*/
|
||||
@ -1388,7 +1192,7 @@ static int unixLock(sqlite3_file *id, int locktype){
|
||||
locktypeName(pLock->locktype), pLock->cnt , getpid());
|
||||
|
||||
/* 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
|
||||
** unixFile, do nothing. Don't use the end_lock: exit path, as
|
||||
** enterMutex() hasn't been called yet.
|
||||
*/
|
||||
if( pFile->locktype>=locktype ){
|
||||
@ -1416,7 +1220,7 @@ static int unixLock(sqlite3_file *id, int locktype){
|
||||
}
|
||||
pLock = pFile->pLock;
|
||||
|
||||
/* If some thread using this PID has a lock via a different OsFile*
|
||||
/* If some thread using this PID has a lock via a different unixFile*
|
||||
** handle that precludes the requested lock, return BUSY.
|
||||
*/
|
||||
if( (pFile->locktype!=pLock->locktype &&
|
||||
@ -1689,13 +1493,19 @@ struct ByteRangeLockPB2
|
||||
|
||||
#define afpfsByteRangeLock2FSCTL _IOWR('z', 23, struct ByteRangeLockPB2)
|
||||
|
||||
/* return 0 on success, 1 on failure. To match the behavior of the
|
||||
normal posix file locking (used in unixLock for example), we should
|
||||
provide 'richer' return codes - specifically to differentiate between
|
||||
'file busy' and 'file system error' results */
|
||||
static int _AFPFSSetLock(const char *path, int fd, unsigned long long offset,
|
||||
unsigned long long length, int setLockFlag)
|
||||
{
|
||||
/*
|
||||
** Return 0 on success, 1 on failure. To match the behavior of the
|
||||
** normal posix file locking (used in unixLock for example), we should
|
||||
** provide 'richer' return codes - specifically to differentiate between
|
||||
** 'file busy' and 'file system error' results.
|
||||
*/
|
||||
static int _AFPFSSetLock(
|
||||
const char *path,
|
||||
int fd,
|
||||
unsigned long long offset,
|
||||
unsigned long long length,
|
||||
int setLockFlag
|
||||
){
|
||||
struct ByteRangeLockPB2 pb;
|
||||
int err;
|
||||
|
||||
@ -1722,7 +1532,7 @@ static int _AFPFSSetLock(const char *path, int fd, unsigned long long offset,
|
||||
** non-zero. If the file is unlocked or holds only SHARED locks, then
|
||||
** return zero.
|
||||
*/
|
||||
static int afpUnixCheckReservedLock(OsFile *id){
|
||||
static int afpUnixCheckReservedLock(sqlite3_file *id){
|
||||
int r = 0;
|
||||
unixFile *pFile = (unixFile*)id;
|
||||
|
||||
@ -1755,7 +1565,7 @@ static int afpUnixCheckReservedLock(OsFile *id){
|
||||
|
||||
/* AFP-style locking following the behavior of unixLock, see the unixLock
|
||||
** function comments for details of lock management. */
|
||||
static int afpUnixLock(OsFile *id, int locktype)
|
||||
static int afpUnixLock(sqlite3_file *id, int locktype)
|
||||
{
|
||||
int rc = SQLITE_OK;
|
||||
unixFile *pFile = (unixFile*)id;
|
||||
@ -1766,7 +1576,7 @@ static int afpUnixLock(OsFile *id, int locktype)
|
||||
OSTRACE5("LOCK %d %s was %s pid=%d\n", pFile->h,
|
||||
locktypeName(locktype), locktypeName(pFile->locktype), getpid());
|
||||
/* If there is already a lock of this type or more restrictive on the
|
||||
** OsFile, do nothing. Don't use the afp_end_lock: exit path, as
|
||||
** unixFile, do nothing. Don't use the afp_end_lock: exit path, as
|
||||
** enterMutex() hasn't been called yet.
|
||||
*/
|
||||
if( pFile->locktype>=locktype ){
|
||||
@ -1889,7 +1699,7 @@ afp_end_lock:
|
||||
** If the locking level of the file descriptor is already at or below
|
||||
** the requested locking level, this routine is a no-op.
|
||||
*/
|
||||
static int afpUnixUnlock(OsFile *id, int locktype) {
|
||||
static int afpUnixUnlock(sqlite3_file *id, int locktype) {
|
||||
struct flock lock;
|
||||
int rc = SQLITE_OK;
|
||||
unixFile *pFile = (unixFile*)id;
|
||||
@ -1957,26 +1767,24 @@ static int afpUnixUnlock(OsFile *id, int locktype) {
|
||||
/*
|
||||
** Close a file & cleanup AFP specific locking context
|
||||
*/
|
||||
static int afpUnixClose(OsFile **pId) {
|
||||
unixFile *id = (unixFile*)*pId;
|
||||
|
||||
if( !id ) return SQLITE_OK;
|
||||
static int afpUnixClose(sqlite3_file *id) {
|
||||
unixFile *pFile = (unixFile*)pId;
|
||||
|
||||
if( !pFile ) return SQLITE_OK;
|
||||
afpUnixUnlock(*pId, NO_LOCK);
|
||||
/* free the AFP locking structure */
|
||||
if (id->lockingContext != NULL) {
|
||||
if (((afpLockingContext *)id->lockingContext)->filePath != NULL)
|
||||
sqlite3_free(((afpLockingContext*)id->lockingContext)->filePath);
|
||||
sqlite3_free(id->lockingContext);
|
||||
if (pFile->lockingContext != NULL) {
|
||||
if (((afpLockingContext *)pFile->lockingContext)->filePath != NULL)
|
||||
sqlite3_free(((afpLockingContext*)pFile->lockingContext)->filePath);
|
||||
sqlite3_free(pFile->lockingContext);
|
||||
}
|
||||
|
||||
if( id->dirfd>=0 ) close(id->dirfd);
|
||||
id->dirfd = -1;
|
||||
close(id->h);
|
||||
id->isOpen = 0;
|
||||
OSTRACE2("CLOSE %-3d\n", id->h);
|
||||
|
||||
if( pFile->dirfd>=0 ) close(pFile->dirfd);
|
||||
pFile->dirfd = -1;
|
||||
close(pFile->h);
|
||||
pFile->isOpen = 0;
|
||||
OSTRACE2("CLOSE %-3d\n", pFile->h);
|
||||
OpenCounter(-1);
|
||||
sqlite3_free(id);
|
||||
*pId = 0;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
@ -1988,7 +1796,7 @@ static int afpUnixClose(OsFile **pId) {
|
||||
*/
|
||||
typedef void flockLockingContext;
|
||||
|
||||
static int flockUnixCheckReservedLock(OsFile *id) {
|
||||
static int flockUnixCheckReservedLock(sqlite3_file *id) {
|
||||
unixFile *pFile = (unixFile*)id;
|
||||
|
||||
if (pFile->locktype == RESERVED_LOCK) {
|
||||
@ -2005,7 +1813,7 @@ static int flockUnixCheckReservedLock(OsFile *id) {
|
||||
}
|
||||
}
|
||||
|
||||
static int flockUnixLock(OsFile *id, int locktype) {
|
||||
static int flockUnixLock(sqlite3_file *id, int locktype) {
|
||||
unixFile *pFile = (unixFile*)id;
|
||||
|
||||
/* if we already have a lock, it is exclusive.
|
||||
@ -2027,7 +1835,7 @@ static int flockUnixLock(OsFile *id, int locktype) {
|
||||
}
|
||||
}
|
||||
|
||||
static int flockUnixUnlock(OsFile *id, int locktype) {
|
||||
static int flockUnixUnlock(sqlite3_file *id, int locktype) {
|
||||
unixFile *pFile = (unixFile*)id;
|
||||
|
||||
assert( locktype<=SHARED_LOCK );
|
||||
@ -2056,23 +1864,21 @@ static int flockUnixUnlock(OsFile *id, int locktype) {
|
||||
/*
|
||||
** Close a file.
|
||||
*/
|
||||
static int flockUnixClose(OsFile **pId) {
|
||||
unixFile *id = (unixFile*)*pId;
|
||||
static int flockUnixClose(sqlite3_file *pId) {
|
||||
unixFile *pFile = (unixFile*)*pId;
|
||||
|
||||
if( !id ) return SQLITE_OK;
|
||||
if( !pFile ) return SQLITE_OK;
|
||||
flockUnixUnlock(*pId, NO_LOCK);
|
||||
|
||||
if( id->dirfd>=0 ) close(id->dirfd);
|
||||
id->dirfd = -1;
|
||||
if( pFile->dirfd>=0 ) close(pFile->dirfd);
|
||||
pFile->dirfd = -1;
|
||||
enterMutex();
|
||||
|
||||
close(id->h);
|
||||
close(pFile->h);
|
||||
leaveMutex();
|
||||
id->isOpen = 0;
|
||||
OSTRACE2("CLOSE %-3d\n", id->h);
|
||||
pFile->isOpen = 0;
|
||||
OSTRACE2("CLOSE %-3d\n", pFile->h);
|
||||
OpenCounter(-1);
|
||||
sqlite3_free(id);
|
||||
*pId = 0;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
@ -2088,7 +1894,7 @@ struct dotlockLockingContext {
|
||||
};
|
||||
|
||||
|
||||
static int dotlockUnixCheckReservedLock(OsFile *id) {
|
||||
static int dotlockUnixCheckReservedLock(sqlite3_file *id) {
|
||||
unixFile *pFile = (unixFile*)id;
|
||||
dotlockLockingContext *context =
|
||||
(dotlockLockingContext *) pFile->lockingContext;
|
||||
@ -2106,7 +1912,7 @@ static int dotlockUnixCheckReservedLock(OsFile *id) {
|
||||
}
|
||||
}
|
||||
|
||||
static int dotlockUnixLock(OsFile *id, int locktype) {
|
||||
static int dotlockUnixLock(sqlite3_file *id, int locktype) {
|
||||
unixFile *pFile = (unixFile*)id;
|
||||
dotlockLockingContext *context =
|
||||
(dotlockLockingContext *) pFile->lockingContext;
|
||||
@ -2140,7 +1946,7 @@ static int dotlockUnixLock(OsFile *id, int locktype) {
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
static int dotlockUnixUnlock(OsFile *id, int locktype) {
|
||||
static int dotlockUnixUnlock(sqlite3_file *id, int locktype) {
|
||||
unixFile *pFile = (unixFile*)id;
|
||||
dotlockLockingContext *context =
|
||||
(dotlockLockingContext *) pFile->lockingContext;
|
||||
@ -2167,31 +1973,29 @@ static int dotlockUnixUnlock(OsFile *id, int locktype) {
|
||||
/*
|
||||
** Close a file.
|
||||
*/
|
||||
static int dotlockUnixClose(OsFile **pId) {
|
||||
unixFile *id = (unixFile*)*pId;
|
||||
static int dotlockUnixClose(sqlite3_file *id) {
|
||||
unixFile *pFile = (unixFile*)id;
|
||||
|
||||
if( !id ) return SQLITE_OK;
|
||||
if( !pFile ) return SQLITE_OK;
|
||||
dotlockUnixUnlock(*pId, NO_LOCK);
|
||||
/* free the dotlock locking structure */
|
||||
if (id->lockingContext != NULL) {
|
||||
if (((dotlockLockingContext *)id->lockingContext)->lockPath != NULL)
|
||||
if (pFile->lockingContext != NULL) {
|
||||
if (((dotlockLockingContext *)pFile->lockingContext)->lockPath != NULL)
|
||||
sqlite3_free( ( (dotlockLockingContext *)
|
||||
id->lockingContext)->lockPath);
|
||||
sqlite3_free(id->lockingContext);
|
||||
pFile->lockingContext)->lockPath);
|
||||
sqlite3_free(pFile->lockingContext);
|
||||
}
|
||||
|
||||
if( id->dirfd>=0 ) close(id->dirfd);
|
||||
id->dirfd = -1;
|
||||
if( pFile->dirfd>=0 ) close(pFile->dirfd);
|
||||
pFile->dirfd = -1;
|
||||
enterMutex();
|
||||
|
||||
close(id->h);
|
||||
close(pFile->h);
|
||||
|
||||
leaveMutex();
|
||||
id->isOpen = 0;
|
||||
OSTRACE2("CLOSE %-3d\n", id->h);
|
||||
pFile->isOpen = 0;
|
||||
OSTRACE2("CLOSE %-3d\n", pFile->h);
|
||||
OpenCounter(-1);
|
||||
sqlite3_free(id);
|
||||
*pId = 0;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
@ -2203,59 +2007,57 @@ static int dotlockUnixClose(OsFile **pId) {
|
||||
*/
|
||||
typedef void nolockLockingContext;
|
||||
|
||||
static int nolockUnixCheckReservedLock(OsFile *id) {
|
||||
static int nolockUnixCheckReservedLock(sqlite3_file *id) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nolockUnixLock(OsFile *id, int locktype) {
|
||||
static int nolockUnixLock(sqlite3_file *id, int locktype) {
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
static int nolockUnixUnlock(OsFile *id, int locktype) {
|
||||
static int nolockUnixUnlock(sqlite3_file *id, int locktype) {
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Close a file.
|
||||
*/
|
||||
static int nolockUnixClose(OsFile **pId) {
|
||||
unixFile *id = (unixFile*)*pId;
|
||||
static int nolockUnixClose(sqlite3_file *id) {
|
||||
unixFile *pFile = (unixFile*)id;
|
||||
|
||||
if( !id ) return SQLITE_OK;
|
||||
if( id->dirfd>=0 ) close(id->dirfd);
|
||||
id->dirfd = -1;
|
||||
if( !pFile ) return SQLITE_OK;
|
||||
if( pFile->dirfd>=0 ) close(pFile->dirfd);
|
||||
pFile->dirfd = -1;
|
||||
enterMutex();
|
||||
|
||||
close(id->h);
|
||||
close(pFile->h);
|
||||
|
||||
leaveMutex();
|
||||
id->isOpen = 0;
|
||||
OSTRACE2("CLOSE %-3d\n", id->h);
|
||||
pFile->isOpen = 0;
|
||||
OSTRACE2("CLOSE %-3d\n", pFile->h);
|
||||
OpenCounter(-1);
|
||||
sqlite3_free(id);
|
||||
*pId = 0;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
#endif /* SQLITE_ENABLE_LOCKING_STYLE */
|
||||
|
||||
#if 0
|
||||
|
||||
/*
|
||||
** Change the value of the fullsync flag in the given file descriptor.
|
||||
** TODO: xBreakLock() for this vfs.
|
||||
*/
|
||||
static void unixSetFullSync(OsFile *id, int v){
|
||||
((unixFile*)id)->fullSync = v;
|
||||
static int unixBreakLock(sqlite3_file *id){
|
||||
assert(!"TODO: unixBreakLock()");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the underlying file handle for an OsFile
|
||||
** Return an integer that indices the type of lock currently held
|
||||
** by this handle. (Used for testing and analysis only.)
|
||||
*/
|
||||
static int unixFileHandle(OsFile *id){
|
||||
return ((unixFile*)id)->h;
|
||||
static int unixLockState(sqlite3_file *id){
|
||||
return ((unixFile*)id)->locktype;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Return the sector size in bytes of the underlying block device for
|
||||
** the specified file. This is almost always 512 bytes, but may be
|
||||
@ -2277,21 +2079,8 @@ static int unixDeviceCharacteristics(sqlite3_file *id){
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int unixBreakLock(sqlite3_file *id){
|
||||
assert(!"TODO: unixBreakLock()");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return an integer that indices the type of lock currently held
|
||||
** by this handle. (Used for testing and analysis only.)
|
||||
*/
|
||||
static int unixLockState(sqlite3_file *id){
|
||||
return ((unixFile*)id)->locktype;
|
||||
}
|
||||
|
||||
/*
|
||||
** This vector defines all the methods that can operate on an OsFile
|
||||
** This vector defines all the methods that can operate on an sqlite3_file
|
||||
** for unix.
|
||||
*/
|
||||
static const sqlite3_io_methods sqlite3UnixIoMethod = {
|
||||
@ -2313,91 +2102,87 @@ static const sqlite3_io_methods sqlite3UnixIoMethod = {
|
||||
|
||||
#ifdef SQLITE_ENABLE_LOCKING_STYLE
|
||||
/*
|
||||
** This vector defines all the methods that can operate on an OsFile
|
||||
** for unix with AFP style file locking.
|
||||
*/
|
||||
static const IoMethod sqlite3AFPLockingUnixIoMethod = {
|
||||
afpUnixClose,
|
||||
unixOpenDirectory,
|
||||
unixRead,
|
||||
unixWrite,
|
||||
unixSeek,
|
||||
unixTruncate,
|
||||
unixSync,
|
||||
unixSetFullSync,
|
||||
unixFileHandle,
|
||||
unixFileSize,
|
||||
afpUnixLock,
|
||||
afpUnixUnlock,
|
||||
unixLockState,
|
||||
afpUnixCheckReservedLock,
|
||||
unixSectorSize,
|
||||
};
|
||||
|
||||
/*
|
||||
** This vector defines all the methods that can operate on an OsFile
|
||||
** for unix with flock() style file locking.
|
||||
*/
|
||||
static const IoMethod sqlite3FlockLockingUnixIoMethod = {
|
||||
flockUnixClose,
|
||||
unixOpenDirectory,
|
||||
unixRead,
|
||||
unixWrite,
|
||||
unixSeek,
|
||||
unixTruncate,
|
||||
unixSync,
|
||||
unixSetFullSync,
|
||||
unixFileHandle,
|
||||
unixFileSize,
|
||||
flockUnixLock,
|
||||
flockUnixUnlock,
|
||||
unixLockState,
|
||||
flockUnixCheckReservedLock,
|
||||
unixSectorSize,
|
||||
};
|
||||
|
||||
/*
|
||||
** This vector defines all the methods that can operate on an OsFile
|
||||
** for unix with dotlock style file locking.
|
||||
*/
|
||||
static const IoMethod sqlite3DotlockLockingUnixIoMethod = {
|
||||
dotlockUnixClose,
|
||||
unixOpenDirectory,
|
||||
unixRead,
|
||||
unixWrite,
|
||||
unixSeek,
|
||||
unixTruncate,
|
||||
unixSync,
|
||||
unixSetFullSync,
|
||||
unixFileHandle,
|
||||
unixFileSize,
|
||||
dotlockUnixLock,
|
||||
dotlockUnixUnlock,
|
||||
unixLockState,
|
||||
dotlockUnixCheckReservedLock,
|
||||
unixSectorSize,
|
||||
};
|
||||
|
||||
/*
|
||||
** This vector defines all the methods that can operate on an OsFile
|
||||
** for unix with dotlock style file locking.
|
||||
*/
|
||||
static const IoMethod sqlite3NolockLockingUnixIoMethod = {
|
||||
nolockUnixClose,
|
||||
unixOpenDirectory,
|
||||
** This vector defines all the methods that can operate on an sqlite3_file
|
||||
** for unix with AFP style file locking.
|
||||
*/
|
||||
static const sqlite3_io_methods sqlite3AFPLockingUnixIoMethod = {
|
||||
1, /* iVersion */
|
||||
unixClose,
|
||||
unixRead,
|
||||
unixWrite,
|
||||
unixTruncate,
|
||||
unixSync,
|
||||
unixFileSize,
|
||||
afpUnixLock,
|
||||
afpUnixUnlock,
|
||||
afpUnixCheckReservedLock,
|
||||
unixBreakLock,
|
||||
unixLockState,
|
||||
unixSectorSize,
|
||||
unixDeviceCharacteristics
|
||||
};
|
||||
|
||||
/*
|
||||
** This vector defines all the methods that can operate on an sqlite3_file
|
||||
** for unix with flock() style file locking.
|
||||
*/
|
||||
static const sqlite3_io_methods sqlite3FlockLockingUnixIoMethod = {
|
||||
1, /* iVersion */
|
||||
flockUnixClose,
|
||||
unixRead,
|
||||
unixWrite,
|
||||
unixTruncate,
|
||||
unixSync,
|
||||
unixFileSize,
|
||||
flockUnixLock,
|
||||
flockUnixUnlock,
|
||||
flockUnixCheckReservedLock,
|
||||
unixBreakLock,
|
||||
unixLockState,
|
||||
unixSectorSize,
|
||||
unixDeviceCharacteristics
|
||||
};
|
||||
|
||||
/*
|
||||
** This vector defines all the methods that can operate on an sqlite3_file
|
||||
** for unix with dotlock style file locking.
|
||||
*/
|
||||
static const sqlite3_io_methods sqlite3DotlockLockingUnixIoMethod = {
|
||||
1, /* iVersion */
|
||||
dotlockUnixClose,
|
||||
unixRead,
|
||||
unixWrite,
|
||||
unixTruncate,
|
||||
unixSync,
|
||||
unixFileSize,
|
||||
dotlockUnixLock,
|
||||
dotlockUnixUnlock,
|
||||
dotlockUnixCheckReservedLock,
|
||||
unixBreakLock,
|
||||
unixLockState,
|
||||
unixSectorSize,
|
||||
unixDeviceCharacteristics
|
||||
};
|
||||
|
||||
/*
|
||||
** This vector defines all the methods that can operate on an sqlite3_file
|
||||
** for unix with dotlock style file locking.
|
||||
*/
|
||||
static const sqlite3_io_methods sqlite3NolockLockingUnixIoMethod = {
|
||||
1, /* iVersion */
|
||||
nolockUnixClose,
|
||||
unixRead,
|
||||
unixWrite,
|
||||
unixSeek,
|
||||
unixTruncate,
|
||||
unixSync,
|
||||
unixSetFullSync,
|
||||
unixFileHandle,
|
||||
unixFileSize,
|
||||
nolockUnixLock,
|
||||
nolockUnixUnlock,
|
||||
unixLockState,
|
||||
nolockUnixCheckReservedLock,
|
||||
unixBreakLock,
|
||||
unixLockState,
|
||||
unixSectorSize,
|
||||
unixDeviceCharacteristics
|
||||
};
|
||||
|
||||
#endif /* SQLITE_ENABLE_LOCKING_STYLE */
|
||||
@ -2409,27 +2194,26 @@ static const IoMethod sqlite3NolockLockingUnixIoMethod = {
|
||||
*/
|
||||
#ifdef SQLITE_ENABLE_LOCKING_STYLE
|
||||
/*
|
||||
** 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 allocateUnixFile(
|
||||
** 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(
|
||||
int h, /* Open file descriptor of file being opened */
|
||||
OsFile **pId, /* Write completed initialization here */
|
||||
int dirfd, /* Directory file descriptor */
|
||||
sqlite3_file *pId, /* Write completed initialization here */
|
||||
const char *zFilename, /* Name of the file being opened */
|
||||
int delFlag /* Delete-on-or-before-close flag */
|
||||
){
|
||||
sqlite3LockingStyle lockingStyle;
|
||||
unixFile *pNew;
|
||||
unixFile f;
|
||||
unixFile *pNew = (unixFile *)pId;
|
||||
int rc;
|
||||
|
||||
memset(&f, 0, sizeof(f));
|
||||
memset(pNew, 0, sizeof(unixFile));
|
||||
lockingStyle = sqlite3DetectLockingStyle(zFilename, h);
|
||||
if ( lockingStyle == posixLockingStyle ) {
|
||||
enterMutex();
|
||||
rc = findLockInfo(h, &f.pLock, &f.pOpen);
|
||||
rc = findLockInfo(h, &pNew->pLock, &pNew->pOpen);
|
||||
leaveMutex();
|
||||
if( rc ){
|
||||
close(h);
|
||||
@ -2438,26 +2222,21 @@ static int allocateUnixFile(
|
||||
}
|
||||
} else {
|
||||
/* pLock and pOpen are only used for posix advisory locking */
|
||||
f.pLock = NULL;
|
||||
f.pOpen = NULL;
|
||||
pNew->pLock = NULL;
|
||||
pNew->pOpen = NULL;
|
||||
}
|
||||
if( delFlag ){
|
||||
unlink(zFilename);
|
||||
}
|
||||
f.dirfd = -1;
|
||||
f.h = h;
|
||||
SET_THREADID(&f);
|
||||
pNew->dirfd = -1;
|
||||
pNew->h = h;
|
||||
SET_THREADID(pNew);
|
||||
pNew = sqlite3_malloc( sizeof(unixFile) );
|
||||
if( pNew==0 ){
|
||||
close(h);
|
||||
enterMutex();
|
||||
releaseLockInfo(f.pLock);
|
||||
releaseOpenCnt(f.pOpen);
|
||||
releaseLockInfo(pNew->pLock);
|
||||
releaseOpenCnt(pNew->pOpen);
|
||||
leaveMutex();
|
||||
*pId = 0;
|
||||
return SQLITE_NOMEM;
|
||||
}else{
|
||||
*pNew = f;
|
||||
switch(lockingStyle) {
|
||||
case afpLockingStyle: {
|
||||
/* afp locking uses the file path so it needs to be included in
|
||||
@ -2502,7 +2281,6 @@ static int allocateUnixFile(
|
||||
default:
|
||||
pNew->pMethod = &sqlite3NolockLockingUnixIoMethod;
|
||||
}
|
||||
*pId = (OsFile*)pNew;
|
||||
OpenCounter(+1);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
@ -2547,6 +2325,16 @@ static int fillInUnixFile(
|
||||
** with other miscellanous aspects of the operating system interface
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
** Open a file descriptor to the directory containing file zFilename.
|
||||
** If successful, *pFd is set to the opened file descriptor and
|
||||
** SQLITE_OK is returned. If an error occurs, either SQLITE_NOMEM
|
||||
** or SQLITE_CANTOPEN is returned and *pFd is set to an undefined
|
||||
** value.
|
||||
**
|
||||
** If SQLITE_OK is returned, the caller is responsible for closing
|
||||
** the file descriptor *pFd using close().
|
||||
*/
|
||||
static int openDirectory(const char *zFilename, int *pFd){
|
||||
char *zDirname;
|
||||
int ii;
|
||||
@ -2575,6 +2363,8 @@ static int openDirectory(const char *zFilename, int *pFd){
|
||||
}
|
||||
|
||||
/*
|
||||
** Open the file zPath.
|
||||
**
|
||||
** Previously, the SQLite OS layer used three functions in place of this
|
||||
** one:
|
||||
**
|
||||
|
Loading…
x
Reference in New Issue
Block a user