xref: /sqlite-3.40.0/src/test_devsym.c (revision 2667be5e)
1 /*
2 ** 2008 Jan 22
3 **
4 ** The author disclaims copyright to this source code.  In place of
5 ** a legal notice, here is a blessing:
6 **
7 **    May you do good and not evil.
8 **    May you find forgiveness for yourself and forgive others.
9 **    May you share freely, never taking more than you give.
10 **
11 ******************************************************************************
12 **
13 ** This file contains code that modified the OS layer in order to simulate
14 ** different device types (by overriding the return values of the
15 ** xDeviceCharacteristics() and xSectorSize() methods).
16 */
17 #if SQLITE_TEST          /* This file is used for testing only */
18 
19 #include "sqlite3.h"
20 #include "sqliteInt.h"
21 
22 /*
23 ** Maximum pathname length supported by the devsym backend.
24 */
25 #define DEVSYM_MAX_PATHNAME 512
26 
27 /*
28 ** Name used to identify this VFS.
29 */
30 #define DEVSYM_VFS_NAME "devsym"
31 
32 typedef struct devsym_file devsym_file;
33 struct devsym_file {
34   sqlite3_file base;
35   sqlite3_file *pReal;
36 };
37 
38 /*
39 ** Method declarations for devsym_file.
40 */
41 static int devsymClose(sqlite3_file*);
42 static int devsymRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
43 static int devsymWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst);
44 static int devsymTruncate(sqlite3_file*, sqlite3_int64 size);
45 static int devsymSync(sqlite3_file*, int flags);
46 static int devsymFileSize(sqlite3_file*, sqlite3_int64 *pSize);
47 static int devsymLock(sqlite3_file*, int);
48 static int devsymUnlock(sqlite3_file*, int);
49 static int devsymCheckReservedLock(sqlite3_file*, int *);
50 static int devsymFileControl(sqlite3_file*, int op, void *pArg);
51 static int devsymSectorSize(sqlite3_file*);
52 static int devsymDeviceCharacteristics(sqlite3_file*);
53 static int devsymShmOpen(sqlite3_file*);
54 static int devsymShmLock(sqlite3_file*,int,int,int);
55 static int devsymShmMap(sqlite3_file*,int,int,int, void volatile **);
56 static void devsymShmBarrier(sqlite3_file*);
57 static int devsymShmClose(sqlite3_file*,int);
58 
59 /*
60 ** Method declarations for devsym_vfs.
61 */
62 static int devsymOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *);
63 static int devsymDelete(sqlite3_vfs*, const char *zName, int syncDir);
64 static int devsymAccess(sqlite3_vfs*, const char *zName, int flags, int *);
65 static int devsymFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut);
66 #ifndef SQLITE_OMIT_LOAD_EXTENSION
67 static void *devsymDlOpen(sqlite3_vfs*, const char *zFilename);
68 static void devsymDlError(sqlite3_vfs*, int nByte, char *zErrMsg);
69 static void (*devsymDlSym(sqlite3_vfs*,void*, const char *zSymbol))(void);
70 static void devsymDlClose(sqlite3_vfs*, void*);
71 #endif /* SQLITE_OMIT_LOAD_EXTENSION */
72 static int devsymRandomness(sqlite3_vfs*, int nByte, char *zOut);
73 static int devsymSleep(sqlite3_vfs*, int microseconds);
74 static int devsymCurrentTime(sqlite3_vfs*, double*);
75 
76 static sqlite3_vfs devsym_vfs = {
77   2,                     /* iVersion */
78   sizeof(devsym_file),      /* szOsFile */
79   DEVSYM_MAX_PATHNAME,      /* mxPathname */
80   0,                     /* pNext */
81   DEVSYM_VFS_NAME,          /* zName */
82   0,                     /* pAppData */
83   devsymOpen,               /* xOpen */
84   devsymDelete,             /* xDelete */
85   devsymAccess,             /* xAccess */
86   devsymFullPathname,       /* xFullPathname */
87 #ifndef SQLITE_OMIT_LOAD_EXTENSION
88   devsymDlOpen,             /* xDlOpen */
89   devsymDlError,            /* xDlError */
90   devsymDlSym,              /* xDlSym */
91   devsymDlClose,            /* xDlClose */
92 #else
93   0,                        /* xDlOpen */
94   0,                        /* xDlError */
95   0,                        /* xDlSym */
96   0,                        /* xDlClose */
97 #endif /* SQLITE_OMIT_LOAD_EXTENSION */
98   devsymRandomness,         /* xRandomness */
99   devsymSleep,              /* xSleep */
100   devsymCurrentTime,        /* xCurrentTime */
101   0,                        /* xGetLastError */
102   0                         /* xCurrentTimeInt64 */
103 };
104 
105 static sqlite3_io_methods devsym_io_methods = {
106   2,                                /* iVersion */
107   devsymClose,                      /* xClose */
108   devsymRead,                       /* xRead */
109   devsymWrite,                      /* xWrite */
110   devsymTruncate,                   /* xTruncate */
111   devsymSync,                       /* xSync */
112   devsymFileSize,                   /* xFileSize */
113   devsymLock,                       /* xLock */
114   devsymUnlock,                     /* xUnlock */
115   devsymCheckReservedLock,          /* xCheckReservedLock */
116   devsymFileControl,                /* xFileControl */
117   devsymSectorSize,                 /* xSectorSize */
118   devsymDeviceCharacteristics,      /* xDeviceCharacteristics */
119   devsymShmOpen,                    /* xShmOpen */
120   devsymShmLock,                    /* xShmLock */
121   devsymShmMap,                     /* xShmMap */
122   devsymShmBarrier,                 /* xShmBarrier */
123   devsymShmClose                    /* xShmClose */
124 };
125 
126 struct DevsymGlobal {
127   sqlite3_vfs *pVfs;
128   int iDeviceChar;
129   int iSectorSize;
130 };
131 struct DevsymGlobal g = {0, 0, 512};
132 
133 /*
134 ** Close an devsym-file.
135 */
136 static int devsymClose(sqlite3_file *pFile){
137   devsym_file *p = (devsym_file *)pFile;
138   return sqlite3OsClose(p->pReal);
139 }
140 
141 /*
142 ** Read data from an devsym-file.
143 */
144 static int devsymRead(
145   sqlite3_file *pFile,
146   void *zBuf,
147   int iAmt,
148   sqlite_int64 iOfst
149 ){
150   devsym_file *p = (devsym_file *)pFile;
151   return sqlite3OsRead(p->pReal, zBuf, iAmt, iOfst);
152 }
153 
154 /*
155 ** Write data to an devsym-file.
156 */
157 static int devsymWrite(
158   sqlite3_file *pFile,
159   const void *zBuf,
160   int iAmt,
161   sqlite_int64 iOfst
162 ){
163   devsym_file *p = (devsym_file *)pFile;
164   return sqlite3OsWrite(p->pReal, zBuf, iAmt, iOfst);
165 }
166 
167 /*
168 ** Truncate an devsym-file.
169 */
170 static int devsymTruncate(sqlite3_file *pFile, sqlite_int64 size){
171   devsym_file *p = (devsym_file *)pFile;
172   return sqlite3OsTruncate(p->pReal, size);
173 }
174 
175 /*
176 ** Sync an devsym-file.
177 */
178 static int devsymSync(sqlite3_file *pFile, int flags){
179   devsym_file *p = (devsym_file *)pFile;
180   return sqlite3OsSync(p->pReal, flags);
181 }
182 
183 /*
184 ** Return the current file-size of an devsym-file.
185 */
186 static int devsymFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
187   devsym_file *p = (devsym_file *)pFile;
188   return sqlite3OsFileSize(p->pReal, pSize);
189 }
190 
191 /*
192 ** Lock an devsym-file.
193 */
194 static int devsymLock(sqlite3_file *pFile, int eLock){
195   devsym_file *p = (devsym_file *)pFile;
196   return sqlite3OsLock(p->pReal, eLock);
197 }
198 
199 /*
200 ** Unlock an devsym-file.
201 */
202 static int devsymUnlock(sqlite3_file *pFile, int eLock){
203   devsym_file *p = (devsym_file *)pFile;
204   return sqlite3OsUnlock(p->pReal, eLock);
205 }
206 
207 /*
208 ** Check if another file-handle holds a RESERVED lock on an devsym-file.
209 */
210 static int devsymCheckReservedLock(sqlite3_file *pFile, int *pResOut){
211   devsym_file *p = (devsym_file *)pFile;
212   return sqlite3OsCheckReservedLock(p->pReal, pResOut);
213 }
214 
215 /*
216 ** File control method. For custom operations on an devsym-file.
217 */
218 static int devsymFileControl(sqlite3_file *pFile, int op, void *pArg){
219   devsym_file *p = (devsym_file *)pFile;
220   return sqlite3OsFileControl(p->pReal, op, pArg);
221 }
222 
223 /*
224 ** Return the sector-size in bytes for an devsym-file.
225 */
226 static int devsymSectorSize(sqlite3_file *pFile){
227   return g.iSectorSize;
228 }
229 
230 /*
231 ** Return the device characteristic flags supported by an devsym-file.
232 */
233 static int devsymDeviceCharacteristics(sqlite3_file *pFile){
234   return g.iDeviceChar;
235 }
236 
237 /*
238 ** Shared-memory methods are all pass-thrus.
239 */
240 static int devsymShmOpen(sqlite3_file *pFile){
241   devsym_file *p = (devsym_file *)pFile;
242   return sqlite3OsShmOpen(p->pReal);
243 }
244 static int devsymShmLock(sqlite3_file *pFile, int ofst, int n, int flags){
245   devsym_file *p = (devsym_file *)pFile;
246   return sqlite3OsShmLock(p->pReal, ofst, n, flags);
247 }
248 static int devsymShmMap(
249   sqlite3_file *pFile,
250   int iRegion,
251   int szRegion,
252   int isWrite,
253   void volatile **pp
254 ){
255   devsym_file *p = (devsym_file *)pFile;
256   return sqlite3OsShmMap(p->pReal, iRegion, szRegion, isWrite, pp);
257 }
258 static void devsymShmBarrier(sqlite3_file *pFile){
259   devsym_file *p = (devsym_file *)pFile;
260   sqlite3OsShmBarrier(p->pReal);
261 }
262 static int devsymShmClose(sqlite3_file *pFile, int delFlag){
263   devsym_file *p = (devsym_file *)pFile;
264   return sqlite3OsShmClose(p->pReal, delFlag);
265 }
266 
267 
268 
269 /*
270 ** Open an devsym file handle.
271 */
272 static int devsymOpen(
273   sqlite3_vfs *pVfs,
274   const char *zName,
275   sqlite3_file *pFile,
276   int flags,
277   int *pOutFlags
278 ){
279   int rc;
280   devsym_file *p = (devsym_file *)pFile;
281   p->pReal = (sqlite3_file *)&p[1];
282   rc = sqlite3OsOpen(g.pVfs, zName, p->pReal, flags, pOutFlags);
283   if( p->pReal->pMethods ){
284     pFile->pMethods = &devsym_io_methods;
285   }
286   return rc;
287 }
288 
289 /*
290 ** Delete the file located at zPath. If the dirSync argument is true,
291 ** ensure the file-system modifications are synced to disk before
292 ** returning.
293 */
294 static int devsymDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
295   return sqlite3OsDelete(g.pVfs, zPath, dirSync);
296 }
297 
298 /*
299 ** Test for access permissions. Return true if the requested permission
300 ** is available, or false otherwise.
301 */
302 static int devsymAccess(
303   sqlite3_vfs *pVfs,
304   const char *zPath,
305   int flags,
306   int *pResOut
307 ){
308   return sqlite3OsAccess(g.pVfs, zPath, flags, pResOut);
309 }
310 
311 /*
312 ** Populate buffer zOut with the full canonical pathname corresponding
313 ** to the pathname in zPath. zOut is guaranteed to point to a buffer
314 ** of at least (DEVSYM_MAX_PATHNAME+1) bytes.
315 */
316 static int devsymFullPathname(
317   sqlite3_vfs *pVfs,
318   const char *zPath,
319   int nOut,
320   char *zOut
321 ){
322   return sqlite3OsFullPathname(g.pVfs, zPath, nOut, zOut);
323 }
324 
325 #ifndef SQLITE_OMIT_LOAD_EXTENSION
326 /*
327 ** Open the dynamic library located at zPath and return a handle.
328 */
329 static void *devsymDlOpen(sqlite3_vfs *pVfs, const char *zPath){
330   return sqlite3OsDlOpen(g.pVfs, zPath);
331 }
332 
333 /*
334 ** Populate the buffer zErrMsg (size nByte bytes) with a human readable
335 ** utf-8 string describing the most recent error encountered associated
336 ** with dynamic libraries.
337 */
338 static void devsymDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
339   sqlite3OsDlError(g.pVfs, nByte, zErrMsg);
340 }
341 
342 /*
343 ** Return a pointer to the symbol zSymbol in the dynamic library pHandle.
344 */
345 static void (*devsymDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){
346   return sqlite3OsDlSym(g.pVfs, p, zSym);
347 }
348 
349 /*
350 ** Close the dynamic library handle pHandle.
351 */
352 static void devsymDlClose(sqlite3_vfs *pVfs, void *pHandle){
353   sqlite3OsDlClose(g.pVfs, pHandle);
354 }
355 #endif /* SQLITE_OMIT_LOAD_EXTENSION */
356 
357 /*
358 ** Populate the buffer pointed to by zBufOut with nByte bytes of
359 ** random data.
360 */
361 static int devsymRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
362   return sqlite3OsRandomness(g.pVfs, nByte, zBufOut);
363 }
364 
365 /*
366 ** Sleep for nMicro microseconds. Return the number of microseconds
367 ** actually slept.
368 */
369 static int devsymSleep(sqlite3_vfs *pVfs, int nMicro){
370   return sqlite3OsSleep(g.pVfs, nMicro);
371 }
372 
373 /*
374 ** Return the current time as a Julian Day number in *pTimeOut.
375 */
376 static int devsymCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
377   return g.pVfs->xCurrentTime(g.pVfs, pTimeOut);
378 }
379 
380 
381 /*
382 ** This procedure registers the devsym vfs with SQLite. If the argument is
383 ** true, the devsym vfs becomes the new default vfs. It is the only publicly
384 ** available function in this file.
385 */
386 void devsym_register(int iDeviceChar, int iSectorSize){
387   if( g.pVfs==0 ){
388     g.pVfs = sqlite3_vfs_find(0);
389     devsym_vfs.szOsFile += g.pVfs->szOsFile;
390     sqlite3_vfs_register(&devsym_vfs, 0);
391   }
392   if( iDeviceChar>=0 ){
393     g.iDeviceChar = iDeviceChar;
394   }else{
395     g.iDeviceChar = 0;
396   }
397   if( iSectorSize>=0 ){
398     g.iSectorSize = iSectorSize;
399   }else{
400     g.iSectorSize = 512;
401   }
402 }
403 
404 #endif
405