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