15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 2007 September 14 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The author disclaims copyright to this source code. In place of 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** a legal notice, here is a blessing: 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** May you do good and not evil. 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** May you find forgiveness for yourself and forgive others. 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** May you share freely, never taking more than you give. 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)************************************************************************* 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** OVERVIEW: 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This file contains some example code demonstrating how the SQLite 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** vfs feature can be used to have SQLite operate directly on an 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** embedded media, without using an intermediate file system. 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Because this is only a demo designed to run on a workstation, the 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** underlying media is simulated using a regular file-system file. The 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** size of the file is fixed when it is first created (default size 10 MB). 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** From SQLite's point of view, this space is used to store a single 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** database file and the journal file. 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Any statement journal created is stored in volatile memory obtained 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** from sqlite3_malloc(). Any attempt to create a temporary database file 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** will fail (SQLITE_IOERR). To prevent SQLite from attempting this, 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** it should be configured to store all temporary database files in 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** main memory (see pragma "temp_store" or the SQLITE_TEMP_STORE compile 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** time option). 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** ASSUMPTIONS: 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** After it has been created, the blob file is accessed using the 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** following three functions only: 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** mediaRead(); - Read a 512 byte block from the file. 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** mediaWrite(); - Write a 512 byte block to the file. 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** mediaSync(); - Tell the media hardware to sync. 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** It is assumed that these can be easily implemented by any "real" 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** media vfs driver adapting this code. 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** FILE FORMAT: 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The basic principle is that the "database file" is stored at the 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** beginning of the 10 MB blob and grows in a forward direction. The 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** "journal file" is stored at the end of the 10MB blob and grows 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** in the reverse direction. If, during a transaction, insufficient 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** space is available to expand either the journal or database file, 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** an SQLITE_FULL error is returned. The database file is never allowed 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** to consume more than 90% of the blob space. If SQLite tries to 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** create a file larger than this, SQLITE_FULL is returned. 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** No allowance is made for "wear-leveling", as is required by. 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** embedded devices in the absence of equivalent hardware features. 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The first 512 block byte of the file is reserved for storing the 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** size of the "database file". It is updated as part of the sync() 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** operation. On startup, it can only be trusted if no journal file 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** exists. If a journal-file does exist, then it stores the real size 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** of the database region. The second and subsequent blocks store the 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** actual database content. 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The size of the "journal file" is not stored persistently in the 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** file. When the system is running, the size of the journal file is 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** stored in volatile memory. When recovering from a crash, this vfs 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** reports a very large size for the journal file. The normal journal 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** header and checksum mechanisms serve to prevent SQLite from 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** processing any data that lies past the logical end of the journal. 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** When SQLite calls OsDelete() to delete the journal file, the final 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 512 bytes of the blob (the area containing the first journal header) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** are zeroed. 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** LOCKING: 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** File locking is a no-op. Only one connection may be open at any one 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** time using this demo vfs. 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sqlite3.h" 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <assert.h> 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h> 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Maximum pathname length supported by the fs backend. 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BLOCKSIZE 512 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BLOBSIZE 10485760 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Name used to identify this VFS. 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define FS_VFS_NAME "fs" 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct fs_real_file fs_real_file; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct fs_real_file { 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_file *pFile; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *zName; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nDatabase; /* Current size of database region */ 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nJournal; /* Current size of journal region */ 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nBlob; /* Total size of allocated blob */ 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nRef; /* Number of pointers to this structure */ 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fs_real_file *pNext; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fs_real_file **ppThis; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct fs_file fs_file; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct fs_file { 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_file base; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int eType; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fs_real_file *pReal; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct tmp_file tmp_file; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct tmp_file { 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_file base; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nSize; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nAlloc; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *zAlloc; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Values for fs_file.eType. */ 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DATABASE_FILE 1 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define JOURNAL_FILE 2 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Method declarations for fs_file. 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int fsClose(sqlite3_file*); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int fsRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int fsWrite(sqlite3_file*, const void*, int iAmt, sqlite3_int64 iOfst); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int fsTruncate(sqlite3_file*, sqlite3_int64 size); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int fsSync(sqlite3_file*, int flags); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int fsFileSize(sqlite3_file*, sqlite3_int64 *pSize); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int fsLock(sqlite3_file*, int); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int fsUnlock(sqlite3_file*, int); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int fsCheckReservedLock(sqlite3_file*, int *pResOut); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int fsFileControl(sqlite3_file*, int op, void *pArg); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int fsSectorSize(sqlite3_file*); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int fsDeviceCharacteristics(sqlite3_file*); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Method declarations for tmp_file. 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int tmpClose(sqlite3_file*); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int tmpRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int tmpWrite(sqlite3_file*, const void*, int iAmt, sqlite3_int64 iOfst); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int tmpTruncate(sqlite3_file*, sqlite3_int64 size); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int tmpSync(sqlite3_file*, int flags); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int tmpFileSize(sqlite3_file*, sqlite3_int64 *pSize); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int tmpLock(sqlite3_file*, int); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int tmpUnlock(sqlite3_file*, int); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int tmpCheckReservedLock(sqlite3_file*, int *pResOut); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int tmpFileControl(sqlite3_file*, int op, void *pArg); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int tmpSectorSize(sqlite3_file*); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int tmpDeviceCharacteristics(sqlite3_file*); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Method declarations for fs_vfs. 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int fsOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int fsDelete(sqlite3_vfs*, const char *zName, int syncDir); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int fsAccess(sqlite3_vfs*, const char *zName, int flags, int *); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int fsFullPathname(sqlite3_vfs*, const char *zName, int nOut,char *zOut); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void *fsDlOpen(sqlite3_vfs*, const char *zFilename); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void fsDlError(sqlite3_vfs*, int nByte, char *zErrMsg); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void (*fsDlSym(sqlite3_vfs*,void*, const char *zSymbol))(void); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void fsDlClose(sqlite3_vfs*, void*); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int fsRandomness(sqlite3_vfs*, int nByte, char *zOut); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int fsSleep(sqlite3_vfs*, int microseconds); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int fsCurrentTime(sqlite3_vfs*, double*); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct fs_vfs_t fs_vfs_t; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct fs_vfs_t { 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_vfs base; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fs_real_file *pFileList; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_vfs *pParent; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static fs_vfs_t fs_vfs = { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1, /* iVersion */ 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, /* szOsFile */ 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, /* mxPathname */ 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, /* pNext */ 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FS_VFS_NAME, /* zName */ 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, /* pAppData */ 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fsOpen, /* xOpen */ 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fsDelete, /* xDelete */ 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fsAccess, /* xAccess */ 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fsFullPathname, /* xFullPathname */ 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fsDlOpen, /* xDlOpen */ 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fsDlError, /* xDlError */ 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fsDlSym, /* xDlSym */ 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fsDlClose, /* xDlClose */ 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fsRandomness, /* xRandomness */ 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fsSleep, /* xSleep */ 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fsCurrentTime, /* xCurrentTime */ 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0 /* xCurrentTimeInt64 */ 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }, 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, /* pFileList */ 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0 /* pParent */ 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static sqlite3_io_methods fs_io_methods = { 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1, /* iVersion */ 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fsClose, /* xClose */ 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fsRead, /* xRead */ 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fsWrite, /* xWrite */ 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fsTruncate, /* xTruncate */ 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fsSync, /* xSync */ 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fsFileSize, /* xFileSize */ 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fsLock, /* xLock */ 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fsUnlock, /* xUnlock */ 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fsCheckReservedLock, /* xCheckReservedLock */ 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fsFileControl, /* xFileControl */ 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fsSectorSize, /* xSectorSize */ 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fsDeviceCharacteristics, /* xDeviceCharacteristics */ 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, /* xShmMap */ 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, /* xShmLock */ 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, /* xShmBarrier */ 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0 /* xShmUnmap */ 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static sqlite3_io_methods tmp_io_methods = { 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1, /* iVersion */ 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmpClose, /* xClose */ 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmpRead, /* xRead */ 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmpWrite, /* xWrite */ 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmpTruncate, /* xTruncate */ 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmpSync, /* xSync */ 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmpFileSize, /* xFileSize */ 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmpLock, /* xLock */ 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmpUnlock, /* xUnlock */ 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmpCheckReservedLock, /* xCheckReservedLock */ 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmpFileControl, /* xFileControl */ 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmpSectorSize, /* xSectorSize */ 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmpDeviceCharacteristics, /* xDeviceCharacteristics */ 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, /* xShmMap */ 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, /* xShmLock */ 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, /* xShmBarrier */ 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0 /* xShmUnmap */ 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Useful macros used in several places */ 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MIN(x,y) ((x)<(y)?(x):(y)) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAX(x,y) ((x)>(y)?(x):(y)) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Close a tmp-file. 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int tmpClose(sqlite3_file *pFile){ 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp_file *pTmp = (tmp_file *)pFile; 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_free(pTmp->zAlloc); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Read data from a tmp-file. 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int tmpRead( 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_file *pFile, 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *zBuf, 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iAmt, 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite_int64 iOfst 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp_file *pTmp = (tmp_file *)pFile; 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (iAmt+iOfst)>pTmp->nSize ){ 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_IOERR_SHORT_READ; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(zBuf, &pTmp->zAlloc[iOfst], iAmt); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Write data to a tmp-file. 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int tmpWrite( 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_file *pFile, 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *zBuf, 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iAmt, 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite_int64 iOfst 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp_file *pTmp = (tmp_file *)pFile; 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (iAmt+iOfst)>pTmp->nAlloc ){ 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nNew = 2*(iAmt+iOfst+pTmp->nAlloc); 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *zNew = sqlite3_realloc(pTmp->zAlloc, nNew); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !zNew ){ 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_NOMEM; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTmp->zAlloc = zNew; 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTmp->nAlloc = nNew; 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(&pTmp->zAlloc[iOfst], zBuf, iAmt); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTmp->nSize = MAX(pTmp->nSize, iOfst+iAmt); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Truncate a tmp-file. 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int tmpTruncate(sqlite3_file *pFile, sqlite_int64 size){ 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp_file *pTmp = (tmp_file *)pFile; 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pTmp->nSize = MIN(pTmp->nSize, size); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Sync a tmp-file. 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int tmpSync(sqlite3_file *pFile, int flags){ 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return the current file-size of a tmp-file. 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int tmpFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp_file *pTmp = (tmp_file *)pFile; 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *pSize = pTmp->nSize; 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Lock a tmp-file. 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int tmpLock(sqlite3_file *pFile, int eLock){ 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Unlock a tmp-file. 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int tmpUnlock(sqlite3_file *pFile, int eLock){ 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Check if another file-handle holds a RESERVED lock on a tmp-file. 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int tmpCheckReservedLock(sqlite3_file *pFile, int *pResOut){ 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *pResOut = 0; 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** File control method. For custom operations on a tmp-file. 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int tmpFileControl(sqlite3_file *pFile, int op, void *pArg){ 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return the sector-size in bytes for a tmp-file. 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int tmpSectorSize(sqlite3_file *pFile){ 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return the device characteristic flags supported by a tmp-file. 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int tmpDeviceCharacteristics(sqlite3_file *pFile){ 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Close an fs-file. 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int fsClose(sqlite3_file *pFile){ 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc = SQLITE_OK; 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fs_file *p = (fs_file *)pFile; 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fs_real_file *pReal = p->pReal; 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Decrement the real_file ref-count. */ 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pReal->nRef--; 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(pReal->nRef>=0); 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* When the ref-count reaches 0, destroy the structure */ 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pReal->nRef==0 ){ 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *pReal->ppThis = pReal->pNext; 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pReal->pNext ){ 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pReal->pNext->ppThis = pReal->ppThis; 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = pReal->pFile->pMethods->xClose(pReal->pFile); 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_free(pReal); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Read data from an fs-file. 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int fsRead( 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_file *pFile, 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *zBuf, 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iAmt, 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite_int64 iOfst 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc = SQLITE_OK; 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fs_file *p = (fs_file *)pFile; 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fs_real_file *pReal = p->pReal; 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_file *pF = pReal->pFile; 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (p->eType==DATABASE_FILE && (iAmt+iOfst)>pReal->nDatabase) 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) || (p->eType==JOURNAL_FILE && (iAmt+iOfst)>pReal->nJournal) 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ){ 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = SQLITE_IOERR_SHORT_READ; 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else if( p->eType==DATABASE_FILE ){ 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = pF->pMethods->xRead(pF, zBuf, iAmt, iOfst+BLOCKSIZE); 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Journal file. */ 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iRem = iAmt; 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iBuf = 0; 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ii = iOfst; 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( iRem>0 && rc==SQLITE_OK ){ 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iRealOff = pReal->nBlob - BLOCKSIZE*((ii/BLOCKSIZE)+1) + ii%BLOCKSIZE; 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iRealAmt = MIN(iRem, BLOCKSIZE - (iRealOff%BLOCKSIZE)); 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = pF->pMethods->xRead(pF, &((char *)zBuf)[iBuf], iRealAmt, iRealOff); 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ii += iRealAmt; 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iBuf += iRealAmt; 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iRem -= iRealAmt; 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Write data to an fs-file. 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int fsWrite( 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_file *pFile, 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *zBuf, 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iAmt, 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite_int64 iOfst 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc = SQLITE_OK; 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fs_file *p = (fs_file *)pFile; 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fs_real_file *pReal = p->pReal; 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_file *pF = pReal->pFile; 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p->eType==DATABASE_FILE ){ 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (iAmt+iOfst+BLOCKSIZE)>(pReal->nBlob-pReal->nJournal) ){ 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = SQLITE_FULL; 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = pF->pMethods->xWrite(pF, zBuf, iAmt, iOfst+BLOCKSIZE); 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc==SQLITE_OK ){ 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pReal->nDatabase = MAX(pReal->nDatabase, iAmt+iOfst); 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Journal file. */ 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iRem = iAmt; 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iBuf = 0; 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ii = iOfst; 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( iRem>0 && rc==SQLITE_OK ){ 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iRealOff = pReal->nBlob - BLOCKSIZE*((ii/BLOCKSIZE)+1) + ii%BLOCKSIZE; 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iRealAmt = MIN(iRem, BLOCKSIZE - (iRealOff%BLOCKSIZE)); 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( iRealOff<(pReal->nDatabase+BLOCKSIZE) ){ 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = SQLITE_FULL; 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = pF->pMethods->xWrite(pF, &((char *)zBuf)[iBuf], iRealAmt,iRealOff); 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ii += iRealAmt; 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iBuf += iRealAmt; 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iRem -= iRealAmt; 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc==SQLITE_OK ){ 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pReal->nJournal = MAX(pReal->nJournal, iAmt+iOfst); 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Truncate an fs-file. 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int fsTruncate(sqlite3_file *pFile, sqlite_int64 size){ 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fs_file *p = (fs_file *)pFile; 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fs_real_file *pReal = p->pReal; 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p->eType==DATABASE_FILE ){ 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pReal->nDatabase = MIN(pReal->nDatabase, size); 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pReal->nJournal = MIN(pReal->nJournal, size); 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Sync an fs-file. 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int fsSync(sqlite3_file *pFile, int flags){ 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fs_file *p = (fs_file *)pFile; 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fs_real_file *pReal = p->pReal; 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_file *pRealFile = pReal->pFile; 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc = SQLITE_OK; 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p->eType==DATABASE_FILE ){ 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char zSize[4]; 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zSize[0] = (pReal->nDatabase&0xFF000000)>>24; 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zSize[1] = (pReal->nDatabase&0x00FF0000)>>16; 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zSize[2] = (pReal->nDatabase&0x0000FF00)>>8; 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zSize[3] = (pReal->nDatabase&0x000000FF); 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = pRealFile->pMethods->xWrite(pRealFile, zSize, 4, 0); 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc==SQLITE_OK ){ 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = pRealFile->pMethods->xSync(pRealFile, flags&(~SQLITE_SYNC_DATAONLY)); 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return the current file-size of an fs-file. 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int fsFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fs_file *p = (fs_file *)pFile; 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fs_real_file *pReal = p->pReal; 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p->eType==DATABASE_FILE ){ 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *pSize = pReal->nDatabase; 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *pSize = pReal->nJournal; 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Lock an fs-file. 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int fsLock(sqlite3_file *pFile, int eLock){ 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Unlock an fs-file. 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int fsUnlock(sqlite3_file *pFile, int eLock){ 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Check if another file-handle holds a RESERVED lock on an fs-file. 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int fsCheckReservedLock(sqlite3_file *pFile, int *pResOut){ 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *pResOut = 0; 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** File control method. For custom operations on an fs-file. 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int fsFileControl(sqlite3_file *pFile, int op, void *pArg){ 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return the sector-size in bytes for an fs-file. 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int fsSectorSize(sqlite3_file *pFile){ 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return BLOCKSIZE; 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return the device characteristic flags supported by an fs-file. 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int fsDeviceCharacteristics(sqlite3_file *pFile){ 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Open an fs file handle. 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int fsOpen( 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_vfs *pVfs, 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *zName, 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_file *pFile, 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int flags, 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int *pOutFlags 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fs_vfs_t *pFsVfs = (fs_vfs_t *)pVfs; 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fs_file *p = (fs_file *)pFile; 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fs_real_file *pReal = 0; 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int eType; 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nName; 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc = SQLITE_OK; 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( 0==(flags&(SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_MAIN_JOURNAL)) ){ 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp_file *p = (tmp_file *)pFile; 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(p, 0, sizeof(*p)); 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->base.pMethods = &tmp_io_methods; 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) eType = ((flags&(SQLITE_OPEN_MAIN_DB))?DATABASE_FILE:JOURNAL_FILE); 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->base.pMethods = &fs_io_methods; 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->eType = eType; 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(strlen("-journal")==8); 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nName = strlen(zName)-((eType==JOURNAL_FILE)?8:0); 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pReal=pFsVfs->pFileList; 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(; pReal && strncmp(pReal->zName, zName, nName); pReal=pReal->pNext); 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !pReal ){ 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int real_flags = (flags&~(SQLITE_OPEN_MAIN_DB))|SQLITE_OPEN_TEMP_DB; 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_int64 size; 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_file *pRealFile; 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_vfs *pParent = pFsVfs->pParent; 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(eType==DATABASE_FILE); 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pReal = (fs_real_file *)sqlite3_malloc(sizeof(*pReal)+pParent->szOsFile); 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !pReal ){ 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = SQLITE_NOMEM; 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto open_out; 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(pReal, 0, sizeof(*pReal)+pParent->szOsFile); 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pReal->zName = zName; 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pReal->pFile = (sqlite3_file *)(&pReal[1]); 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = pParent->xOpen(pParent, zName, pReal->pFile, real_flags, pOutFlags); 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc!=SQLITE_OK ){ 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto open_out; 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pRealFile = pReal->pFile; 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = pRealFile->pMethods->xFileSize(pRealFile, &size); 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc!=SQLITE_OK ){ 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto open_out; 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( size==0 ){ 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = pRealFile->pMethods->xWrite(pRealFile, "\0", 1, BLOBSIZE-1); 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pReal->nBlob = BLOBSIZE; 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char zS[4]; 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pReal->nBlob = size; 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = pRealFile->pMethods->xRead(pRealFile, zS, 4, 0); 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pReal->nDatabase = (zS[0]<<24)+(zS[1]<<16)+(zS[2]<<8)+zS[3]; 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc==SQLITE_OK ){ 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = pRealFile->pMethods->xRead(pRealFile, zS, 4, pReal->nBlob-4); 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( zS[0] || zS[1] || zS[2] || zS[3] ){ 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pReal->nJournal = pReal->nBlob; 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc==SQLITE_OK ){ 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pReal->pNext = pFsVfs->pFileList; 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pReal->pNext ){ 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pReal->pNext->ppThis = &pReal->pNext; 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pReal->ppThis = &pFsVfs->pFileList; 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pFsVfs->pFileList = pReal; 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)open_out: 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pReal ){ 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc==SQLITE_OK ){ 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->pReal = pReal; 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pReal->nRef++; 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pReal->pFile->pMethods ){ 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pReal->pFile->pMethods->xClose(pReal->pFile); 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_free(pReal); 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Delete the file located at zPath. If the dirSync argument is true, 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** ensure the file-system modifications are synced to disk before 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** returning. 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int fsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc = SQLITE_OK; 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fs_vfs_t *pFsVfs = (fs_vfs_t *)pVfs; 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fs_real_file *pReal; 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_file *pF; 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nName = strlen(zPath) - 8; 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(strlen("-journal")==8); 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(strcmp("-journal", &zPath[nName])==0); 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pReal = pFsVfs->pFileList; 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(; pReal && strncmp(pReal->zName, zPath, nName); pReal=pReal->pNext); 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pReal ){ 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pF = pReal->pFile; 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = pF->pMethods->xWrite(pF, "\0\0\0\0", 4, pReal->nBlob-BLOCKSIZE); 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc==SQLITE_OK ){ 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pReal->nJournal = 0; 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Test for access permissions. Return true if the requested permission 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** is available, or false otherwise. 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int fsAccess( 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_vfs *pVfs, 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *zPath, 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int flags, 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int *pResOut 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fs_vfs_t *pFsVfs = (fs_vfs_t *)pVfs; 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fs_real_file *pReal; 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int isJournal = 0; 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nName = strlen(zPath); 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( flags!=SQLITE_ACCESS_EXISTS ){ 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_vfs *pParent = ((fs_vfs_t *)pVfs)->pParent; 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pParent->xAccess(pParent, zPath, flags, pResOut); 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(strlen("-journal")==8); 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( nName>8 && strcmp("-journal", &zPath[nName-8])==0 ){ 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nName -= 8; 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) isJournal = 1; 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pReal = pFsVfs->pFileList; 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(; pReal && strncmp(pReal->zName, zPath, nName); pReal=pReal->pNext); 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *pResOut = (pReal && (!isJournal || pReal->nJournal>0)); 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Populate buffer zOut with the full canonical pathname corresponding 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** to the pathname in zPath. zOut is guaranteed to point to a buffer 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** of at least (FS_MAX_PATHNAME+1) bytes. 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int fsFullPathname( 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_vfs *pVfs, /* Pointer to vfs object */ 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *zPath, /* Possibly relative input path */ 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nOut, /* Size of output buffer in bytes */ 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *zOut /* Output buffer */ 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_vfs *pParent = ((fs_vfs_t *)pVfs)->pParent; 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pParent->xFullPathname(pParent, zPath, nOut, zOut); 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Open the dynamic library located at zPath and return a handle. 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void *fsDlOpen(sqlite3_vfs *pVfs, const char *zPath){ 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_vfs *pParent = ((fs_vfs_t *)pVfs)->pParent; 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pParent->xDlOpen(pParent, zPath); 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Populate the buffer zErrMsg (size nByte bytes) with a human readable 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** utf-8 string describing the most recent error encountered associated 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** with dynamic libraries. 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void fsDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){ 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_vfs *pParent = ((fs_vfs_t *)pVfs)->pParent; 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pParent->xDlError(pParent, nByte, zErrMsg); 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return a pointer to the symbol zSymbol in the dynamic library pHandle. 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void (*fsDlSym(sqlite3_vfs *pVfs, void *pH, const char *zSym))(void){ 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_vfs *pParent = ((fs_vfs_t *)pVfs)->pParent; 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pParent->xDlSym(pParent, pH, zSym); 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Close the dynamic library handle pHandle. 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void fsDlClose(sqlite3_vfs *pVfs, void *pHandle){ 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_vfs *pParent = ((fs_vfs_t *)pVfs)->pParent; 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pParent->xDlClose(pParent, pHandle); 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Populate the buffer pointed to by zBufOut with nByte bytes of 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** random data. 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int fsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_vfs *pParent = ((fs_vfs_t *)pVfs)->pParent; 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pParent->xRandomness(pParent, nByte, zBufOut); 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Sleep for nMicro microseconds. Return the number of microseconds 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** actually slept. 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int fsSleep(sqlite3_vfs *pVfs, int nMicro){ 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_vfs *pParent = ((fs_vfs_t *)pVfs)->pParent; 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pParent->xSleep(pParent, nMicro); 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return the current time as a Julian Day number in *pTimeOut. 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int fsCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){ 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_vfs *pParent = ((fs_vfs_t *)pVfs)->pParent; 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pParent->xCurrentTime(pParent, pTimeOut); 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This procedure registers the fs vfs with SQLite. If the argument is 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** true, the fs vfs becomes the new default vfs. It is the only publicly 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** available function in this file. 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int fs_register(void){ 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( fs_vfs.pParent ) return SQLITE_OK; 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fs_vfs.pParent = sqlite3_vfs_find(0); 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fs_vfs.base.mxPathname = fs_vfs.pParent->mxPathname; 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fs_vfs.base.szOsFile = MAX(sizeof(tmp_file), sizeof(fs_file)); 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sqlite3_vfs_register(&fs_vfs.base, 0); 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_TEST 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int SqlitetestOnefile_Init() {return fs_register();} 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 831