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