xref: /sqlite-3.40.0/src/test_devsym.c (revision 33447e77)
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"
31*33447e77Sdan #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;
80*33447e77Sdan   int nWriteCrash;
81bf260978Sdanielk1977 };
82*33447e77Sdan struct DevsymGlobal g = {0, 0, 512, 0};
83bf260978Sdanielk1977 
84bf260978Sdanielk1977 /*
85bf260978Sdanielk1977 ** Close an devsym-file.
86bf260978Sdanielk1977 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
185bf260978Sdanielk1977 static int devsymDeviceCharacteristics(sqlite3_file *pFile){
186bf260978Sdanielk1977   return g.iDeviceChar;
187bf260978Sdanielk1977 }
188bf260978Sdanielk1977 
189bf260978Sdanielk1977 /*
190365e2d25Sdrh ** Shared-memory methods are all pass-thrus.
191365e2d25Sdrh */
19273b64e4dSdrh static int devsymShmLock(sqlite3_file *pFile, int ofst, int n, int flags){
193365e2d25Sdrh   devsym_file *p = (devsym_file *)pFile;
19473b64e4dSdrh   return sqlite3OsShmLock(p->pReal, ofst, n, flags);
195365e2d25Sdrh }
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;
20418801915Sdan   return sqlite3OsShmMap(p->pReal, iRegion, szRegion, isWrite, pp);
20513a3cb82Sdan }
2066b017cc6Sdrh static void devsymShmBarrier(sqlite3_file *pFile){
2076b017cc6Sdrh   devsym_file *p = (devsym_file *)pFile;
2086b017cc6Sdrh   sqlite3OsShmBarrier(p->pReal);
2096b017cc6Sdrh }
210e11fedc5Sdrh static int devsymShmUnmap(sqlite3_file *pFile, int delFlag){
2116b017cc6Sdrh   devsym_file *p = (devsym_file *)pFile;
212e11fedc5Sdrh   return sqlite3OsShmUnmap(p->pReal, delFlag);
2136b017cc6Sdrh }
214365e2d25Sdrh 
215365e2d25Sdrh 
216365e2d25Sdrh 
217365e2d25Sdrh /*
218bf260978Sdanielk1977 ** Open an devsym file handle.
219bf260978Sdanielk1977 */
220bf260978Sdanielk1977 static int devsymOpen(
221bf260978Sdanielk1977   sqlite3_vfs *pVfs,
222bf260978Sdanielk1977   const char *zName,
223bf260978Sdanielk1977   sqlite3_file *pFile,
224bf260978Sdanielk1977   int flags,
225bf260978Sdanielk1977   int *pOutFlags
226bf260978Sdanielk1977 ){
227*33447e77Sdan static sqlite3_io_methods devsym_io_methods = {
228*33447e77Sdan   2,                                /* iVersion */
229*33447e77Sdan   devsymClose,                      /* xClose */
230*33447e77Sdan   devsymRead,                       /* xRead */
231*33447e77Sdan   devsymWrite,                      /* xWrite */
232*33447e77Sdan   devsymTruncate,                   /* xTruncate */
233*33447e77Sdan   devsymSync,                       /* xSync */
234*33447e77Sdan   devsymFileSize,                   /* xFileSize */
235*33447e77Sdan   devsymLock,                       /* xLock */
236*33447e77Sdan   devsymUnlock,                     /* xUnlock */
237*33447e77Sdan   devsymCheckReservedLock,          /* xCheckReservedLock */
238*33447e77Sdan   devsymFileControl,                /* xFileControl */
239*33447e77Sdan   devsymSectorSize,                 /* xSectorSize */
240*33447e77Sdan   devsymDeviceCharacteristics,      /* xDeviceCharacteristics */
241*33447e77Sdan   devsymShmMap,                     /* xShmMap */
242*33447e77Sdan   devsymShmLock,                    /* xShmLock */
243*33447e77Sdan   devsymShmBarrier,                 /* xShmBarrier */
244*33447e77Sdan   devsymShmUnmap                    /* xShmUnmap */
245*33447e77Sdan };
246*33447e77Sdan 
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
344bf260978Sdanielk1977 static int devsymCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
345b7e8ea20Sdrh   return g.pVfs->xCurrentTime(g.pVfs, pTimeOut);
346bf260978Sdanielk1977 }
347bf260978Sdanielk1977 
348*33447e77Sdan /*
349*33447e77Sdan ** Return the sector-size in bytes for an writecrash-file.
350*33447e77Sdan */
351*33447e77Sdan static int writecrashSectorSize(sqlite3_file *pFile){
352*33447e77Sdan   devsym_file *p = (devsym_file *)pFile;
353*33447e77Sdan   return sqlite3OsSectorSize(p->pReal);
354*33447e77Sdan }
355*33447e77Sdan 
356*33447e77Sdan /*
357*33447e77Sdan ** Return the device characteristic flags supported by an writecrash-file.
358*33447e77Sdan */
359*33447e77Sdan static int writecrashDeviceCharacteristics(sqlite3_file *pFile){
360*33447e77Sdan   devsym_file *p = (devsym_file *)pFile;
361*33447e77Sdan   return sqlite3OsDeviceCharacteristics(p->pReal);
362*33447e77Sdan }
363*33447e77Sdan 
364*33447e77Sdan /*
365*33447e77Sdan ** Write data to an writecrash-file.
366*33447e77Sdan */
367*33447e77Sdan static int writecrashWrite(
368*33447e77Sdan   sqlite3_file *pFile,
369*33447e77Sdan   const void *zBuf,
370*33447e77Sdan   int iAmt,
371*33447e77Sdan   sqlite_int64 iOfst
372*33447e77Sdan ){
373*33447e77Sdan   devsym_file *p = (devsym_file *)pFile;
374*33447e77Sdan   if( g.nWriteCrash>0 ){
375*33447e77Sdan     g.nWriteCrash--;
376*33447e77Sdan     if( g.nWriteCrash==0 ) abort();
377*33447e77Sdan   }
378*33447e77Sdan   return sqlite3OsWrite(p->pReal, zBuf, iAmt, iOfst);
379*33447e77Sdan }
380*33447e77Sdan 
381*33447e77Sdan /*
382*33447e77Sdan ** Open an writecrash file handle.
383*33447e77Sdan */
384*33447e77Sdan static int writecrashOpen(
385*33447e77Sdan   sqlite3_vfs *pVfs,
386*33447e77Sdan   const char *zName,
387*33447e77Sdan   sqlite3_file *pFile,
388*33447e77Sdan   int flags,
389*33447e77Sdan   int *pOutFlags
390*33447e77Sdan ){
391*33447e77Sdan static sqlite3_io_methods writecrash_io_methods = {
392*33447e77Sdan   2,                                /* iVersion */
393*33447e77Sdan   devsymClose,                      /* xClose */
394*33447e77Sdan   devsymRead,                       /* xRead */
395*33447e77Sdan   writecrashWrite,                  /* xWrite */
396*33447e77Sdan   devsymTruncate,                   /* xTruncate */
397*33447e77Sdan   devsymSync,                       /* xSync */
398*33447e77Sdan   devsymFileSize,                   /* xFileSize */
399*33447e77Sdan   devsymLock,                       /* xLock */
400*33447e77Sdan   devsymUnlock,                     /* xUnlock */
401*33447e77Sdan   devsymCheckReservedLock,          /* xCheckReservedLock */
402*33447e77Sdan   devsymFileControl,                /* xFileControl */
403*33447e77Sdan   writecrashSectorSize,             /* xSectorSize */
404*33447e77Sdan   writecrashDeviceCharacteristics,  /* xDeviceCharacteristics */
405*33447e77Sdan   devsymShmMap,                     /* xShmMap */
406*33447e77Sdan   devsymShmLock,                    /* xShmLock */
407*33447e77Sdan   devsymShmBarrier,                 /* xShmBarrier */
408*33447e77Sdan   devsymShmUnmap                    /* xShmUnmap */
409*33447e77Sdan };
410*33447e77Sdan 
411*33447e77Sdan   int rc;
412*33447e77Sdan   devsym_file *p = (devsym_file *)pFile;
413*33447e77Sdan   p->pReal = (sqlite3_file *)&p[1];
414*33447e77Sdan   rc = sqlite3OsOpen(g.pVfs, zName, p->pReal, flags, pOutFlags);
415*33447e77Sdan   if( p->pReal->pMethods ){
416*33447e77Sdan     pFile->pMethods = &writecrash_io_methods;
417*33447e77Sdan   }
418*33447e77Sdan   return rc;
419*33447e77Sdan }
420*33447e77Sdan 
421*33447e77Sdan static sqlite3_vfs devsym_vfs = {
422*33447e77Sdan   2,                     /* iVersion */
423*33447e77Sdan   sizeof(devsym_file),      /* szOsFile */
424*33447e77Sdan   DEVSYM_MAX_PATHNAME,      /* mxPathname */
425*33447e77Sdan   0,                     /* pNext */
426*33447e77Sdan   DEVSYM_VFS_NAME,          /* zName */
427*33447e77Sdan   0,                     /* pAppData */
428*33447e77Sdan   devsymOpen,               /* xOpen */
429*33447e77Sdan   devsymDelete,             /* xDelete */
430*33447e77Sdan   devsymAccess,             /* xAccess */
431*33447e77Sdan   devsymFullPathname,       /* xFullPathname */
432*33447e77Sdan #ifndef SQLITE_OMIT_LOAD_EXTENSION
433*33447e77Sdan   devsymDlOpen,             /* xDlOpen */
434*33447e77Sdan   devsymDlError,            /* xDlError */
435*33447e77Sdan   devsymDlSym,              /* xDlSym */
436*33447e77Sdan   devsymDlClose,            /* xDlClose */
437*33447e77Sdan #else
438*33447e77Sdan   0,                        /* xDlOpen */
439*33447e77Sdan   0,                        /* xDlError */
440*33447e77Sdan   0,                        /* xDlSym */
441*33447e77Sdan   0,                        /* xDlClose */
442*33447e77Sdan #endif /* SQLITE_OMIT_LOAD_EXTENSION */
443*33447e77Sdan   devsymRandomness,         /* xRandomness */
444*33447e77Sdan   devsymSleep,              /* xSleep */
445*33447e77Sdan   devsymCurrentTime,        /* xCurrentTime */
446*33447e77Sdan   0,                        /* xGetLastError */
447*33447e77Sdan   0                         /* xCurrentTimeInt64 */
448*33447e77Sdan };
449*33447e77Sdan 
450*33447e77Sdan static sqlite3_vfs writecrash_vfs = {
451*33447e77Sdan   2,                     /* iVersion */
452*33447e77Sdan   sizeof(devsym_file),      /* szOsFile */
453*33447e77Sdan   DEVSYM_MAX_PATHNAME,      /* mxPathname */
454*33447e77Sdan   0,                     /* pNext */
455*33447e77Sdan   WRITECRASH_NAME,          /* zName */
456*33447e77Sdan   0,                     /* pAppData */
457*33447e77Sdan   writecrashOpen,           /* xOpen */
458*33447e77Sdan   devsymDelete,             /* xDelete */
459*33447e77Sdan   devsymAccess,             /* xAccess */
460*33447e77Sdan   devsymFullPathname,       /* xFullPathname */
461*33447e77Sdan #ifndef SQLITE_OMIT_LOAD_EXTENSION
462*33447e77Sdan   devsymDlOpen,             /* xDlOpen */
463*33447e77Sdan   devsymDlError,            /* xDlError */
464*33447e77Sdan   devsymDlSym,              /* xDlSym */
465*33447e77Sdan   devsymDlClose,            /* xDlClose */
466*33447e77Sdan #else
467*33447e77Sdan   0,                        /* xDlOpen */
468*33447e77Sdan   0,                        /* xDlError */
469*33447e77Sdan   0,                        /* xDlSym */
470*33447e77Sdan   0,                        /* xDlClose */
471*33447e77Sdan #endif /* SQLITE_OMIT_LOAD_EXTENSION */
472*33447e77Sdan   devsymRandomness,         /* xRandomness */
473*33447e77Sdan   devsymSleep,              /* xSleep */
474*33447e77Sdan   devsymCurrentTime,        /* xCurrentTime */
475*33447e77Sdan   0,                        /* xGetLastError */
476*33447e77Sdan   0                         /* xCurrentTimeInt64 */
477*33447e77Sdan };
478*33447e77Sdan 
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 */
485bf260978Sdanielk1977 void devsym_register(int iDeviceChar, int iSectorSize){
486*33447e77Sdan 
487bf260978Sdanielk1977   if( g.pVfs==0 ){
488bf260978Sdanielk1977     g.pVfs = sqlite3_vfs_find(0);
489bf260978Sdanielk1977     devsym_vfs.szOsFile += g.pVfs->szOsFile;
490*33447e77Sdan     writecrash_vfs.szOsFile += g.pVfs->szOsFile;
491bf260978Sdanielk1977     sqlite3_vfs_register(&devsym_vfs, 0);
492*33447e77Sdan     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 
50605accd22Sdan void devsym_unregister(){
50705accd22Sdan   sqlite3_vfs_unregister(&devsym_vfs);
50805accd22Sdan   g.pVfs = 0;
50905accd22Sdan   g.iDeviceChar = 0;
51005accd22Sdan   g.iSectorSize = 0;
51105accd22Sdan }
51205accd22Sdan 
513*33447e77Sdan void devsym_crash_on_write(int nWrite){
514*33447e77Sdan   if( g.pVfs==0 ){
515*33447e77Sdan     g.pVfs = sqlite3_vfs_find(0);
516*33447e77Sdan     devsym_vfs.szOsFile += g.pVfs->szOsFile;
517*33447e77Sdan     writecrash_vfs.szOsFile += g.pVfs->szOsFile;
518*33447e77Sdan     sqlite3_vfs_register(&devsym_vfs, 0);
519*33447e77Sdan     sqlite3_vfs_register(&writecrash_vfs, 0);
520*33447e77Sdan   }
521*33447e77Sdan   g.nWriteCrash = nWrite;
522*33447e77Sdan }
523*33447e77Sdan 
524bf260978Sdanielk1977 #endif
525