DBD-SQLite-Amalgamation
view release on metacpan or search on metacpan
sqlite-amalgamation.c view on Meta::CPAN
**
** Bummer. If you ask me, this is broken. Badly broken. It means
** that we cannot use POSIX locks to synchronize file access among
** competing threads of the same process. POSIX locks will work fine
** to synchronize access for threads in separate processes, but not
** threads within the same process.
**
** To work around the problem, SQLite has to manage file locks internally
** on its own. Whenever a new database is opened, we have to find the
** specific inode of the database file (the inode is determined by the
** st_dev and st_ino fields of the stat structure that fstat() fills in)
** and check for locks already existing on that inode. When locks are
** created or removed, we have to look at our own internal record of the
** locks to see if another thread has previously set a lock on that same
** inode.
**
** 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 unixFile structures
sqlite-amalgamation.c view on Meta::CPAN
/* Testing for flock() can give false positives. So if if the above
** test fails, then we fall back to using dot-file style locking.
*/
return LOCKING_STYLE_DOTFILE;
}
#endif
/*
** 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.
*/
static int detectLockingStyle(
sqlite3_vfs *pVfs,
sqlite-amalgamation.c view on Meta::CPAN
int fd, /* The file descriptor used in the key */
struct lockInfo **ppLock, /* Return the lockInfo structure here */
struct openCnt **ppOpen /* Return the openCnt structure here */
){
int rc;
struct lockKey key1;
struct openKey key2;
struct stat statbuf;
struct lockInfo *pLock;
struct openCnt *pOpen;
rc = fstat(fd, &statbuf);
if( rc!=0 ){
#ifdef EOVERFLOW
if( errno==EOVERFLOW ) return SQLITE_NOLFS;
#endif
return SQLITE_IOERR;
}
/* On OS X on an msdos filesystem, the inode number is reported
** incorrectly for zero-size files. See ticket #3260. To work
** around this problem (we consider it a bug in OS X, not SQLite)
** we always increase the file size to 1 by writing a single byte
** prior to accessing the inode number. The one byte written is
** an ASCII 'S' character which also happens to be the first byte
** in the header of every SQLite database. In this way, if there
** is a race condition such that another thread has already populated
** the first page of the database, no damage is done.
*/
if( statbuf.st_size==0 ){
write(fd, "S", 1);
rc = fstat(fd, &statbuf);
if( rc!=0 ){
return SQLITE_IOERR;
}
}
memset(&key1, 0, sizeof(key1));
key1.dev = statbuf.st_dev;
key1.ino = statbuf.st_ino;
#if SQLITE_THREADSAFE
if( threadsOverrideEachOthersLocks<0 ){
sqlite-amalgamation.c view on Meta::CPAN
}
}
/*
** Determine the current size of a file in bytes
*/
static int unixFileSize(sqlite3_file *id, i64 *pSize){
int rc;
struct stat buf;
assert( id );
rc = fstat(((unixFile*)id)->h, &buf);
SimulateIOError( rc=1 );
if( rc!=0 ){
return SQLITE_IOERR_FSTAT;
}
*pSize = buf.st_size;
/* When opening a zero-size database, the findLockInfo() procedure
** writes a single byte into that file in order to work around a bug
** in the OS-X msdos filesystem. In order to avoid problems with upper
** layers, we need to report this file size as zero even though it is
sqlite-amalgamation.c view on Meta::CPAN
#pragma mark Old-School .lock file based locking
static int dotlockCheckReservedLock(sqlite3_file *id, int *pResOut) {
int r = 1;
unixFile *pFile = (unixFile*)id;
char *zLockFile = (char *)pFile->lockingContext;
if (pFile->locktype != RESERVED_LOCK) {
struct stat statBuf;
if (lstat(zLockFile, &statBuf) != 0){
/* file does not exist, we could have it if we want it */
r = 0;
}
}
*pResOut = r;
return SQLITE_OK;
}
static int dotlockLock(sqlite3_file *id, int locktype) {
sqlite-amalgamation.c view on Meta::CPAN
if (pFile->locktype > NO_LOCK) {
pFile->locktype = locktype;
/* Always update the timestamp on the old file */
utimes(zLockFile, NULL);
return SQLITE_OK;
}
/* check to see if lock file already exists */
struct stat statBuf;
if (lstat(zLockFile,&statBuf) == 0){
return SQLITE_BUSY; /* it does, busy */
}
/* grab an exclusive lock */
fd = open(zLockFile,O_RDONLY|O_CREAT|O_EXCL,0600);
if( fd<0 ){
/* failed to open/create the file, someone else may have stolen the lock */
return SQLITE_BUSY;
}
close(fd);
sqlite-amalgamation.c view on Meta::CPAN
/* It's odd to simulate an io-error here, but really this is just
** using the io-error infrastructure to test that SQLite handles this
** function failing.
*/
SimulateIOError( return SQLITE_IOERR );
azDirs[0] = sqlite3_temp_directory;
for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); i++){
if( azDirs[i]==0 ) continue;
if( stat(azDirs[i], &buf) ) continue;
if( !S_ISDIR(buf.st_mode) ) continue;
if( access(azDirs[i], 07) ) continue;
zDir = azDirs[i];
break;
}
/* Check that the output buffer is large enough for the temporary file
** name. If it is not, return SQLITE_ERROR.
*/
if( (strlen(zDir) + strlen(SQLITE_TEMP_FILE_PREFIX) + 17) >= nBuf ){
( run in 0.473 second using v1.01-cache-2.11-cpan-49f99fa48dc )