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