blob: d428e4dc60713e54ea96efc3a0bd3f5b0aa3810f [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).
danielk1977822a5162008-05-16 04:51:54 +000016**
drhec1724e2008-12-09 01:32:03 +000017** $Id: test_devsym.c,v 1.9 2008/12/09 01:32:03 drh Exp $
danielk1977bf260972008-01-22 11:50:13 +000018*/
19#if SQLITE_TEST /* This file is used for testing only */
20
mlcreechfb80d202008-03-09 02:00:19 +000021#include "sqlite3.h"
danielk1977bf260972008-01-22 11:50:13 +000022#include "sqliteInt.h"
23
24/*
25** Maximum pathname length supported by the devsym backend.
26*/
27#define DEVSYM_MAX_PATHNAME 512
28
29/*
30** Name used to identify this VFS.
31*/
32#define DEVSYM_VFS_NAME "devsym"
33
34typedef struct devsym_file devsym_file;
35struct devsym_file {
36 sqlite3_file base;
37 sqlite3_file *pReal;
38};
39
40/*
41** Method declarations for devsym_file.
42*/
43static int devsymClose(sqlite3_file*);
44static int devsymRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
45static int devsymWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst);
46static int devsymTruncate(sqlite3_file*, sqlite3_int64 size);
47static int devsymSync(sqlite3_file*, int flags);
48static int devsymFileSize(sqlite3_file*, sqlite3_int64 *pSize);
49static int devsymLock(sqlite3_file*, int);
50static int devsymUnlock(sqlite3_file*, int);
danielk1977861f7452008-06-05 11:39:11 +000051static int devsymCheckReservedLock(sqlite3_file*, int *);
danielk1977bf260972008-01-22 11:50:13 +000052static int devsymFileControl(sqlite3_file*, int op, void *pArg);
53static int devsymSectorSize(sqlite3_file*);
54static int devsymDeviceCharacteristics(sqlite3_file*);
55
56/*
57** Method declarations for devsym_vfs.
58*/
59static int devsymOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *);
60static int devsymDelete(sqlite3_vfs*, const char *zName, int syncDir);
danielk1977861f7452008-06-05 11:39:11 +000061static int devsymAccess(sqlite3_vfs*, const char *zName, int flags, int *);
danielk1977bf260972008-01-22 11:50:13 +000062static int devsymFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut);
shane75998ab2008-05-29 02:52:59 +000063#ifndef SQLITE_OMIT_LOAD_EXTENSION
danielk1977bf260972008-01-22 11:50:13 +000064static void *devsymDlOpen(sqlite3_vfs*, const char *zFilename);
65static void devsymDlError(sqlite3_vfs*, int nByte, char *zErrMsg);
drhec1724e2008-12-09 01:32:03 +000066static void (*devsymDlSym(sqlite3_vfs*,void*, const char *zSymbol))(void);
danielk1977bf260972008-01-22 11:50:13 +000067static void devsymDlClose(sqlite3_vfs*, void*);
shane75998ab2008-05-29 02:52:59 +000068#endif /* SQLITE_OMIT_LOAD_EXTENSION */
danielk1977bf260972008-01-22 11:50:13 +000069static int devsymRandomness(sqlite3_vfs*, int nByte, char *zOut);
70static int devsymSleep(sqlite3_vfs*, int microseconds);
71static int devsymCurrentTime(sqlite3_vfs*, double*);
72
73static sqlite3_vfs devsym_vfs = {
74 1, /* iVersion */
75 sizeof(devsym_file), /* szOsFile */
76 DEVSYM_MAX_PATHNAME, /* mxPathname */
77 0, /* pNext */
78 DEVSYM_VFS_NAME, /* zName */
79 0, /* pAppData */
80 devsymOpen, /* xOpen */
81 devsymDelete, /* xDelete */
82 devsymAccess, /* xAccess */
danielk1977bf260972008-01-22 11:50:13 +000083 devsymFullPathname, /* xFullPathname */
shane75998ab2008-05-29 02:52:59 +000084#ifndef SQLITE_OMIT_LOAD_EXTENSION
danielk1977bf260972008-01-22 11:50:13 +000085 devsymDlOpen, /* xDlOpen */
86 devsymDlError, /* xDlError */
87 devsymDlSym, /* xDlSym */
88 devsymDlClose, /* xDlClose */
shane75998ab2008-05-29 02:52:59 +000089#else
90 0, /* xDlOpen */
91 0, /* xDlError */
92 0, /* xDlSym */
93 0, /* xDlClose */
94#endif /* SQLITE_OMIT_LOAD_EXTENSION */
danielk1977bf260972008-01-22 11:50:13 +000095 devsymRandomness, /* xRandomness */
96 devsymSleep, /* xSleep */
97 devsymCurrentTime /* xCurrentTime */
98};
99
100static sqlite3_io_methods devsym_io_methods = {
101 1, /* iVersion */
102 devsymClose, /* xClose */
103 devsymRead, /* xRead */
104 devsymWrite, /* xWrite */
105 devsymTruncate, /* xTruncate */
106 devsymSync, /* xSync */
107 devsymFileSize, /* xFileSize */
108 devsymLock, /* xLock */
109 devsymUnlock, /* xUnlock */
110 devsymCheckReservedLock, /* xCheckReservedLock */
111 devsymFileControl, /* xFileControl */
112 devsymSectorSize, /* xSectorSize */
113 devsymDeviceCharacteristics /* xDeviceCharacteristics */
114};
115
116struct DevsymGlobal {
117 sqlite3_vfs *pVfs;
118 int iDeviceChar;
119 int iSectorSize;
120};
121struct DevsymGlobal g = {0, 0, 512};
122
123/*
124** Close an devsym-file.
125*/
126static int devsymClose(sqlite3_file *pFile){
127 devsym_file *p = (devsym_file *)pFile;
128 return sqlite3OsClose(p->pReal);
129}
130
131/*
132** Read data from an devsym-file.
133*/
134static int devsymRead(
135 sqlite3_file *pFile,
136 void *zBuf,
137 int iAmt,
138 sqlite_int64 iOfst
139){
140 devsym_file *p = (devsym_file *)pFile;
141 return sqlite3OsRead(p->pReal, zBuf, iAmt, iOfst);
142}
143
144/*
145** Write data to an devsym-file.
146*/
147static int devsymWrite(
148 sqlite3_file *pFile,
149 const void *zBuf,
150 int iAmt,
151 sqlite_int64 iOfst
152){
153 devsym_file *p = (devsym_file *)pFile;
154 return sqlite3OsWrite(p->pReal, zBuf, iAmt, iOfst);
155}
156
157/*
158** Truncate an devsym-file.
159*/
160static int devsymTruncate(sqlite3_file *pFile, sqlite_int64 size){
161 devsym_file *p = (devsym_file *)pFile;
162 return sqlite3OsTruncate(p->pReal, size);
163}
164
165/*
166** Sync an devsym-file.
167*/
168static int devsymSync(sqlite3_file *pFile, int flags){
169 devsym_file *p = (devsym_file *)pFile;
170 return sqlite3OsSync(p->pReal, flags);
171}
172
173/*
174** Return the current file-size of an devsym-file.
175*/
176static int devsymFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
177 devsym_file *p = (devsym_file *)pFile;
178 return sqlite3OsFileSize(p->pReal, pSize);
179}
180
181/*
182** Lock an devsym-file.
183*/
184static int devsymLock(sqlite3_file *pFile, int eLock){
185 devsym_file *p = (devsym_file *)pFile;
186 return sqlite3OsLock(p->pReal, eLock);
187}
188
189/*
190** Unlock an devsym-file.
191*/
192static int devsymUnlock(sqlite3_file *pFile, int eLock){
193 devsym_file *p = (devsym_file *)pFile;
194 return sqlite3OsUnlock(p->pReal, eLock);
195}
196
197/*
198** Check if another file-handle holds a RESERVED lock on an devsym-file.
199*/
danielk1977861f7452008-06-05 11:39:11 +0000200static int devsymCheckReservedLock(sqlite3_file *pFile, int *pResOut){
danielk1977bf260972008-01-22 11:50:13 +0000201 devsym_file *p = (devsym_file *)pFile;
danielk1977861f7452008-06-05 11:39:11 +0000202 return sqlite3OsCheckReservedLock(p->pReal, pResOut);
danielk1977bf260972008-01-22 11:50:13 +0000203}
204
205/*
206** File control method. For custom operations on an devsym-file.
207*/
208static int devsymFileControl(sqlite3_file *pFile, int op, void *pArg){
209 devsym_file *p = (devsym_file *)pFile;
210 return sqlite3OsFileControl(p->pReal, op, pArg);
211}
212
213/*
214** Return the sector-size in bytes for an devsym-file.
215*/
216static int devsymSectorSize(sqlite3_file *pFile){
217 return g.iSectorSize;
218}
219
220/*
221** Return the device characteristic flags supported by an devsym-file.
222*/
223static int devsymDeviceCharacteristics(sqlite3_file *pFile){
224 return g.iDeviceChar;
225}
226
227/*
228** Open an devsym file handle.
229*/
230static int devsymOpen(
231 sqlite3_vfs *pVfs,
232 const char *zName,
233 sqlite3_file *pFile,
234 int flags,
235 int *pOutFlags
236){
danielk1977755339e2008-09-12 10:22:40 +0000237 int rc;
danielk1977bf260972008-01-22 11:50:13 +0000238 devsym_file *p = (devsym_file *)pFile;
danielk1977bf260972008-01-22 11:50:13 +0000239 p->pReal = (sqlite3_file *)&p[1];
danielk1977755339e2008-09-12 10:22:40 +0000240 rc = sqlite3OsOpen(g.pVfs, zName, p->pReal, flags, pOutFlags);
241 if( p->pReal->pMethods ){
242 pFile->pMethods = &devsym_io_methods;
243 }
244 return rc;
danielk1977bf260972008-01-22 11:50:13 +0000245}
246
247/*
248** Delete the file located at zPath. If the dirSync argument is true,
249** ensure the file-system modifications are synced to disk before
250** returning.
251*/
252static int devsymDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
253 return sqlite3OsDelete(g.pVfs, zPath, dirSync);
254}
255
256/*
257** Test for access permissions. Return true if the requested permission
258** is available, or false otherwise.
259*/
danielk1977861f7452008-06-05 11:39:11 +0000260static int devsymAccess(
261 sqlite3_vfs *pVfs,
262 const char *zPath,
263 int flags,
264 int *pResOut
265){
266 return sqlite3OsAccess(g.pVfs, zPath, flags, pResOut);
danielk1977bf260972008-01-22 11:50:13 +0000267}
268
269/*
danielk1977bf260972008-01-22 11:50:13 +0000270** Populate buffer zOut with the full canonical pathname corresponding
271** to the pathname in zPath. zOut is guaranteed to point to a buffer
272** of at least (DEVSYM_MAX_PATHNAME+1) bytes.
273*/
274static int devsymFullPathname(
275 sqlite3_vfs *pVfs,
276 const char *zPath,
277 int nOut,
278 char *zOut
279){
280 return sqlite3OsFullPathname(g.pVfs, zPath, nOut, zOut);
281}
282
shane75998ab2008-05-29 02:52:59 +0000283#ifndef SQLITE_OMIT_LOAD_EXTENSION
danielk1977bf260972008-01-22 11:50:13 +0000284/*
285** Open the dynamic library located at zPath and return a handle.
286*/
287static void *devsymDlOpen(sqlite3_vfs *pVfs, const char *zPath){
288 return sqlite3OsDlOpen(g.pVfs, zPath);
289}
290
291/*
292** Populate the buffer zErrMsg (size nByte bytes) with a human readable
293** utf-8 string describing the most recent error encountered associated
294** with dynamic libraries.
295*/
296static void devsymDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
297 sqlite3OsDlError(g.pVfs, nByte, zErrMsg);
298}
299
300/*
301** Return a pointer to the symbol zSymbol in the dynamic library pHandle.
302*/
drhec1724e2008-12-09 01:32:03 +0000303static void (*devsymDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){
304 return sqlite3OsDlSym(g.pVfs, p, zSym);
danielk1977bf260972008-01-22 11:50:13 +0000305}
306
307/*
308** Close the dynamic library handle pHandle.
309*/
310static void devsymDlClose(sqlite3_vfs *pVfs, void *pHandle){
311 sqlite3OsDlClose(g.pVfs, pHandle);
312}
shane75998ab2008-05-29 02:52:59 +0000313#endif /* SQLITE_OMIT_LOAD_EXTENSION */
danielk1977bf260972008-01-22 11:50:13 +0000314
315/*
316** Populate the buffer pointed to by zBufOut with nByte bytes of
317** random data.
318*/
319static int devsymRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
320 return sqlite3OsRandomness(g.pVfs, nByte, zBufOut);
321}
322
323/*
324** Sleep for nMicro microseconds. Return the number of microseconds
325** actually slept.
326*/
327static int devsymSleep(sqlite3_vfs *pVfs, int nMicro){
328 return sqlite3OsSleep(g.pVfs, nMicro);
329}
330
331/*
332** Return the current time as a Julian Day number in *pTimeOut.
333*/
334static int devsymCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
335 return sqlite3OsCurrentTime(g.pVfs, pTimeOut);
336}
337
338/*
339** This procedure registers the devsym vfs with SQLite. If the argument is
340** true, the devsym vfs becomes the new default vfs. It is the only publicly
341** available function in this file.
342*/
343void devsym_register(int iDeviceChar, int iSectorSize){
344 if( g.pVfs==0 ){
345 g.pVfs = sqlite3_vfs_find(0);
346 devsym_vfs.szOsFile += g.pVfs->szOsFile;
347 sqlite3_vfs_register(&devsym_vfs, 0);
348 }
349 if( iDeviceChar>=0 ){
350 g.iDeviceChar = iDeviceChar;
351 }
352 if( iSectorSize>=0 ){
353 g.iSectorSize = iSectorSize;
354 }
355}
356
357#endif