aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/sqlite/win32/os.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rwxr-xr-xlibraries/sqlite/win32/os.c282
1 files changed, 282 insertions, 0 deletions
diff --git a/libraries/sqlite/win32/os.c b/libraries/sqlite/win32/os.c
new file mode 100755
index 0000000..3b6ca7b
--- /dev/null
+++ b/libraries/sqlite/win32/os.c
@@ -0,0 +1,282 @@
1 /*
2** 2005 November 29
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 OS interface code that is common to all
14** architectures.
15*/
16#define _SQLITE_OS_C_ 1
17#include "sqliteInt.h"
18#undef _SQLITE_OS_C_
19
20/*
21** The default SQLite sqlite3_vfs implementations do not allocate
22** memory (actually, os_unix.c allocates a small amount of memory
23** from within OsOpen()), but some third-party implementations may.
24** So we test the effects of a malloc() failing and the sqlite3OsXXX()
25** function returning SQLITE_IOERR_NOMEM using the DO_OS_MALLOC_TEST macro.
26**
27** The following functions are instrumented for malloc() failure
28** testing:
29**
30** sqlite3OsOpen()
31** sqlite3OsRead()
32** sqlite3OsWrite()
33** sqlite3OsSync()
34** sqlite3OsLock()
35**
36*/
37#ifdef SQLITE_TEST
38 #define DO_OS_MALLOC_TEST if (1) { \
39 void *pTstAlloc = sqlite3_malloc(10); \
40 if (!pTstAlloc) return SQLITE_IOERR_NOMEM; \
41 sqlite3_free(pTstAlloc); \
42 }
43#else
44 #define DO_OS_MALLOC_TEST
45#endif
46
47/*
48** The following routines are convenience wrappers around methods
49** of the sqlite3_file object. This is mostly just syntactic sugar. All
50** of this would be completely automatic if SQLite were coded using
51** C++ instead of plain old C.
52*/
53int sqlite3OsClose(sqlite3_file *pId){
54 int rc = SQLITE_OK;
55 if( pId->pMethods ){
56 rc = pId->pMethods->xClose(pId);
57 pId->pMethods = 0;
58 }
59 return rc;
60}
61int sqlite3OsRead(sqlite3_file *id, void *pBuf, int amt, i64 offset){
62 DO_OS_MALLOC_TEST;
63 return id->pMethods->xRead(id, pBuf, amt, offset);
64}
65int sqlite3OsWrite(sqlite3_file *id, const void *pBuf, int amt, i64 offset){
66 DO_OS_MALLOC_TEST;
67 return id->pMethods->xWrite(id, pBuf, amt, offset);
68}
69int sqlite3OsTruncate(sqlite3_file *id, i64 size){
70 return id->pMethods->xTruncate(id, size);
71}
72int sqlite3OsSync(sqlite3_file *id, int flags){
73 DO_OS_MALLOC_TEST;
74 return id->pMethods->xSync(id, flags);
75}
76int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){
77 return id->pMethods->xFileSize(id, pSize);
78}
79int sqlite3OsLock(sqlite3_file *id, int lockType){
80 DO_OS_MALLOC_TEST;
81 return id->pMethods->xLock(id, lockType);
82}
83int sqlite3OsUnlock(sqlite3_file *id, int lockType){
84 return id->pMethods->xUnlock(id, lockType);
85}
86int sqlite3OsCheckReservedLock(sqlite3_file *id){
87 return id->pMethods->xCheckReservedLock(id);
88}
89int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){
90 return id->pMethods->xFileControl(id,op,pArg);
91}
92
93#ifdef SQLITE_TEST
94 /* The following two variables are used to override the values returned
95 ** by the xSectorSize() and xDeviceCharacteristics() vfs methods for
96 ** testing purposes. They are usually set by a test command implemented
97 ** in test6.c.
98 */
99 int sqlite3_test_sector_size = 0;
100 int sqlite3_test_device_characteristics = 0;
101 int sqlite3OsDeviceCharacteristics(sqlite3_file *id){
102 int dc = id->pMethods->xDeviceCharacteristics(id);
103 return dc | sqlite3_test_device_characteristics;
104 }
105 int sqlite3OsSectorSize(sqlite3_file *id){
106 if( sqlite3_test_sector_size==0 ){
107 int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize;
108 return (xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE);
109 }
110 return sqlite3_test_sector_size;
111 }
112#else
113 int sqlite3OsSectorSize(sqlite3_file *id){
114 int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize;
115 return (xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE);
116 }
117 int sqlite3OsDeviceCharacteristics(sqlite3_file *id){
118 return id->pMethods->xDeviceCharacteristics(id);
119 }
120#endif
121
122/*
123** The next group of routines are convenience wrappers around the
124** VFS methods.
125*/
126int sqlite3OsOpen(
127 sqlite3_vfs *pVfs,
128 const char *zPath,
129 sqlite3_file *pFile,
130 int flags,
131 int *pFlagsOut
132){
133 DO_OS_MALLOC_TEST;
134 return pVfs->xOpen(pVfs, zPath, pFile, flags, pFlagsOut);
135}
136int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
137 return pVfs->xDelete(pVfs, zPath, dirSync);
138}
139int sqlite3OsAccess(sqlite3_vfs *pVfs, const char *zPath, int flags){
140 return pVfs->xAccess(pVfs, zPath, flags);
141}
142int sqlite3OsGetTempname(sqlite3_vfs *pVfs, int nBufOut, char *zBufOut){
143 return pVfs->xGetTempname(pVfs, nBufOut, zBufOut);
144}
145int sqlite3OsFullPathname(
146 sqlite3_vfs *pVfs,
147 const char *zPath,
148 int nPathOut,
149 char *zPathOut
150){
151 return pVfs->xFullPathname(pVfs, zPath, nPathOut, zPathOut);
152}
153void *sqlite3OsDlOpen(sqlite3_vfs *pVfs, const char *zPath){
154 return pVfs->xDlOpen(pVfs, zPath);
155}
156void sqlite3OsDlError(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
157 pVfs->xDlError(pVfs, nByte, zBufOut);
158}
159void *sqlite3OsDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){
160 return pVfs->xDlSym(pVfs, pHandle, zSymbol);
161}
162void sqlite3OsDlClose(sqlite3_vfs *pVfs, void *pHandle){
163 pVfs->xDlClose(pVfs, pHandle);
164}
165int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
166 return pVfs->xRandomness(pVfs, nByte, zBufOut);
167}
168int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){
169 return pVfs->xSleep(pVfs, nMicro);
170}
171int sqlite3OsCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
172 return pVfs->xCurrentTime(pVfs, pTimeOut);
173}
174
175int sqlite3OsOpenMalloc(
176 sqlite3_vfs *pVfs,
177 const char *zFile,
178 sqlite3_file **ppFile,
179 int flags,
180 int *pOutFlags
181){
182 int rc = SQLITE_NOMEM;
183 sqlite3_file *pFile;
184 pFile = (sqlite3_file *)sqlite3_malloc(pVfs->szOsFile);
185 if( pFile ){
186 rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags);
187 if( rc!=SQLITE_OK ){
188 sqlite3_free(pFile);
189 }else{
190 *ppFile = pFile;
191 }
192 }
193 return rc;
194}
195int sqlite3OsCloseFree(sqlite3_file *pFile){
196 int rc = SQLITE_OK;
197 if( pFile ){
198 rc = sqlite3OsClose(pFile);
199 sqlite3_free(pFile);
200 }
201 return rc;
202}
203
204/*
205** The list of all registered VFS implementations. This list is
206** initialized to the single VFS returned by sqlite3OsDefaultVfs()
207** upon the first call to sqlite3_vfs_find().
208*/
209static sqlite3_vfs *vfsList = 0;
210
211/*
212** Locate a VFS by name. If no name is given, simply return the
213** first VFS on the list.
214*/
215sqlite3_vfs *sqlite3_vfs_find(const char *zVfs){
216 sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
217 sqlite3_vfs *pVfs;
218 static int isInit = 0;
219 sqlite3_mutex_enter(mutex);
220 if( !isInit ){
221 vfsList = sqlite3OsDefaultVfs();
222 isInit = 1;
223 }
224 for(pVfs = vfsList; pVfs; pVfs=pVfs->pNext){
225 if( zVfs==0 ) break;
226 if( strcmp(zVfs, pVfs->zName)==0 ) break;
227 }
228 sqlite3_mutex_leave(mutex);
229 return pVfs;
230}
231
232/*
233** Unlink a VFS from the linked list
234*/
235static void vfsUnlink(sqlite3_vfs *pVfs){
236 assert( sqlite3_mutex_held(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)) );
237 if( vfsList==pVfs ){
238 vfsList = pVfs->pNext;
239 }else{
240 sqlite3_vfs *p = vfsList;
241 while( p->pNext && p->pNext!=pVfs ){
242 p = p->pNext;
243 }
244 if( p->pNext==pVfs ){
245 p->pNext = pVfs->pNext;
246 }
247 }
248}
249
250/*
251** Register a VFS with the system. It is harmless to register the same
252** VFS multiple times. The new VFS becomes the default if makeDflt is
253** true.
254*/
255int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
256 sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
257 sqlite3_vfs_find(0); /* Make sure we are initialized */
258 sqlite3_mutex_enter(mutex);
259 vfsUnlink(pVfs);
260 if( makeDflt || vfsList==0 ){
261 pVfs->pNext = vfsList;
262 vfsList = pVfs;
263 }else{
264 pVfs->pNext = vfsList->pNext;
265 vfsList->pNext = pVfs;
266 }
267 assert(vfsList);
268 sqlite3_mutex_leave(mutex);
269 return SQLITE_OK;
270}
271
272/*
273** Unregister a VFS so that it is no longer accessible.
274*/
275int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){
276 sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
277 sqlite3_mutex_enter(mutex);
278 vfsUnlink(pVfs);
279 assert(vfsList);
280 sqlite3_mutex_leave(mutex);
281 return SQLITE_OK;
282}