diff options
Diffstat (limited to 'libraries/sqlite/win32/os.c')
-rwxr-xr-x | libraries/sqlite/win32/os.c | 282 |
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 | */ | ||
53 | int 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 | } | ||
61 | int 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 | } | ||
65 | int 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 | } | ||
69 | int sqlite3OsTruncate(sqlite3_file *id, i64 size){ | ||
70 | return id->pMethods->xTruncate(id, size); | ||
71 | } | ||
72 | int sqlite3OsSync(sqlite3_file *id, int flags){ | ||
73 | DO_OS_MALLOC_TEST; | ||
74 | return id->pMethods->xSync(id, flags); | ||
75 | } | ||
76 | int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){ | ||
77 | return id->pMethods->xFileSize(id, pSize); | ||
78 | } | ||
79 | int sqlite3OsLock(sqlite3_file *id, int lockType){ | ||
80 | DO_OS_MALLOC_TEST; | ||
81 | return id->pMethods->xLock(id, lockType); | ||
82 | } | ||
83 | int sqlite3OsUnlock(sqlite3_file *id, int lockType){ | ||
84 | return id->pMethods->xUnlock(id, lockType); | ||
85 | } | ||
86 | int sqlite3OsCheckReservedLock(sqlite3_file *id){ | ||
87 | return id->pMethods->xCheckReservedLock(id); | ||
88 | } | ||
89 | int 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 | */ | ||
126 | int 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 | } | ||
136 | int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ | ||
137 | return pVfs->xDelete(pVfs, zPath, dirSync); | ||
138 | } | ||
139 | int sqlite3OsAccess(sqlite3_vfs *pVfs, const char *zPath, int flags){ | ||
140 | return pVfs->xAccess(pVfs, zPath, flags); | ||
141 | } | ||
142 | int sqlite3OsGetTempname(sqlite3_vfs *pVfs, int nBufOut, char *zBufOut){ | ||
143 | return pVfs->xGetTempname(pVfs, nBufOut, zBufOut); | ||
144 | } | ||
145 | int 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 | } | ||
153 | void *sqlite3OsDlOpen(sqlite3_vfs *pVfs, const char *zPath){ | ||
154 | return pVfs->xDlOpen(pVfs, zPath); | ||
155 | } | ||
156 | void sqlite3OsDlError(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ | ||
157 | pVfs->xDlError(pVfs, nByte, zBufOut); | ||
158 | } | ||
159 | void *sqlite3OsDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){ | ||
160 | return pVfs->xDlSym(pVfs, pHandle, zSymbol); | ||
161 | } | ||
162 | void sqlite3OsDlClose(sqlite3_vfs *pVfs, void *pHandle){ | ||
163 | pVfs->xDlClose(pVfs, pHandle); | ||
164 | } | ||
165 | int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ | ||
166 | return pVfs->xRandomness(pVfs, nByte, zBufOut); | ||
167 | } | ||
168 | int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){ | ||
169 | return pVfs->xSleep(pVfs, nMicro); | ||
170 | } | ||
171 | int sqlite3OsCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){ | ||
172 | return pVfs->xCurrentTime(pVfs, pTimeOut); | ||
173 | } | ||
174 | |||
175 | int 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 | } | ||
195 | int 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 | */ | ||
209 | static 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 | */ | ||
215 | sqlite3_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 | */ | ||
235 | static 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 | */ | ||
255 | int 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 | */ | ||
275 | int 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 | } | ||