+++ /dev/null
-/*
-** 2004 May 22
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-******************************************************************************
-**
-** This file contains code that is specific to Unix systems. It is used
-** for testing SQLite only.
-*/
-#if OS_TEST /* This file is used for the test backend only */
-#include "sqliteInt.h"
-#include "os.h" /* Must be first to enable large file support */
-
-#define sqlite3OsOpenReadWrite sqlite3RealOpenReadWrite
-#define sqlite3OsOpenExclusive sqlite3RealOpenExclusive
-#define sqlite3OsOpenReadOnly sqlite3RealOpenReadOnly
-#define sqlite3OsOpenDirectory sqlite3RealOpenDirectory
-#define sqlite3OsClose sqlite3RealClose
-#define sqlite3OsRead sqlite3RealRead
-#define sqlite3OsWrite sqlite3RealWrite
-#define sqlite3OsSeek sqlite3RealSeek
-#define sqlite3OsSync sqlite3RealSync
-#define sqlite3OsTruncate sqlite3RealTruncate
-#define sqlite3OsFileSize sqlite3RealFileSize
-#define sqlite3OsLock sqlite3RealLock
-#define sqlite3OsUnlock sqlite3RealUnlock
-#define sqlite3OsCheckReservedLock sqlite3RealCheckReservedLock
-
-#define OsFile OsRealFile
-#define OS_UNIX 1
-#include "os_unix.c"
-#undef OS_UNIX
-#undef OsFile
-
-#undef sqlite3OsOpenReadWrite
-#undef sqlite3OsOpenExclusive
-#undef sqlite3OsOpenReadOnly
-#undef sqlite3OsOpenDirectory
-#undef sqlite3OsClose
-#undef sqlite3OsRead
-#undef sqlite3OsWrite
-#undef sqlite3OsSeek
-#undef sqlite3OsSync
-#undef sqlite3OsTruncate
-#undef sqlite3OsFileSize
-#undef sqlite3OsLock
-#undef sqlite3OsUnlock
-#undef sqlite3OsCheckReservedLock
-
-#define BLOCKSIZE 512
-#define BLOCK_OFFSET(x) ((x) * BLOCKSIZE)
-
-
-/*
-** The following variables control when a simulated crash occurs.
-**
-** If iCrashDelay is non-zero, then zCrashFile contains (full path) name of
-** a file that SQLite will call sqlite3OsSync() on. Each time this happens
-** iCrashDelay is decremented. If iCrashDelay is zero after being
-** decremented, a "crash" occurs during the sync() operation.
-**
-** In other words, a crash occurs the iCrashDelay'th time zCrashFile is
-** synced.
-*/
-static int iCrashDelay = 0;
-char zCrashFile[256];
-
-/*
-** Set the value of the two crash parameters.
-*/
-void sqlite3SetCrashParams(int iDelay, char const *zFile){
- sqlite3OsEnterMutex();
- assert( strlen(zFile)<256 );
- strcpy(zCrashFile, zFile);
- iCrashDelay = iDelay;
- sqlite3OsLeaveMutex();
-}
-
-/*
-** File zPath is being sync()ed. Return non-zero if this should
-** cause a crash.
-*/
-static int crashRequired(char const *zPath){
- int r;
- int n;
- sqlite3OsEnterMutex();
- n = strlen(zCrashFile);
- if( zCrashFile[n-1]=='*' ){
- n--;
- }else if( strlen(zPath)>n ){
- n = strlen(zPath);
- }
- r = 0;
- if( iCrashDelay>0 && strncmp(zPath, zCrashFile, n)==0 ){
- iCrashDelay--;
- if( iCrashDelay<=0 ){
- r = 1;
- }
- }
- sqlite3OsLeaveMutex();
- return r;
-}
-
-
-static OsTestFile *pAllFiles = 0;
-
-/*
-** Initialise the os_test.c specific fields of pFile.
-*/
-static void initFile(OsFile *id, char const *zName){
- OsTestFile *pFile = (OsTestFile *)
- sqliteMalloc(sizeof(OsTestFile) + strlen(zName)+1);
- pFile->nMaxWrite = 0;
- pFile->nBlk = 0;
- pFile->apBlk = 0;
- pFile->zName = (char *)(&pFile[1]);
- strcpy(pFile->zName, zName);
- *id = pFile;
- pFile->pNext = pAllFiles;
- pAllFiles = pFile;
-}
-
-/*
-** Undo the work done by initFile. Delete the OsTestFile structure
-** and unlink the structure from the pAllFiles list.
-*/
-static void closeFile(OsFile *id){
- OsTestFile *pFile = *id;
- if( pFile==pAllFiles ){
- pAllFiles = pFile->pNext;
- }else{
- OsTestFile *p;
- for(p=pAllFiles; p->pNext!=pFile; p=p->pNext ){
- assert( p );
- }
- p->pNext = pFile->pNext;
- }
- sqliteFree(pFile);
- *id = 0;
-}
-
-/*
-** Return the current seek offset from the start of the file. This
-** is unix-only code.
-*/
-static i64 osTell(OsTestFile *pFile){
- return lseek(pFile->fd.h, 0, SEEK_CUR);
-}
-
-/*
-** Load block 'blk' into the cache of pFile.
-*/
-static int cacheBlock(OsTestFile *pFile, int blk){
- if( blk>=pFile->nBlk ){
- int n = ((pFile->nBlk * 2) + 100 + blk);
- /* if( pFile->nBlk==0 ){ printf("DIRTY %s\n", pFile->zName); } */
- pFile->apBlk = (u8 **)sqliteRealloc(pFile->apBlk, n * sizeof(u8*));
- if( !pFile->apBlk ) return SQLITE_NOMEM;
- memset(&pFile->apBlk[pFile->nBlk], 0, (n - pFile->nBlk)*sizeof(u8*));
- pFile->nBlk = n;
- }
-
- if( !pFile->apBlk[blk] ){
- i64 filesize;
- int rc;
-
- u8 *p = sqliteMalloc(BLOCKSIZE);
- if( !p ) return SQLITE_NOMEM;
- pFile->apBlk[blk] = p;
-
- rc = sqlite3RealFileSize(&pFile->fd, &filesize);
- if( rc!=SQLITE_OK ) return rc;
-
- if( BLOCK_OFFSET(blk)<filesize ){
- int len = BLOCKSIZE;
- rc = sqlite3RealSeek(&pFile->fd, blk*BLOCKSIZE);
- if( BLOCK_OFFSET(blk+1)>filesize ){
- len = filesize - BLOCK_OFFSET(blk);
- }
- if( rc!=SQLITE_OK ) return rc;
- rc = sqlite3RealRead(&pFile->fd, p, len);
- if( rc!=SQLITE_OK ) return rc;
- }
- }
-
- return SQLITE_OK;
-}
-
-/* #define TRACE_WRITECACHE */
-
-/*
-** Write the cache of pFile to disk. If crash is non-zero, randomly
-** skip blocks when writing. The cache is deleted before returning.
-*/
-static int writeCache2(OsTestFile *pFile, int crash){
- int i;
- int nMax = pFile->nMaxWrite;
- i64 offset;
- int rc = SQLITE_OK;
-
- offset = osTell(pFile);
- for(i=0; i<pFile->nBlk; i++){
- u8 *p = pFile->apBlk[i];
- if( p ){
- int skip = 0;
- int trash = 0;
- if( crash ){
- char random;
- sqlite3_randomness(1, &random);
- if( random & 0x01 ){
- if( random & 0x02 ){
- trash = 1;
-#ifdef TRACE_WRITECACHE
-printf("Trashing block %d of %s\n", i, pFile->zName);
-#endif
- }else{
- skip = 1;
-#ifdef TRACE_WRITECACHE
-printf("Skiping block %d of %s\n", i, pFile->zName);
-#endif
- }
- }else{
-#ifdef TRACE_WRITECACHE
-printf("Writing block %d of %s\n", i, pFile->zName);
-#endif
- }
- }
- if( rc==SQLITE_OK ){
- rc = sqlite3RealSeek(&pFile->fd, BLOCK_OFFSET(i));
- }
- if( rc==SQLITE_OK && !skip ){
- int len = BLOCKSIZE;
- if( BLOCK_OFFSET(i+1)>nMax ){
- len = nMax-BLOCK_OFFSET(i);
- }
- if( len>0 ){
- if( trash ){
- sqlite3_randomness(len, p);
- }
- rc = sqlite3RealWrite(&pFile->fd, p, len);
- }
- }
- sqliteFree(p);
- }
- }
- sqliteFree(pFile->apBlk);
- pFile->nBlk = 0;
- pFile->apBlk = 0;
- pFile->nMaxWrite = 0;
-
- if( rc==SQLITE_OK ){
- rc = sqlite3RealSeek(&pFile->fd, offset);
- }
- return rc;
-}
-
-/*
-** Write the cache to disk.
-*/
-static int writeCache(OsTestFile *pFile){
- if( pFile->apBlk ){
- int c = crashRequired(pFile->zName);
- if( c ){
- OsTestFile *p;
-#ifdef TRACE_WRITECACHE
- printf("\nCrash during sync of %s\n", pFile->zName);
-#endif
- for(p=pAllFiles; p; p=p->pNext){
- writeCache2(p, 1);
- }
- exit(-1);
- }else{
- return writeCache2(pFile, 0);
- }
- }
- return SQLITE_OK;
-}
-
-/*
-** Close the file.
-*/
-int sqlite3OsClose(OsFile *id){
- if( !(*id) ) return SQLITE_OK;
- if( (*id)->fd.isOpen ){
- /* printf("CLOSE %s (%d blocks)\n", (*id)->zName, (*id)->nBlk); */
- writeCache(*id);
- sqlite3RealClose(&(*id)->fd);
- }
- closeFile(id);
- return SQLITE_OK;
-}
-
-int sqlite3OsRead(OsFile *id, void *pBuf, int amt){
- i64 offset; /* The current offset from the start of the file */
- i64 end; /* The byte just past the last byte read */
- int blk; /* Block number the read starts on */
- int i;
- u8 *zCsr;
- int rc = SQLITE_OK;
- OsTestFile *pFile = *id;
-
- offset = osTell(pFile);
- end = offset+amt;
- blk = (offset/BLOCKSIZE);
-
- zCsr = (u8 *)pBuf;
- for(i=blk; i*BLOCKSIZE<end; i++){
- int off = 0;
- int len = 0;
-
-
- if( BLOCK_OFFSET(i) < offset ){
- off = offset-BLOCK_OFFSET(i);
- }
- len = BLOCKSIZE - off;
- if( BLOCK_OFFSET(i+1) > end ){
- len = len - (BLOCK_OFFSET(i+1)-end);
- }
-
- if( i<pFile->nBlk && pFile->apBlk[i]){
- u8 *pBlk = pFile->apBlk[i];
- memcpy(zCsr, &pBlk[off], len);
- }else{
- rc = sqlite3RealSeek(&pFile->fd, BLOCK_OFFSET(i) + off);
- if( rc!=SQLITE_OK ) return rc;
- rc = sqlite3RealRead(&pFile->fd, zCsr, len);
- if( rc!=SQLITE_OK ) return rc;
- }
-
- zCsr += len;
- }
- assert( zCsr==&((u8 *)pBuf)[amt] );
-
- rc = sqlite3RealSeek(&pFile->fd, end);
- return rc;
-}
-
-int sqlite3OsWrite(OsFile *id, const void *pBuf, int amt){
- i64 offset; /* The current offset from the start of the file */
- i64 end; /* The byte just past the last byte written */
- int blk; /* Block number the write starts on */
- int i;
- const u8 *zCsr;
- int rc = SQLITE_OK;
- OsTestFile *pFile = *id;
-
- offset = osTell(pFile);
- end = offset+amt;
- blk = (offset/BLOCKSIZE);
-
- zCsr = (u8 *)pBuf;
- for(i=blk; i*BLOCKSIZE<end; i++){
- u8 *pBlk;
- int off = 0;
- int len = 0;
-
- /* Make sure the block is in the cache */
- rc = cacheBlock(pFile, i);
- if( rc!=SQLITE_OK ) return rc;
-
- /* Write into the cache */
- pBlk = pFile->apBlk[i];
- assert( pBlk );
-
- if( BLOCK_OFFSET(i) < offset ){
- off = offset-BLOCK_OFFSET(i);
- }
- len = BLOCKSIZE - off;
- if( BLOCK_OFFSET(i+1) > end ){
- len = len - (BLOCK_OFFSET(i+1)-end);
- }
- memcpy(&pBlk[off], zCsr, len);
- zCsr += len;
- }
- if( pFile->nMaxWrite<end ){
- pFile->nMaxWrite = end;
- }
- assert( zCsr==&((u8 *)pBuf)[amt] );
-
- rc = sqlite3RealSeek(&pFile->fd, end);
- return rc;
-}
-
-/*
-** Sync the file. First flush the write-cache to disk, then call the
-** real sync() function.
-*/
-int sqlite3OsSync(OsFile *id, int dataOnly){
- int rc;
- /* printf("SYNC %s (%d blocks)\n", (*id)->zName, (*id)->nBlk); */
- rc = writeCache(*id);
- if( rc!=SQLITE_OK ) return rc;
- rc = sqlite3RealSync(&(*id)->fd, dataOnly);
- return rc;
-}
-
-/*
-** Truncate the file. Set the internal OsFile.nMaxWrite variable to the new
-** file size to ensure that nothing in the write-cache past this point
-** is written to disk.
-*/
-int sqlite3OsTruncate(OsFile *id, i64 nByte){
- (*id)->nMaxWrite = nByte;
- return sqlite3RealTruncate(&(*id)->fd, nByte);
-}
-
-/*
-** Return the size of the file. If the cache contains a write that extended
-** the file, then return this size instead of the on-disk size.
-*/
-int sqlite3OsFileSize(OsFile *id, i64 *pSize){
- int rc = sqlite3RealFileSize(&(*id)->fd, pSize);
- if( rc==SQLITE_OK && pSize && *pSize<(*id)->nMaxWrite ){
- *pSize = (*id)->nMaxWrite;
- }
- return rc;
-}
-
-/*
-** The three functions used to open files. All that is required is to
-** initialise the os_test.c specific fields and then call the corresponding
-** os_unix.c function to really open the file.
-*/
-int sqlite3OsOpenReadWrite(const char *zFilename, OsFile *id, int *pReadonly){
- initFile(id, zFilename);
- return sqlite3RealOpenReadWrite(zFilename, &(*id)->fd, pReadonly);
-}
-int sqlite3OsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){
- initFile(id, zFilename);
- return sqlite3RealOpenExclusive(zFilename, &(*id)->fd, delFlag);
-}
-int sqlite3OsOpenReadOnly(const char *zFilename, OsFile *id){
- initFile(id, zFilename);
- return sqlite3RealOpenReadOnly(zFilename, &(*id)->fd);
-}
-
-/*
-** These six function calls are passed straight through to the os_unix.c
-** backend.
-*/
-int sqlite3OsSeek(OsFile *id, i64 offset){
- return sqlite3RealSeek(&(*id)->fd, offset);
-}
-int sqlite3OsCheckReservedLock(OsFile *id){
- return sqlite3RealCheckReservedLock(&(*id)->fd);
-}
-int sqlite3OsLock(OsFile *id, int locktype){
- return sqlite3RealLock(&(*id)->fd, locktype);
-}
-int sqlite3OsUnlock(OsFile *id, int locktype){
- return sqlite3RealUnlock(&(*id)->fd, locktype);
-}
-int sqlite3OsOpenDirectory(const char *zDirname, OsFile *id){
- return sqlite3RealOpenDirectory(zDirname, &(*id)->fd);
-}
-
-#endif /* OS_TEST */
+++ /dev/null
-/*
-** 2004 May 22
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-******************************************************************************
-**
-** This header file defined OS-specific features for Unix.
-*/
-#ifndef _SQLITE_OS_UNIX_H_
-#define _SQLITE_OS_UNIX_H_
-
-/*
-** Helpful hint: To get this to compile on HP/UX, add -D_INCLUDE_POSIX_SOURCE
-** to the compiler command line.
-*/
-
-/*
-** These #defines should enable >2GB file support on Posix if the
-** underlying operating system supports it. If the OS lacks
-** large file support, or if the OS is windows, these should be no-ops.
-**
-** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch
-** on the compiler command line. This is necessary if you are compiling
-** on a recent machine (ex: RedHat 7.2) but you want your code to work
-** on an older machine (ex: RedHat 6.0). If you compile on RedHat 7.2
-** without this option, LFS is enable. But LFS does not exist in the kernel
-** in RedHat 6.0, so the code won't work. Hence, for maximum binary
-** portability you should omit LFS.
-**
-** Similar is true for MacOS. LFS is only supported on MacOS 9 and later.
-*/
-#ifndef SQLITE_DISABLE_LFS
-# define _LARGE_FILE 1
-# ifndef _FILE_OFFSET_BITS
-# define _FILE_OFFSET_BITS 64
-# endif
-# define _LARGEFILE_SOURCE 1
-#endif
-
-/*
-** standard include files.
-*/
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-/*
-** Macros used to determine whether or not to use threads. The
-** SQLITE_UNIX_THREADS macro is defined if we are synchronizing for
-** Posix threads and SQLITE_W32_THREADS is defined if we are
-** synchronizing using Win32 threads.
-*/
-#if defined(THREADSAFE) && THREADSAFE
-# include <pthread.h>
-# define SQLITE_UNIX_THREADS 1
-#endif
-
-/*
-** The OsFile structure is a operating-system independing representation
-** of an open file handle. It is defined differently for each architecture.
-**
-** This is the definition for Unix.
-**
-** OsFile.locktype takes one of the values SHARED_LOCK, RESERVED_LOCK,
-** PENDING_LOCK or EXCLUSIVE_LOCK.
-*/
-typedef struct OsFile OsFile;
-struct OsFile {
- struct Pager *pPager; /* The pager that owns this OsFile. Might be 0 */
- struct openCnt *pOpen; /* Info about all open fd's on this inode */
- struct lockInfo *pLock; /* Info about locks on this inode */
- int h; /* The file descriptor */
- unsigned char locktype; /* The type of lock held on this fd */
- unsigned char isOpen; /* True if needs to be closed */
- unsigned char fullSync; /* Use F_FULLSYNC if available */
- int dirfd; /* File descriptor for the directory */
-#ifdef SQLITE_UNIX_THREADS
- pthread_t tid; /* The thread authorized to use this OsFile */
-#endif
-};
-
-/*
-** A macro to set the OsFile.fullSync flag, if it exists.
-*/
-#define SET_FULLSYNC(x,y) ((x).fullSync = (y))
-
-/*
-** Maximum number of characters in a temporary file name
-*/
-#define SQLITE_TEMPNAME_SIZE 200
-
-/*
-** Minimum interval supported by sqlite3OsSleep().
-*/
-#if defined(HAVE_USLEEP) && HAVE_USLEEP
-# define SQLITE_MIN_SLEEP_MS 1
-#else
-# define SQLITE_MIN_SLEEP_MS 1000
-#endif
-
-/*
-** Default permissions when creating a new file
-*/
-#ifndef SQLITE_DEFAULT_FILE_PERMISSIONS
-# define SQLITE_DEFAULT_FILE_PERMISSIONS 0644
-#endif
-
-
-#endif /* _SQLITE_OS_UNIX_H_ */