xref: /sqlite-3.40.0/src/test_devsym.c (revision 2d536e18)
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 
54 /*
55 ** Method declarations for devsym_vfs.
56 */
57 static int devsymOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *);
58 static int devsymDelete(sqlite3_vfs*, const char *zName, int syncDir);
59 static int devsymAccess(sqlite3_vfs*, const char *zName, int flags, int *);
60 static int devsymFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut);
61 #ifndef SQLITE_OMIT_LOAD_EXTENSION
62 static void *devsymDlOpen(sqlite3_vfs*, const char *zFilename);
63 static void devsymDlError(sqlite3_vfs*, int nByte, char *zErrMsg);
64 static void (*devsymDlSym(sqlite3_vfs*,void*, const char *zSymbol))(void);
65 static void devsymDlClose(sqlite3_vfs*, void*);
66 #endif /* SQLITE_OMIT_LOAD_EXTENSION */
67 static int devsymRandomness(sqlite3_vfs*, int nByte, char *zOut);
68 static int devsymSleep(sqlite3_vfs*, int microseconds);
69 static int devsymCurrentTime(sqlite3_vfs*, double*);
70 
71 static int devsymShmOpen(sqlite3_vfs *, const char *, sqlite3_shm **);
72 static int devsymShmSize(sqlite3_shm *, int , int *);
73 static int devsymShmGet(sqlite3_shm *, int , int *, void **);
74 static int devsymShmRelease(sqlite3_shm *);
75 static int devsymShmLock(sqlite3_shm *, int , int *);
76 static int devsymShmClose(sqlite3_shm *, int);
77 
78 static sqlite3_vfs devsym_vfs = {
79   2,                     /* iVersion */
80   sizeof(devsym_file),      /* szOsFile */
81   DEVSYM_MAX_PATHNAME,      /* mxPathname */
82   0,                     /* pNext */
83   DEVSYM_VFS_NAME,          /* zName */
84   0,                     /* pAppData */
85   devsymOpen,               /* xOpen */
86   devsymDelete,             /* xDelete */
87   devsymAccess,             /* xAccess */
88   devsymFullPathname,       /* xFullPathname */
89 #ifndef SQLITE_OMIT_LOAD_EXTENSION
90   devsymDlOpen,             /* xDlOpen */
91   devsymDlError,            /* xDlError */
92   devsymDlSym,              /* xDlSym */
93   devsymDlClose,            /* xDlClose */
94 #else
95   0,                        /* xDlOpen */
96   0,                        /* xDlError */
97   0,                        /* xDlSym */
98   0,                        /* xDlClose */
99 #endif /* SQLITE_OMIT_LOAD_EXTENSION */
100   devsymRandomness,         /* xRandomness */
101   devsymSleep,              /* xSleep */
102   devsymCurrentTime,        /* xCurrentTime */
103   0,                        /* xGetLastError */
104   devsymShmOpen,
105   devsymShmSize,
106   devsymShmGet,
107   devsymShmRelease,
108   0,
109   0,
110   devsymShmLock,
111   devsymShmClose,
112   0,
113   0,
114 };
115 
116 static sqlite3_io_methods devsym_io_methods = {
117   1,                            /* iVersion */
118   devsymClose,                      /* xClose */
119   devsymRead,                       /* xRead */
120   devsymWrite,                      /* xWrite */
121   devsymTruncate,                   /* xTruncate */
122   devsymSync,                       /* xSync */
123   devsymFileSize,                   /* xFileSize */
124   devsymLock,                       /* xLock */
125   devsymUnlock,                     /* xUnlock */
126   devsymCheckReservedLock,          /* xCheckReservedLock */
127   devsymFileControl,                /* xFileControl */
128   devsymSectorSize,                 /* xSectorSize */
129   devsymDeviceCharacteristics       /* xDeviceCharacteristics */
130 };
131 
132 struct DevsymGlobal {
133   sqlite3_vfs *pVfs;
134   int iDeviceChar;
135   int iSectorSize;
136 };
137 struct DevsymGlobal g = {0, 0, 512};
138 
139 /*
140 ** Close an devsym-file.
141 */
142 static int devsymClose(sqlite3_file *pFile){
143   devsym_file *p = (devsym_file *)pFile;
144   return sqlite3OsClose(p->pReal);
145 }
146 
147 /*
148 ** Read data from an devsym-file.
149 */
150 static int devsymRead(
151   sqlite3_file *pFile,
152   void *zBuf,
153   int iAmt,
154   sqlite_int64 iOfst
155 ){
156   devsym_file *p = (devsym_file *)pFile;
157   return sqlite3OsRead(p->pReal, zBuf, iAmt, iOfst);
158 }
159 
160 /*
161 ** Write data to an devsym-file.
162 */
163 static int devsymWrite(
164   sqlite3_file *pFile,
165   const void *zBuf,
166   int iAmt,
167   sqlite_int64 iOfst
168 ){
169   devsym_file *p = (devsym_file *)pFile;
170   return sqlite3OsWrite(p->pReal, zBuf, iAmt, iOfst);
171 }
172 
173 /*
174 ** Truncate an devsym-file.
175 */
176 static int devsymTruncate(sqlite3_file *pFile, sqlite_int64 size){
177   devsym_file *p = (devsym_file *)pFile;
178   return sqlite3OsTruncate(p->pReal, size);
179 }
180 
181 /*
182 ** Sync an devsym-file.
183 */
184 static int devsymSync(sqlite3_file *pFile, int flags){
185   devsym_file *p = (devsym_file *)pFile;
186   return sqlite3OsSync(p->pReal, flags);
187 }
188 
189 /*
190 ** Return the current file-size of an devsym-file.
191 */
192 static int devsymFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
193   devsym_file *p = (devsym_file *)pFile;
194   return sqlite3OsFileSize(p->pReal, pSize);
195 }
196 
197 /*
198 ** Lock an devsym-file.
199 */
200 static int devsymLock(sqlite3_file *pFile, int eLock){
201   devsym_file *p = (devsym_file *)pFile;
202   return sqlite3OsLock(p->pReal, eLock);
203 }
204 
205 /*
206 ** Unlock an devsym-file.
207 */
208 static int devsymUnlock(sqlite3_file *pFile, int eLock){
209   devsym_file *p = (devsym_file *)pFile;
210   return sqlite3OsUnlock(p->pReal, eLock);
211 }
212 
213 /*
214 ** Check if another file-handle holds a RESERVED lock on an devsym-file.
215 */
216 static int devsymCheckReservedLock(sqlite3_file *pFile, int *pResOut){
217   devsym_file *p = (devsym_file *)pFile;
218   return sqlite3OsCheckReservedLock(p->pReal, pResOut);
219 }
220 
221 /*
222 ** File control method. For custom operations on an devsym-file.
223 */
224 static int devsymFileControl(sqlite3_file *pFile, int op, void *pArg){
225   devsym_file *p = (devsym_file *)pFile;
226   return sqlite3OsFileControl(p->pReal, op, pArg);
227 }
228 
229 /*
230 ** Return the sector-size in bytes for an devsym-file.
231 */
232 static int devsymSectorSize(sqlite3_file *pFile){
233   return g.iSectorSize;
234 }
235 
236 /*
237 ** Return the device characteristic flags supported by an devsym-file.
238 */
239 static int devsymDeviceCharacteristics(sqlite3_file *pFile){
240   return g.iDeviceChar;
241 }
242 
243 /*
244 ** Open an devsym file handle.
245 */
246 static int devsymOpen(
247   sqlite3_vfs *pVfs,
248   const char *zName,
249   sqlite3_file *pFile,
250   int flags,
251   int *pOutFlags
252 ){
253   int rc;
254   devsym_file *p = (devsym_file *)pFile;
255   p->pReal = (sqlite3_file *)&p[1];
256   rc = sqlite3OsOpen(g.pVfs, zName, p->pReal, flags, pOutFlags);
257   if( p->pReal->pMethods ){
258     pFile->pMethods = &devsym_io_methods;
259   }
260   return rc;
261 }
262 
263 /*
264 ** Delete the file located at zPath. If the dirSync argument is true,
265 ** ensure the file-system modifications are synced to disk before
266 ** returning.
267 */
268 static int devsymDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
269   return sqlite3OsDelete(g.pVfs, zPath, dirSync);
270 }
271 
272 /*
273 ** Test for access permissions. Return true if the requested permission
274 ** is available, or false otherwise.
275 */
276 static int devsymAccess(
277   sqlite3_vfs *pVfs,
278   const char *zPath,
279   int flags,
280   int *pResOut
281 ){
282   return sqlite3OsAccess(g.pVfs, zPath, flags, pResOut);
283 }
284 
285 /*
286 ** Populate buffer zOut with the full canonical pathname corresponding
287 ** to the pathname in zPath. zOut is guaranteed to point to a buffer
288 ** of at least (DEVSYM_MAX_PATHNAME+1) bytes.
289 */
290 static int devsymFullPathname(
291   sqlite3_vfs *pVfs,
292   const char *zPath,
293   int nOut,
294   char *zOut
295 ){
296   return sqlite3OsFullPathname(g.pVfs, zPath, nOut, zOut);
297 }
298 
299 #ifndef SQLITE_OMIT_LOAD_EXTENSION
300 /*
301 ** Open the dynamic library located at zPath and return a handle.
302 */
303 static void *devsymDlOpen(sqlite3_vfs *pVfs, const char *zPath){
304   return sqlite3OsDlOpen(g.pVfs, zPath);
305 }
306 
307 /*
308 ** Populate the buffer zErrMsg (size nByte bytes) with a human readable
309 ** utf-8 string describing the most recent error encountered associated
310 ** with dynamic libraries.
311 */
312 static void devsymDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
313   sqlite3OsDlError(g.pVfs, nByte, zErrMsg);
314 }
315 
316 /*
317 ** Return a pointer to the symbol zSymbol in the dynamic library pHandle.
318 */
319 static void (*devsymDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){
320   return sqlite3OsDlSym(g.pVfs, p, zSym);
321 }
322 
323 /*
324 ** Close the dynamic library handle pHandle.
325 */
326 static void devsymDlClose(sqlite3_vfs *pVfs, void *pHandle){
327   sqlite3OsDlClose(g.pVfs, pHandle);
328 }
329 #endif /* SQLITE_OMIT_LOAD_EXTENSION */
330 
331 /*
332 ** Populate the buffer pointed to by zBufOut with nByte bytes of
333 ** random data.
334 */
335 static int devsymRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
336   return sqlite3OsRandomness(g.pVfs, nByte, zBufOut);
337 }
338 
339 /*
340 ** Sleep for nMicro microseconds. Return the number of microseconds
341 ** actually slept.
342 */
343 static int devsymSleep(sqlite3_vfs *pVfs, int nMicro){
344   return sqlite3OsSleep(g.pVfs, nMicro);
345 }
346 
347 /*
348 ** Return the current time as a Julian Day number in *pTimeOut.
349 */
350 static int devsymCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
351   return sqlite3OsCurrentTime(g.pVfs, pTimeOut);
352 }
353 
354 
355 static int devsymShmOpen(
356   sqlite3_vfs *pVfs,
357   const char *zName,
358   sqlite3_shm **pp
359 ){
360   return g.pVfs->xShmOpen(g.pVfs, zName, pp);
361 }
362 static int devsymShmSize(sqlite3_shm *p, int reqSize, int *pNewSize){
363   return g.pVfs->xShmSize(p, reqSize, pNewSize);
364 }
365 static int devsymShmGet(
366   sqlite3_shm *p,
367   int reqMapSize,
368   int *pMapSize,
369   void **pp
370 ){
371   return g.pVfs->xShmGet(p, reqMapSize, pMapSize, pp);
372 }
373 static int devsymShmRelease(sqlite3_shm *p){
374   return g.pVfs->xShmRelease(p);
375 }
376 static int devsymShmLock(sqlite3_shm *p, int desiredLock, int *gotLock){
377   return g.pVfs->xShmLock(p, desiredLock, gotLock);
378 }
379 static int devsymShmClose(sqlite3_shm *p, int deleteFlag){
380   return g.pVfs->xShmClose(p, deleteFlag);
381 }
382 
383 /*
384 ** This procedure registers the devsym vfs with SQLite. If the argument is
385 ** true, the devsym vfs becomes the new default vfs. It is the only publicly
386 ** available function in this file.
387 */
388 void devsym_register(int iDeviceChar, int iSectorSize){
389   if( g.pVfs==0 ){
390     g.pVfs = sqlite3_vfs_find(0);
391     devsym_vfs.szOsFile += g.pVfs->szOsFile;
392     devsym_vfs.xShmOpen = (g.pVfs->xShmOpen ? devsymShmOpen : 0);
393     devsym_vfs.xShmSize = (g.pVfs->xShmSize ? devsymShmSize : 0);
394     devsym_vfs.xShmGet = (g.pVfs->xShmGet ? devsymShmGet : 0);
395     devsym_vfs.xShmRelease = (g.pVfs->xShmRelease ? devsymShmRelease : 0);
396     devsym_vfs.xShmLock = (g.pVfs->xShmLock ? devsymShmLock : 0);
397     devsym_vfs.xShmClose = (g.pVfs->xShmClose ? devsymShmClose : 0);
398     sqlite3_vfs_register(&devsym_vfs, 0);
399   }
400   if( iDeviceChar>=0 ){
401     g.iDeviceChar = iDeviceChar;
402   }else{
403     g.iDeviceChar = 0;
404   }
405   if( iSectorSize>=0 ){
406     g.iSectorSize = iSectorSize;
407   }else{
408     g.iSectorSize = 512;
409   }
410 }
411 
412 #endif
413