blob: 9617e63af30139d796107f604898e34095ed0f8f [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 */
95 devsymCurrentTime /* xCurrentTime */
96};
97
98static sqlite3_io_methods devsym_io_methods = {
99 1, /* iVersion */
100 devsymClose, /* xClose */
101 devsymRead, /* xRead */
102 devsymWrite, /* xWrite */
103 devsymTruncate, /* xTruncate */
104 devsymSync, /* xSync */
105 devsymFileSize, /* xFileSize */
106 devsymLock, /* xLock */
107 devsymUnlock, /* xUnlock */
108 devsymCheckReservedLock, /* xCheckReservedLock */
109 devsymFileControl, /* xFileControl */
110 devsymSectorSize, /* xSectorSize */
111 devsymDeviceCharacteristics /* xDeviceCharacteristics */
112};
113
114struct DevsymGlobal {
115 sqlite3_vfs *pVfs;
116 int iDeviceChar;
117 int iSectorSize;
118};
119struct DevsymGlobal g = {0, 0, 512};
120
121/*
122** Close an devsym-file.
123*/
124static int devsymClose(sqlite3_file *pFile){
125 devsym_file *p = (devsym_file *)pFile;
126 return sqlite3OsClose(p->pReal);
127}
128
129/*
130** Read data from an devsym-file.
131*/
132static int devsymRead(
133 sqlite3_file *pFile,
134 void *zBuf,
135 int iAmt,
136 sqlite_int64 iOfst
137){
138 devsym_file *p = (devsym_file *)pFile;
139 return sqlite3OsRead(p->pReal, zBuf, iAmt, iOfst);
140}
141
142/*
143** Write data to an devsym-file.
144*/
145static int devsymWrite(
146 sqlite3_file *pFile,
147 const void *zBuf,
148 int iAmt,
149 sqlite_int64 iOfst
150){
151 devsym_file *p = (devsym_file *)pFile;
152 return sqlite3OsWrite(p->pReal, zBuf, iAmt, iOfst);
153}
154
155/*
156** Truncate an devsym-file.
157*/
158static int devsymTruncate(sqlite3_file *pFile, sqlite_int64 size){
159 devsym_file *p = (devsym_file *)pFile;
160 return sqlite3OsTruncate(p->pReal, size);
161}
162
163/*
164** Sync an devsym-file.
165*/
166static int devsymSync(sqlite3_file *pFile, int flags){
167 devsym_file *p = (devsym_file *)pFile;
168 return sqlite3OsSync(p->pReal, flags);
169}
170
171/*
172** Return the current file-size of an devsym-file.
173*/
174static int devsymFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
175 devsym_file *p = (devsym_file *)pFile;
176 return sqlite3OsFileSize(p->pReal, pSize);
177}
178
179/*
180** Lock an devsym-file.
181*/
182static int devsymLock(sqlite3_file *pFile, int eLock){
183 devsym_file *p = (devsym_file *)pFile;
184 return sqlite3OsLock(p->pReal, eLock);
185}
186
187/*
188** Unlock an devsym-file.
189*/
190static int devsymUnlock(sqlite3_file *pFile, int eLock){
191 devsym_file *p = (devsym_file *)pFile;
192 return sqlite3OsUnlock(p->pReal, eLock);
193}
194
195/*
196** Check if another file-handle holds a RESERVED lock on an devsym-file.
197*/
danielk1977861f7452008-06-05 11:39:11 +0000198static int devsymCheckReservedLock(sqlite3_file *pFile, int *pResOut){
danielk1977bf260972008-01-22 11:50:13 +0000199 devsym_file *p = (devsym_file *)pFile;
danielk1977861f7452008-06-05 11:39:11 +0000200 return sqlite3OsCheckReservedLock(p->pReal, pResOut);
danielk1977bf260972008-01-22 11:50:13 +0000201}
202
203/*
204** File control method. For custom operations on an devsym-file.
205*/
206static int devsymFileControl(sqlite3_file *pFile, int op, void *pArg){
207 devsym_file *p = (devsym_file *)pFile;
208 return sqlite3OsFileControl(p->pReal, op, pArg);
209}
210
211/*
212** Return the sector-size in bytes for an devsym-file.
213*/
214static int devsymSectorSize(sqlite3_file *pFile){
215 return g.iSectorSize;
216}
217
218/*
219** Return the device characteristic flags supported by an devsym-file.
220*/
221static int devsymDeviceCharacteristics(sqlite3_file *pFile){
222 return g.iDeviceChar;
223}
224
225/*
226** Open an devsym file handle.
227*/
228static int devsymOpen(
229 sqlite3_vfs *pVfs,
230 const char *zName,
231 sqlite3_file *pFile,
232 int flags,
233 int *pOutFlags
234){
danielk1977755339e2008-09-12 10:22:40 +0000235 int rc;
danielk1977bf260972008-01-22 11:50:13 +0000236 devsym_file *p = (devsym_file *)pFile;
danielk1977bf260972008-01-22 11:50:13 +0000237 p->pReal = (sqlite3_file *)&p[1];
danielk1977755339e2008-09-12 10:22:40 +0000238 rc = sqlite3OsOpen(g.pVfs, zName, p->pReal, flags, pOutFlags);
239 if( p->pReal->pMethods ){
240 pFile->pMethods = &devsym_io_methods;
241 }
242 return rc;
danielk1977bf260972008-01-22 11:50:13 +0000243}
244
245/*
246** Delete the file located at zPath. If the dirSync argument is true,
247** ensure the file-system modifications are synced to disk before
248** returning.
249*/
250static int devsymDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
251 return sqlite3OsDelete(g.pVfs, zPath, dirSync);
252}
253
254/*
255** Test for access permissions. Return true if the requested permission
256** is available, or false otherwise.
257*/
danielk1977861f7452008-06-05 11:39:11 +0000258static int devsymAccess(
259 sqlite3_vfs *pVfs,
260 const char *zPath,
261 int flags,
262 int *pResOut
263){
264 return sqlite3OsAccess(g.pVfs, zPath, flags, pResOut);
danielk1977bf260972008-01-22 11:50:13 +0000265}
266
267/*
danielk1977bf260972008-01-22 11:50:13 +0000268** Populate buffer zOut with the full canonical pathname corresponding
269** to the pathname in zPath. zOut is guaranteed to point to a buffer
270** of at least (DEVSYM_MAX_PATHNAME+1) bytes.
271*/
272static int devsymFullPathname(
273 sqlite3_vfs *pVfs,
274 const char *zPath,
275 int nOut,
276 char *zOut
277){
278 return sqlite3OsFullPathname(g.pVfs, zPath, nOut, zOut);
279}
280
shane75998ab2008-05-29 02:52:59 +0000281#ifndef SQLITE_OMIT_LOAD_EXTENSION
danielk1977bf260972008-01-22 11:50:13 +0000282/*
283** Open the dynamic library located at zPath and return a handle.
284*/
285static void *devsymDlOpen(sqlite3_vfs *pVfs, const char *zPath){
286 return sqlite3OsDlOpen(g.pVfs, zPath);
287}
288
289/*
290** Populate the buffer zErrMsg (size nByte bytes) with a human readable
291** utf-8 string describing the most recent error encountered associated
292** with dynamic libraries.
293*/
294static void devsymDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
295 sqlite3OsDlError(g.pVfs, nByte, zErrMsg);
296}
297
298/*
299** Return a pointer to the symbol zSymbol in the dynamic library pHandle.
300*/
drhec1724e2008-12-09 01:32:03 +0000301static void (*devsymDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){
302 return sqlite3OsDlSym(g.pVfs, p, zSym);
danielk1977bf260972008-01-22 11:50:13 +0000303}
304
305/*
306** Close the dynamic library handle pHandle.
307*/
308static void devsymDlClose(sqlite3_vfs *pVfs, void *pHandle){
309 sqlite3OsDlClose(g.pVfs, pHandle);
310}
shane75998ab2008-05-29 02:52:59 +0000311#endif /* SQLITE_OMIT_LOAD_EXTENSION */
danielk1977bf260972008-01-22 11:50:13 +0000312
313/*
314** Populate the buffer pointed to by zBufOut with nByte bytes of
315** random data.
316*/
317static int devsymRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
318 return sqlite3OsRandomness(g.pVfs, nByte, zBufOut);
319}
320
321/*
322** Sleep for nMicro microseconds. Return the number of microseconds
323** actually slept.
324*/
325static int devsymSleep(sqlite3_vfs *pVfs, int nMicro){
326 return sqlite3OsSleep(g.pVfs, nMicro);
327}
328
329/*
330** Return the current time as a Julian Day number in *pTimeOut.
331*/
332static int devsymCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
333 return sqlite3OsCurrentTime(g.pVfs, pTimeOut);
334}
335
336/*
337** This procedure registers the devsym vfs with SQLite. If the argument is
338** true, the devsym vfs becomes the new default vfs. It is the only publicly
339** available function in this file.
340*/
341void devsym_register(int iDeviceChar, int iSectorSize){
342 if( g.pVfs==0 ){
343 g.pVfs = sqlite3_vfs_find(0);
344 devsym_vfs.szOsFile += g.pVfs->szOsFile;
345 sqlite3_vfs_register(&devsym_vfs, 0);
346 }
347 if( iDeviceChar>=0 ){
348 g.iDeviceChar = iDeviceChar;
drh47f18f72010-04-12 14:51:10 +0000349 }else{
350 g.iDeviceChar = 0;
danielk1977bf260972008-01-22 11:50:13 +0000351 }
352 if( iSectorSize>=0 ){
353 g.iSectorSize = iSectorSize;
drh47f18f72010-04-12 14:51:10 +0000354 }else{
355 g.iSectorSize = 512;
danielk1977bf260972008-01-22 11:50:13 +0000356 }
357}
358
359#endif