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