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