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