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