1bf260978Sdanielk1977 /*
2bf260978Sdanielk1977 ** 2008 Jan 22
3bf260978Sdanielk1977 **
4bf260978Sdanielk1977 ** The author disclaims copyright to this source code. In place of
5bf260978Sdanielk1977 ** a legal notice, here is a blessing:
6bf260978Sdanielk1977 **
7bf260978Sdanielk1977 ** May you do good and not evil.
8bf260978Sdanielk1977 ** May you find forgiveness for yourself and forgive others.
9bf260978Sdanielk1977 ** May you share freely, never taking more than you give.
10bf260978Sdanielk1977 **
11bf260978Sdanielk1977 ******************************************************************************
12bf260978Sdanielk1977 **
13bf260978Sdanielk1977 ** This file contains code that modified the OS layer in order to simulate
14bf260978Sdanielk1977 ** different device types (by overriding the return values of the
15bf260978Sdanielk1977 ** xDeviceCharacteristics() and xSectorSize() methods).
16bf260978Sdanielk1977 */
17bf260978Sdanielk1977 #if SQLITE_TEST /* This file is used for testing only */
18bf260978Sdanielk1977
19fb80d20aSmlcreech #include "sqlite3.h"
20bf260978Sdanielk1977 #include "sqliteInt.h"
21bf260978Sdanielk1977
22bf260978Sdanielk1977 /*
23bf260978Sdanielk1977 ** Maximum pathname length supported by the devsym backend.
24bf260978Sdanielk1977 */
25bf260978Sdanielk1977 #define DEVSYM_MAX_PATHNAME 512
26bf260978Sdanielk1977
27bf260978Sdanielk1977 /*
28bf260978Sdanielk1977 ** Name used to identify this VFS.
29bf260978Sdanielk1977 */
30bf260978Sdanielk1977 #define DEVSYM_VFS_NAME "devsym"
3133447e77Sdan #define WRITECRASH_NAME "writecrash"
32bf260978Sdanielk1977
33bf260978Sdanielk1977 typedef struct devsym_file devsym_file;
34bf260978Sdanielk1977 struct devsym_file {
35bf260978Sdanielk1977 sqlite3_file base;
36bf260978Sdanielk1977 sqlite3_file *pReal;
37bf260978Sdanielk1977 };
38bf260978Sdanielk1977
39bf260978Sdanielk1977 /*
40bf260978Sdanielk1977 ** Method declarations for devsym_file.
41bf260978Sdanielk1977 */
42bf260978Sdanielk1977 static int devsymClose(sqlite3_file*);
43bf260978Sdanielk1977 static int devsymRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
44bf260978Sdanielk1977 static int devsymWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst);
45bf260978Sdanielk1977 static int devsymTruncate(sqlite3_file*, sqlite3_int64 size);
46bf260978Sdanielk1977 static int devsymSync(sqlite3_file*, int flags);
47bf260978Sdanielk1977 static int devsymFileSize(sqlite3_file*, sqlite3_int64 *pSize);
48bf260978Sdanielk1977 static int devsymLock(sqlite3_file*, int);
49bf260978Sdanielk1977 static int devsymUnlock(sqlite3_file*, int);
50861f7456Sdanielk1977 static int devsymCheckReservedLock(sqlite3_file*, int *);
51bf260978Sdanielk1977 static int devsymFileControl(sqlite3_file*, int op, void *pArg);
52bf260978Sdanielk1977 static int devsymSectorSize(sqlite3_file*);
53bf260978Sdanielk1977 static int devsymDeviceCharacteristics(sqlite3_file*);
5473b64e4dSdrh static int devsymShmLock(sqlite3_file*,int,int,int);
556b017cc6Sdrh static int devsymShmMap(sqlite3_file*,int,int,int, void volatile **);
56286a2884Sdrh static void devsymShmBarrier(sqlite3_file*);
57e11fedc5Sdrh static int devsymShmUnmap(sqlite3_file*,int);
58bf260978Sdanielk1977
59bf260978Sdanielk1977 /*
60bf260978Sdanielk1977 ** Method declarations for devsym_vfs.
61bf260978Sdanielk1977 */
62bf260978Sdanielk1977 static int devsymOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *);
63bf260978Sdanielk1977 static int devsymDelete(sqlite3_vfs*, const char *zName, int syncDir);
64861f7456Sdanielk1977 static int devsymAccess(sqlite3_vfs*, const char *zName, int flags, int *);
65bf260978Sdanielk1977 static int devsymFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut);
6675998ab3Sshane #ifndef SQLITE_OMIT_LOAD_EXTENSION
67bf260978Sdanielk1977 static void *devsymDlOpen(sqlite3_vfs*, const char *zFilename);
68bf260978Sdanielk1977 static void devsymDlError(sqlite3_vfs*, int nByte, char *zErrMsg);
69ec1724e8Sdrh static void (*devsymDlSym(sqlite3_vfs*,void*, const char *zSymbol))(void);
70bf260978Sdanielk1977 static void devsymDlClose(sqlite3_vfs*, void*);
7175998ab3Sshane #endif /* SQLITE_OMIT_LOAD_EXTENSION */
72bf260978Sdanielk1977 static int devsymRandomness(sqlite3_vfs*, int nByte, char *zOut);
73bf260978Sdanielk1977 static int devsymSleep(sqlite3_vfs*, int microseconds);
74bf260978Sdanielk1977 static int devsymCurrentTime(sqlite3_vfs*, double*);
75bf260978Sdanielk1977
76bf260978Sdanielk1977 struct DevsymGlobal {
77bf260978Sdanielk1977 sqlite3_vfs *pVfs;
78bf260978Sdanielk1977 int iDeviceChar;
79bf260978Sdanielk1977 int iSectorSize;
8033447e77Sdan int nWriteCrash;
81bf260978Sdanielk1977 };
8233447e77Sdan struct DevsymGlobal g = {0, 0, 512, 0};
83bf260978Sdanielk1977
84bf260978Sdanielk1977 /*
85bf260978Sdanielk1977 ** Close an devsym-file.
86bf260978Sdanielk1977 */
devsymClose(sqlite3_file * pFile)87bf260978Sdanielk1977 static int devsymClose(sqlite3_file *pFile){
88bf260978Sdanielk1977 devsym_file *p = (devsym_file *)pFile;
898f2ce914Sdrh sqlite3OsClose(p->pReal);
908f2ce914Sdrh return SQLITE_OK;
91bf260978Sdanielk1977 }
92bf260978Sdanielk1977
93bf260978Sdanielk1977 /*
94bf260978Sdanielk1977 ** Read data from an devsym-file.
95bf260978Sdanielk1977 */
devsymRead(sqlite3_file * pFile,void * zBuf,int iAmt,sqlite_int64 iOfst)96bf260978Sdanielk1977 static int devsymRead(
97bf260978Sdanielk1977 sqlite3_file *pFile,
98bf260978Sdanielk1977 void *zBuf,
99bf260978Sdanielk1977 int iAmt,
100bf260978Sdanielk1977 sqlite_int64 iOfst
101bf260978Sdanielk1977 ){
102bf260978Sdanielk1977 devsym_file *p = (devsym_file *)pFile;
103bf260978Sdanielk1977 return sqlite3OsRead(p->pReal, zBuf, iAmt, iOfst);
104bf260978Sdanielk1977 }
105bf260978Sdanielk1977
106bf260978Sdanielk1977 /*
107bf260978Sdanielk1977 ** Write data to an devsym-file.
108bf260978Sdanielk1977 */
devsymWrite(sqlite3_file * pFile,const void * zBuf,int iAmt,sqlite_int64 iOfst)109bf260978Sdanielk1977 static int devsymWrite(
110bf260978Sdanielk1977 sqlite3_file *pFile,
111bf260978Sdanielk1977 const void *zBuf,
112bf260978Sdanielk1977 int iAmt,
113bf260978Sdanielk1977 sqlite_int64 iOfst
114bf260978Sdanielk1977 ){
115bf260978Sdanielk1977 devsym_file *p = (devsym_file *)pFile;
116bf260978Sdanielk1977 return sqlite3OsWrite(p->pReal, zBuf, iAmt, iOfst);
117bf260978Sdanielk1977 }
118bf260978Sdanielk1977
119bf260978Sdanielk1977 /*
120bf260978Sdanielk1977 ** Truncate an devsym-file.
121bf260978Sdanielk1977 */
devsymTruncate(sqlite3_file * pFile,sqlite_int64 size)122bf260978Sdanielk1977 static int devsymTruncate(sqlite3_file *pFile, sqlite_int64 size){
123bf260978Sdanielk1977 devsym_file *p = (devsym_file *)pFile;
124bf260978Sdanielk1977 return sqlite3OsTruncate(p->pReal, size);
125bf260978Sdanielk1977 }
126bf260978Sdanielk1977
127bf260978Sdanielk1977 /*
128bf260978Sdanielk1977 ** Sync an devsym-file.
129bf260978Sdanielk1977 */
devsymSync(sqlite3_file * pFile,int flags)130bf260978Sdanielk1977 static int devsymSync(sqlite3_file *pFile, int flags){
131bf260978Sdanielk1977 devsym_file *p = (devsym_file *)pFile;
132bf260978Sdanielk1977 return sqlite3OsSync(p->pReal, flags);
133bf260978Sdanielk1977 }
134bf260978Sdanielk1977
135bf260978Sdanielk1977 /*
136bf260978Sdanielk1977 ** Return the current file-size of an devsym-file.
137bf260978Sdanielk1977 */
devsymFileSize(sqlite3_file * pFile,sqlite_int64 * pSize)138bf260978Sdanielk1977 static int devsymFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
139bf260978Sdanielk1977 devsym_file *p = (devsym_file *)pFile;
140bf260978Sdanielk1977 return sqlite3OsFileSize(p->pReal, pSize);
141bf260978Sdanielk1977 }
142bf260978Sdanielk1977
143bf260978Sdanielk1977 /*
144bf260978Sdanielk1977 ** Lock an devsym-file.
145bf260978Sdanielk1977 */
devsymLock(sqlite3_file * pFile,int eLock)146bf260978Sdanielk1977 static int devsymLock(sqlite3_file *pFile, int eLock){
147bf260978Sdanielk1977 devsym_file *p = (devsym_file *)pFile;
148bf260978Sdanielk1977 return sqlite3OsLock(p->pReal, eLock);
149bf260978Sdanielk1977 }
150bf260978Sdanielk1977
151bf260978Sdanielk1977 /*
152bf260978Sdanielk1977 ** Unlock an devsym-file.
153bf260978Sdanielk1977 */
devsymUnlock(sqlite3_file * pFile,int eLock)154bf260978Sdanielk1977 static int devsymUnlock(sqlite3_file *pFile, int eLock){
155bf260978Sdanielk1977 devsym_file *p = (devsym_file *)pFile;
156bf260978Sdanielk1977 return sqlite3OsUnlock(p->pReal, eLock);
157bf260978Sdanielk1977 }
158bf260978Sdanielk1977
159bf260978Sdanielk1977 /*
160bf260978Sdanielk1977 ** Check if another file-handle holds a RESERVED lock on an devsym-file.
161bf260978Sdanielk1977 */
devsymCheckReservedLock(sqlite3_file * pFile,int * pResOut)162861f7456Sdanielk1977 static int devsymCheckReservedLock(sqlite3_file *pFile, int *pResOut){
163bf260978Sdanielk1977 devsym_file *p = (devsym_file *)pFile;
164861f7456Sdanielk1977 return sqlite3OsCheckReservedLock(p->pReal, pResOut);
165bf260978Sdanielk1977 }
166bf260978Sdanielk1977
167bf260978Sdanielk1977 /*
168bf260978Sdanielk1977 ** File control method. For custom operations on an devsym-file.
169bf260978Sdanielk1977 */
devsymFileControl(sqlite3_file * pFile,int op,void * pArg)170bf260978Sdanielk1977 static int devsymFileControl(sqlite3_file *pFile, int op, void *pArg){
171bf260978Sdanielk1977 devsym_file *p = (devsym_file *)pFile;
172bf260978Sdanielk1977 return sqlite3OsFileControl(p->pReal, op, pArg);
173bf260978Sdanielk1977 }
174bf260978Sdanielk1977
175bf260978Sdanielk1977 /*
176bf260978Sdanielk1977 ** Return the sector-size in bytes for an devsym-file.
177bf260978Sdanielk1977 */
devsymSectorSize(sqlite3_file * pFile)178bf260978Sdanielk1977 static int devsymSectorSize(sqlite3_file *pFile){
179bf260978Sdanielk1977 return g.iSectorSize;
180bf260978Sdanielk1977 }
181bf260978Sdanielk1977
182bf260978Sdanielk1977 /*
183bf260978Sdanielk1977 ** Return the device characteristic flags supported by an devsym-file.
184bf260978Sdanielk1977 */
devsymDeviceCharacteristics(sqlite3_file * pFile)185bf260978Sdanielk1977 static int devsymDeviceCharacteristics(sqlite3_file *pFile){
186bf260978Sdanielk1977 return g.iDeviceChar;
187bf260978Sdanielk1977 }
188bf260978Sdanielk1977
189bf260978Sdanielk1977 /*
190365e2d25Sdrh ** Shared-memory methods are all pass-thrus.
191365e2d25Sdrh */
devsymShmLock(sqlite3_file * pFile,int ofst,int n,int flags)19273b64e4dSdrh static int devsymShmLock(sqlite3_file *pFile, int ofst, int n, int flags){
193365e2d25Sdrh devsym_file *p = (devsym_file *)pFile;
194*7093a3beSdan return p->pReal->pMethods->xShmLock(p->pReal, ofst, n, flags);
195365e2d25Sdrh }
devsymShmMap(sqlite3_file * pFile,int iRegion,int szRegion,int isWrite,void volatile ** pp)19618801915Sdan static int devsymShmMap(
19713a3cb82Sdan sqlite3_file *pFile,
19818801915Sdan int iRegion,
19918801915Sdan int szRegion,
20013a3cb82Sdan int isWrite,
20113a3cb82Sdan void volatile **pp
20213a3cb82Sdan ){
20313a3cb82Sdan devsym_file *p = (devsym_file *)pFile;
204*7093a3beSdan return p->pReal->pMethods->xShmMap(p->pReal, iRegion, szRegion, isWrite, pp);
20513a3cb82Sdan }
devsymShmBarrier(sqlite3_file * pFile)2066b017cc6Sdrh static void devsymShmBarrier(sqlite3_file *pFile){
2076b017cc6Sdrh devsym_file *p = (devsym_file *)pFile;
208*7093a3beSdan p->pReal->pMethods->xShmBarrier(p->pReal);
2096b017cc6Sdrh }
devsymShmUnmap(sqlite3_file * pFile,int delFlag)210e11fedc5Sdrh static int devsymShmUnmap(sqlite3_file *pFile, int delFlag){
2116b017cc6Sdrh devsym_file *p = (devsym_file *)pFile;
212*7093a3beSdan return p->pReal->pMethods->xShmUnmap(p->pReal, delFlag);
2136b017cc6Sdrh }
214365e2d25Sdrh
215365e2d25Sdrh
216365e2d25Sdrh
217365e2d25Sdrh /*
218bf260978Sdanielk1977 ** Open an devsym file handle.
219bf260978Sdanielk1977 */
devsymOpen(sqlite3_vfs * pVfs,const char * zName,sqlite3_file * pFile,int flags,int * pOutFlags)220bf260978Sdanielk1977 static int devsymOpen(
221bf260978Sdanielk1977 sqlite3_vfs *pVfs,
222bf260978Sdanielk1977 const char *zName,
223bf260978Sdanielk1977 sqlite3_file *pFile,
224bf260978Sdanielk1977 int flags,
225bf260978Sdanielk1977 int *pOutFlags
226bf260978Sdanielk1977 ){
22733447e77Sdan static sqlite3_io_methods devsym_io_methods = {
22833447e77Sdan 2, /* iVersion */
22933447e77Sdan devsymClose, /* xClose */
23033447e77Sdan devsymRead, /* xRead */
23133447e77Sdan devsymWrite, /* xWrite */
23233447e77Sdan devsymTruncate, /* xTruncate */
23333447e77Sdan devsymSync, /* xSync */
23433447e77Sdan devsymFileSize, /* xFileSize */
23533447e77Sdan devsymLock, /* xLock */
23633447e77Sdan devsymUnlock, /* xUnlock */
23733447e77Sdan devsymCheckReservedLock, /* xCheckReservedLock */
23833447e77Sdan devsymFileControl, /* xFileControl */
23933447e77Sdan devsymSectorSize, /* xSectorSize */
24033447e77Sdan devsymDeviceCharacteristics, /* xDeviceCharacteristics */
24133447e77Sdan devsymShmMap, /* xShmMap */
24233447e77Sdan devsymShmLock, /* xShmLock */
24333447e77Sdan devsymShmBarrier, /* xShmBarrier */
24433447e77Sdan devsymShmUnmap /* xShmUnmap */
24533447e77Sdan };
24633447e77Sdan
247755339ecSdanielk1977 int rc;
248bf260978Sdanielk1977 devsym_file *p = (devsym_file *)pFile;
249bf260978Sdanielk1977 p->pReal = (sqlite3_file *)&p[1];
250755339ecSdanielk1977 rc = sqlite3OsOpen(g.pVfs, zName, p->pReal, flags, pOutFlags);
251755339ecSdanielk1977 if( p->pReal->pMethods ){
252755339ecSdanielk1977 pFile->pMethods = &devsym_io_methods;
253755339ecSdanielk1977 }
254755339ecSdanielk1977 return rc;
255bf260978Sdanielk1977 }
256bf260978Sdanielk1977
257bf260978Sdanielk1977 /*
258bf260978Sdanielk1977 ** Delete the file located at zPath. If the dirSync argument is true,
259bf260978Sdanielk1977 ** ensure the file-system modifications are synced to disk before
260bf260978Sdanielk1977 ** returning.
261bf260978Sdanielk1977 */
devsymDelete(sqlite3_vfs * pVfs,const char * zPath,int dirSync)262bf260978Sdanielk1977 static int devsymDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
263bf260978Sdanielk1977 return sqlite3OsDelete(g.pVfs, zPath, dirSync);
264bf260978Sdanielk1977 }
265bf260978Sdanielk1977
266bf260978Sdanielk1977 /*
267bf260978Sdanielk1977 ** Test for access permissions. Return true if the requested permission
268bf260978Sdanielk1977 ** is available, or false otherwise.
269bf260978Sdanielk1977 */
devsymAccess(sqlite3_vfs * pVfs,const char * zPath,int flags,int * pResOut)270861f7456Sdanielk1977 static int devsymAccess(
271861f7456Sdanielk1977 sqlite3_vfs *pVfs,
272861f7456Sdanielk1977 const char *zPath,
273861f7456Sdanielk1977 int flags,
274861f7456Sdanielk1977 int *pResOut
275861f7456Sdanielk1977 ){
276861f7456Sdanielk1977 return sqlite3OsAccess(g.pVfs, zPath, flags, pResOut);
277bf260978Sdanielk1977 }
278bf260978Sdanielk1977
279bf260978Sdanielk1977 /*
280bf260978Sdanielk1977 ** Populate buffer zOut with the full canonical pathname corresponding
281bf260978Sdanielk1977 ** to the pathname in zPath. zOut is guaranteed to point to a buffer
282bf260978Sdanielk1977 ** of at least (DEVSYM_MAX_PATHNAME+1) bytes.
283bf260978Sdanielk1977 */
devsymFullPathname(sqlite3_vfs * pVfs,const char * zPath,int nOut,char * zOut)284bf260978Sdanielk1977 static int devsymFullPathname(
285bf260978Sdanielk1977 sqlite3_vfs *pVfs,
286bf260978Sdanielk1977 const char *zPath,
287bf260978Sdanielk1977 int nOut,
288bf260978Sdanielk1977 char *zOut
289bf260978Sdanielk1977 ){
290bf260978Sdanielk1977 return sqlite3OsFullPathname(g.pVfs, zPath, nOut, zOut);
291bf260978Sdanielk1977 }
292bf260978Sdanielk1977
29375998ab3Sshane #ifndef SQLITE_OMIT_LOAD_EXTENSION
294bf260978Sdanielk1977 /*
295bf260978Sdanielk1977 ** Open the dynamic library located at zPath and return a handle.
296bf260978Sdanielk1977 */
devsymDlOpen(sqlite3_vfs * pVfs,const char * zPath)297bf260978Sdanielk1977 static void *devsymDlOpen(sqlite3_vfs *pVfs, const char *zPath){
298bf260978Sdanielk1977 return sqlite3OsDlOpen(g.pVfs, zPath);
299bf260978Sdanielk1977 }
300bf260978Sdanielk1977
301bf260978Sdanielk1977 /*
302bf260978Sdanielk1977 ** Populate the buffer zErrMsg (size nByte bytes) with a human readable
303bf260978Sdanielk1977 ** utf-8 string describing the most recent error encountered associated
304bf260978Sdanielk1977 ** with dynamic libraries.
305bf260978Sdanielk1977 */
devsymDlError(sqlite3_vfs * pVfs,int nByte,char * zErrMsg)306bf260978Sdanielk1977 static void devsymDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
307bf260978Sdanielk1977 sqlite3OsDlError(g.pVfs, nByte, zErrMsg);
308bf260978Sdanielk1977 }
309bf260978Sdanielk1977
310bf260978Sdanielk1977 /*
311bf260978Sdanielk1977 ** Return a pointer to the symbol zSymbol in the dynamic library pHandle.
312bf260978Sdanielk1977 */
devsymDlSym(sqlite3_vfs * pVfs,void * p,const char * zSym)313ec1724e8Sdrh static void (*devsymDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){
314ec1724e8Sdrh return sqlite3OsDlSym(g.pVfs, p, zSym);
315bf260978Sdanielk1977 }
316bf260978Sdanielk1977
317bf260978Sdanielk1977 /*
318bf260978Sdanielk1977 ** Close the dynamic library handle pHandle.
319bf260978Sdanielk1977 */
devsymDlClose(sqlite3_vfs * pVfs,void * pHandle)320bf260978Sdanielk1977 static void devsymDlClose(sqlite3_vfs *pVfs, void *pHandle){
321bf260978Sdanielk1977 sqlite3OsDlClose(g.pVfs, pHandle);
322bf260978Sdanielk1977 }
32375998ab3Sshane #endif /* SQLITE_OMIT_LOAD_EXTENSION */
324bf260978Sdanielk1977
325bf260978Sdanielk1977 /*
326bf260978Sdanielk1977 ** Populate the buffer pointed to by zBufOut with nByte bytes of
327bf260978Sdanielk1977 ** random data.
328bf260978Sdanielk1977 */
devsymRandomness(sqlite3_vfs * pVfs,int nByte,char * zBufOut)329bf260978Sdanielk1977 static int devsymRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
330bf260978Sdanielk1977 return sqlite3OsRandomness(g.pVfs, nByte, zBufOut);
331bf260978Sdanielk1977 }
332bf260978Sdanielk1977
333bf260978Sdanielk1977 /*
334bf260978Sdanielk1977 ** Sleep for nMicro microseconds. Return the number of microseconds
335bf260978Sdanielk1977 ** actually slept.
336bf260978Sdanielk1977 */
devsymSleep(sqlite3_vfs * pVfs,int nMicro)337bf260978Sdanielk1977 static int devsymSleep(sqlite3_vfs *pVfs, int nMicro){
338bf260978Sdanielk1977 return sqlite3OsSleep(g.pVfs, nMicro);
339bf260978Sdanielk1977 }
340bf260978Sdanielk1977
341bf260978Sdanielk1977 /*
342bf260978Sdanielk1977 ** Return the current time as a Julian Day number in *pTimeOut.
343bf260978Sdanielk1977 */
devsymCurrentTime(sqlite3_vfs * pVfs,double * pTimeOut)344bf260978Sdanielk1977 static int devsymCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
345b7e8ea20Sdrh return g.pVfs->xCurrentTime(g.pVfs, pTimeOut);
346bf260978Sdanielk1977 }
347bf260978Sdanielk1977
34833447e77Sdan /*
34933447e77Sdan ** Return the sector-size in bytes for an writecrash-file.
35033447e77Sdan */
writecrashSectorSize(sqlite3_file * pFile)35133447e77Sdan static int writecrashSectorSize(sqlite3_file *pFile){
35233447e77Sdan devsym_file *p = (devsym_file *)pFile;
35333447e77Sdan return sqlite3OsSectorSize(p->pReal);
35433447e77Sdan }
35533447e77Sdan
35633447e77Sdan /*
35733447e77Sdan ** Return the device characteristic flags supported by an writecrash-file.
35833447e77Sdan */
writecrashDeviceCharacteristics(sqlite3_file * pFile)35933447e77Sdan static int writecrashDeviceCharacteristics(sqlite3_file *pFile){
36033447e77Sdan devsym_file *p = (devsym_file *)pFile;
36133447e77Sdan return sqlite3OsDeviceCharacteristics(p->pReal);
36233447e77Sdan }
36333447e77Sdan
36433447e77Sdan /*
36533447e77Sdan ** Write data to an writecrash-file.
36633447e77Sdan */
writecrashWrite(sqlite3_file * pFile,const void * zBuf,int iAmt,sqlite_int64 iOfst)36733447e77Sdan static int writecrashWrite(
36833447e77Sdan sqlite3_file *pFile,
36933447e77Sdan const void *zBuf,
37033447e77Sdan int iAmt,
37133447e77Sdan sqlite_int64 iOfst
37233447e77Sdan ){
37333447e77Sdan devsym_file *p = (devsym_file *)pFile;
37433447e77Sdan if( g.nWriteCrash>0 ){
37533447e77Sdan g.nWriteCrash--;
37633447e77Sdan if( g.nWriteCrash==0 ) abort();
37733447e77Sdan }
37833447e77Sdan return sqlite3OsWrite(p->pReal, zBuf, iAmt, iOfst);
37933447e77Sdan }
38033447e77Sdan
38133447e77Sdan /*
38233447e77Sdan ** Open an writecrash file handle.
38333447e77Sdan */
writecrashOpen(sqlite3_vfs * pVfs,const char * zName,sqlite3_file * pFile,int flags,int * pOutFlags)38433447e77Sdan static int writecrashOpen(
38533447e77Sdan sqlite3_vfs *pVfs,
38633447e77Sdan const char *zName,
38733447e77Sdan sqlite3_file *pFile,
38833447e77Sdan int flags,
38933447e77Sdan int *pOutFlags
39033447e77Sdan ){
39133447e77Sdan static sqlite3_io_methods writecrash_io_methods = {
39233447e77Sdan 2, /* iVersion */
39333447e77Sdan devsymClose, /* xClose */
39433447e77Sdan devsymRead, /* xRead */
39533447e77Sdan writecrashWrite, /* xWrite */
39633447e77Sdan devsymTruncate, /* xTruncate */
39733447e77Sdan devsymSync, /* xSync */
39833447e77Sdan devsymFileSize, /* xFileSize */
39933447e77Sdan devsymLock, /* xLock */
40033447e77Sdan devsymUnlock, /* xUnlock */
40133447e77Sdan devsymCheckReservedLock, /* xCheckReservedLock */
40233447e77Sdan devsymFileControl, /* xFileControl */
40333447e77Sdan writecrashSectorSize, /* xSectorSize */
40433447e77Sdan writecrashDeviceCharacteristics, /* xDeviceCharacteristics */
40533447e77Sdan devsymShmMap, /* xShmMap */
40633447e77Sdan devsymShmLock, /* xShmLock */
40733447e77Sdan devsymShmBarrier, /* xShmBarrier */
40833447e77Sdan devsymShmUnmap /* xShmUnmap */
40933447e77Sdan };
41033447e77Sdan
41133447e77Sdan int rc;
41233447e77Sdan devsym_file *p = (devsym_file *)pFile;
41333447e77Sdan p->pReal = (sqlite3_file *)&p[1];
41433447e77Sdan rc = sqlite3OsOpen(g.pVfs, zName, p->pReal, flags, pOutFlags);
41533447e77Sdan if( p->pReal->pMethods ){
41633447e77Sdan pFile->pMethods = &writecrash_io_methods;
41733447e77Sdan }
41833447e77Sdan return rc;
41933447e77Sdan }
42033447e77Sdan
42133447e77Sdan static sqlite3_vfs devsym_vfs = {
42233447e77Sdan 2, /* iVersion */
42333447e77Sdan sizeof(devsym_file), /* szOsFile */
42433447e77Sdan DEVSYM_MAX_PATHNAME, /* mxPathname */
42533447e77Sdan 0, /* pNext */
42633447e77Sdan DEVSYM_VFS_NAME, /* zName */
42733447e77Sdan 0, /* pAppData */
42833447e77Sdan devsymOpen, /* xOpen */
42933447e77Sdan devsymDelete, /* xDelete */
43033447e77Sdan devsymAccess, /* xAccess */
43133447e77Sdan devsymFullPathname, /* xFullPathname */
43233447e77Sdan #ifndef SQLITE_OMIT_LOAD_EXTENSION
43333447e77Sdan devsymDlOpen, /* xDlOpen */
43433447e77Sdan devsymDlError, /* xDlError */
43533447e77Sdan devsymDlSym, /* xDlSym */
43633447e77Sdan devsymDlClose, /* xDlClose */
43733447e77Sdan #else
43833447e77Sdan 0, /* xDlOpen */
43933447e77Sdan 0, /* xDlError */
44033447e77Sdan 0, /* xDlSym */
44133447e77Sdan 0, /* xDlClose */
44233447e77Sdan #endif /* SQLITE_OMIT_LOAD_EXTENSION */
44333447e77Sdan devsymRandomness, /* xRandomness */
44433447e77Sdan devsymSleep, /* xSleep */
44533447e77Sdan devsymCurrentTime, /* xCurrentTime */
44633447e77Sdan 0, /* xGetLastError */
44733447e77Sdan 0 /* xCurrentTimeInt64 */
44833447e77Sdan };
44933447e77Sdan
45033447e77Sdan static sqlite3_vfs writecrash_vfs = {
45133447e77Sdan 2, /* iVersion */
45233447e77Sdan sizeof(devsym_file), /* szOsFile */
45333447e77Sdan DEVSYM_MAX_PATHNAME, /* mxPathname */
45433447e77Sdan 0, /* pNext */
45533447e77Sdan WRITECRASH_NAME, /* zName */
45633447e77Sdan 0, /* pAppData */
45733447e77Sdan writecrashOpen, /* xOpen */
45833447e77Sdan devsymDelete, /* xDelete */
45933447e77Sdan devsymAccess, /* xAccess */
46033447e77Sdan devsymFullPathname, /* xFullPathname */
46133447e77Sdan #ifndef SQLITE_OMIT_LOAD_EXTENSION
46233447e77Sdan devsymDlOpen, /* xDlOpen */
46333447e77Sdan devsymDlError, /* xDlError */
46433447e77Sdan devsymDlSym, /* xDlSym */
46533447e77Sdan devsymDlClose, /* xDlClose */
46633447e77Sdan #else
46733447e77Sdan 0, /* xDlOpen */
46833447e77Sdan 0, /* xDlError */
46933447e77Sdan 0, /* xDlSym */
47033447e77Sdan 0, /* xDlClose */
47133447e77Sdan #endif /* SQLITE_OMIT_LOAD_EXTENSION */
47233447e77Sdan devsymRandomness, /* xRandomness */
47333447e77Sdan devsymSleep, /* xSleep */
47433447e77Sdan devsymCurrentTime, /* xCurrentTime */
47533447e77Sdan 0, /* xGetLastError */
47633447e77Sdan 0 /* xCurrentTimeInt64 */
47733447e77Sdan };
47833447e77Sdan
4796ddb4bf9Sdan
480bf260978Sdanielk1977 /*
481bf260978Sdanielk1977 ** This procedure registers the devsym vfs with SQLite. If the argument is
482bf260978Sdanielk1977 ** true, the devsym vfs becomes the new default vfs. It is the only publicly
483bf260978Sdanielk1977 ** available function in this file.
484bf260978Sdanielk1977 */
devsym_register(int iDeviceChar,int iSectorSize)485bf260978Sdanielk1977 void devsym_register(int iDeviceChar, int iSectorSize){
48633447e77Sdan
487bf260978Sdanielk1977 if( g.pVfs==0 ){
488bf260978Sdanielk1977 g.pVfs = sqlite3_vfs_find(0);
489bf260978Sdanielk1977 devsym_vfs.szOsFile += g.pVfs->szOsFile;
49033447e77Sdan writecrash_vfs.szOsFile += g.pVfs->szOsFile;
491bf260978Sdanielk1977 sqlite3_vfs_register(&devsym_vfs, 0);
49233447e77Sdan sqlite3_vfs_register(&writecrash_vfs, 0);
493bf260978Sdanielk1977 }
494bf260978Sdanielk1977 if( iDeviceChar>=0 ){
495bf260978Sdanielk1977 g.iDeviceChar = iDeviceChar;
49647f18f72Sdrh }else{
49747f18f72Sdrh g.iDeviceChar = 0;
498bf260978Sdanielk1977 }
499bf260978Sdanielk1977 if( iSectorSize>=0 ){
500bf260978Sdanielk1977 g.iSectorSize = iSectorSize;
50147f18f72Sdrh }else{
50247f18f72Sdrh g.iSectorSize = 512;
503bf260978Sdanielk1977 }
504bf260978Sdanielk1977 }
505bf260978Sdanielk1977
devsym_unregister()50605accd22Sdan void devsym_unregister(){
50705accd22Sdan sqlite3_vfs_unregister(&devsym_vfs);
508e88c0cdeSdan sqlite3_vfs_unregister(&writecrash_vfs);
50905accd22Sdan g.pVfs = 0;
51005accd22Sdan g.iDeviceChar = 0;
51105accd22Sdan g.iSectorSize = 0;
51205accd22Sdan }
51305accd22Sdan
devsym_crash_on_write(int nWrite)51433447e77Sdan void devsym_crash_on_write(int nWrite){
51533447e77Sdan if( g.pVfs==0 ){
51633447e77Sdan g.pVfs = sqlite3_vfs_find(0);
51733447e77Sdan devsym_vfs.szOsFile += g.pVfs->szOsFile;
51833447e77Sdan writecrash_vfs.szOsFile += g.pVfs->szOsFile;
51933447e77Sdan sqlite3_vfs_register(&devsym_vfs, 0);
52033447e77Sdan sqlite3_vfs_register(&writecrash_vfs, 0);
52133447e77Sdan }
52233447e77Sdan g.nWriteCrash = nWrite;
52333447e77Sdan }
52433447e77Sdan
525bf260978Sdanielk1977 #endif
526