blob: 4249573aa1f629ea12d2c59db7790d521ae9e843 [file] [log] [blame]
danielk1977bf260972008-01-22 11:50:13 +00001/*
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
mlcreechfb80d202008-03-09 02:00:19 +000019#include "sqlite3.h"
danielk1977bf260972008-01-22 11:50:13 +000020#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
32typedef struct devsym_file devsym_file;
33struct devsym_file {
34 sqlite3_file base;
35 sqlite3_file *pReal;
36};
37
38/*
39** Method declarations for devsym_file.
40*/
41static int devsymClose(sqlite3_file*);
42static int devsymRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
43static int devsymWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst);
44static int devsymTruncate(sqlite3_file*, sqlite3_int64 size);
45static int devsymSync(sqlite3_file*, int flags);
46static int devsymFileSize(sqlite3_file*, sqlite3_int64 *pSize);
47static int devsymLock(sqlite3_file*, int);
48static int devsymUnlock(sqlite3_file*, int);
danielk1977861f7452008-06-05 11:39:11 +000049static int devsymCheckReservedLock(sqlite3_file*, int *);
danielk1977bf260972008-01-22 11:50:13 +000050static int devsymFileControl(sqlite3_file*, int op, void *pArg);
51static int devsymSectorSize(sqlite3_file*);
52static int devsymDeviceCharacteristics(sqlite3_file*);
53
54/*
55** Method declarations for devsym_vfs.
56*/
57static int devsymOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *);
58static int devsymDelete(sqlite3_vfs*, const char *zName, int syncDir);
danielk1977861f7452008-06-05 11:39:11 +000059static int devsymAccess(sqlite3_vfs*, const char *zName, int flags, int *);
danielk1977bf260972008-01-22 11:50:13 +000060static int devsymFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut);
shane75998ab2008-05-29 02:52:59 +000061#ifndef SQLITE_OMIT_LOAD_EXTENSION
danielk1977bf260972008-01-22 11:50:13 +000062static void *devsymDlOpen(sqlite3_vfs*, const char *zFilename);
63static void devsymDlError(sqlite3_vfs*, int nByte, char *zErrMsg);
drhec1724e2008-12-09 01:32:03 +000064static void (*devsymDlSym(sqlite3_vfs*,void*, const char *zSymbol))(void);
danielk1977bf260972008-01-22 11:50:13 +000065static void devsymDlClose(sqlite3_vfs*, void*);
shane75998ab2008-05-29 02:52:59 +000066#endif /* SQLITE_OMIT_LOAD_EXTENSION */
danielk1977bf260972008-01-22 11:50:13 +000067static int devsymRandomness(sqlite3_vfs*, int nByte, char *zOut);
68static int devsymSleep(sqlite3_vfs*, int microseconds);
69static int devsymCurrentTime(sqlite3_vfs*, double*);
70
71static sqlite3_vfs devsym_vfs = {
72 1, /* 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 */
danielk1977bf260972008-01-22 11:50:13 +000081 devsymFullPathname, /* xFullPathname */
shane75998ab2008-05-29 02:52:59 +000082#ifndef SQLITE_OMIT_LOAD_EXTENSION
danielk1977bf260972008-01-22 11:50:13 +000083 devsymDlOpen, /* xDlOpen */
84 devsymDlError, /* xDlError */
85 devsymDlSym, /* xDlSym */
86 devsymDlClose, /* xDlClose */
shane75998ab2008-05-29 02:52:59 +000087#else
88 0, /* xDlOpen */
89 0, /* xDlError */
90 0, /* xDlSym */
91 0, /* xDlClose */
92#endif /* SQLITE_OMIT_LOAD_EXTENSION */
danielk1977bf260972008-01-22 11:50:13 +000093 devsymRandomness, /* xRandomness */
94 devsymSleep, /* xSleep */
drhf2424c52010-04-26 00:04:55 +000095 devsymCurrentTime, /* xCurrentTime */
96 0, /* xShmOpen */
97 0, /* xShmSize */
98 0, /* xShmPush */
99 0, /* xShmPull */
100 0, /* xShmLock */
101 0, /* xShmClose */
102 0, /* xShmDelete */
103 0, /* xRename */
104 0 /* xCurrentTimeInt64 */
danielk1977bf260972008-01-22 11:50:13 +0000105};
106
107static sqlite3_io_methods devsym_io_methods = {
108 1, /* 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};
122
123struct DevsymGlobal {
124 sqlite3_vfs *pVfs;
125 int iDeviceChar;
126 int iSectorSize;
127};
128struct DevsymGlobal g = {0, 0, 512};
129
130/*
131** Close an devsym-file.
132*/
133static 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*/
141static 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*/
154static 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*/
167static 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*/
175static 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*/
183static 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*/
191static 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*/
199static 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*/
danielk1977861f7452008-06-05 11:39:11 +0000207static int devsymCheckReservedLock(sqlite3_file *pFile, int *pResOut){
danielk1977bf260972008-01-22 11:50:13 +0000208 devsym_file *p = (devsym_file *)pFile;
danielk1977861f7452008-06-05 11:39:11 +0000209 return sqlite3OsCheckReservedLock(p->pReal, pResOut);
danielk1977bf260972008-01-22 11:50:13 +0000210}
211
212/*
213** File control method. For custom operations on an devsym-file.
214*/
215static 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*/
223static int devsymSectorSize(sqlite3_file *pFile){
224 return g.iSectorSize;
225}
226
227/*
228** Return the device characteristic flags supported by an devsym-file.
229*/
230static int devsymDeviceCharacteristics(sqlite3_file *pFile){
231 return g.iDeviceChar;
232}
233
234/*
235** Open an devsym file handle.
236*/
237static int devsymOpen(
238 sqlite3_vfs *pVfs,
239 const char *zName,
240 sqlite3_file *pFile,
241 int flags,
242 int *pOutFlags
243){
danielk1977755339e2008-09-12 10:22:40 +0000244 int rc;
danielk1977bf260972008-01-22 11:50:13 +0000245 devsym_file *p = (devsym_file *)pFile;
danielk1977bf260972008-01-22 11:50:13 +0000246 p->pReal = (sqlite3_file *)&p[1];
danielk1977755339e2008-09-12 10:22:40 +0000247 rc = sqlite3OsOpen(g.pVfs, zName, p->pReal, flags, pOutFlags);
248 if( p->pReal->pMethods ){
249 pFile->pMethods = &devsym_io_methods;
250 }
251 return rc;
danielk1977bf260972008-01-22 11:50:13 +0000252}
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*/
259static 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*/
danielk1977861f7452008-06-05 11:39:11 +0000267static 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);
danielk1977bf260972008-01-22 11:50:13 +0000274}
275
276/*
danielk1977bf260972008-01-22 11:50:13 +0000277** 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*/
281static 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
shane75998ab2008-05-29 02:52:59 +0000290#ifndef SQLITE_OMIT_LOAD_EXTENSION
danielk1977bf260972008-01-22 11:50:13 +0000291/*
292** Open the dynamic library located at zPath and return a handle.
293*/
294static 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*/
303static 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*/
drhec1724e2008-12-09 01:32:03 +0000310static void (*devsymDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){
311 return sqlite3OsDlSym(g.pVfs, p, zSym);
danielk1977bf260972008-01-22 11:50:13 +0000312}
313
314/*
315** Close the dynamic library handle pHandle.
316*/
317static void devsymDlClose(sqlite3_vfs *pVfs, void *pHandle){
318 sqlite3OsDlClose(g.pVfs, pHandle);
319}
shane75998ab2008-05-29 02:52:59 +0000320#endif /* SQLITE_OMIT_LOAD_EXTENSION */
danielk1977bf260972008-01-22 11:50:13 +0000321
322/*
323** Populate the buffer pointed to by zBufOut with nByte bytes of
324** random data.
325*/
326static 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*/
334static 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*/
341static int devsymCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
342 return sqlite3OsCurrentTime(g.pVfs, pTimeOut);
343}
344
345/*
346** This procedure registers the devsym vfs with SQLite. If the argument is
347** true, the devsym vfs becomes the new default vfs. It is the only publicly
348** available function in this file.
349*/
350void devsym_register(int iDeviceChar, int iSectorSize){
351 if( g.pVfs==0 ){
352 g.pVfs = sqlite3_vfs_find(0);
353 devsym_vfs.szOsFile += g.pVfs->szOsFile;
354 sqlite3_vfs_register(&devsym_vfs, 0);
355 }
356 if( iDeviceChar>=0 ){
357 g.iDeviceChar = iDeviceChar;
drh47f18f72010-04-12 14:51:10 +0000358 }else{
359 g.iDeviceChar = 0;
danielk1977bf260972008-01-22 11:50:13 +0000360 }
361 if( iSectorSize>=0 ){
362 g.iSectorSize = iSectorSize;
drh47f18f72010-04-12 14:51:10 +0000363 }else{
364 g.iSectorSize = 512;
danielk1977bf260972008-01-22 11:50:13 +0000365 }
366}
367
368#endif