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