Annotation of embedaddon/sqlite3/src/os.c, revision 1.1.1.1
1.1 misho 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: ** sqlite3OsRead()
31: ** sqlite3OsWrite()
32: ** sqlite3OsSync()
33: ** sqlite3OsFileSize()
34: ** sqlite3OsLock()
35: ** sqlite3OsCheckReservedLock()
36: ** sqlite3OsFileControl()
37: ** sqlite3OsShmMap()
38: ** sqlite3OsOpen()
39: ** sqlite3OsDelete()
40: ** sqlite3OsAccess()
41: ** sqlite3OsFullPathname()
42: **
43: */
44: #if defined(SQLITE_TEST)
45: int sqlite3_memdebug_vfs_oom_test = 1;
46: #define DO_OS_MALLOC_TEST(x) \
47: if (sqlite3_memdebug_vfs_oom_test && (!x || !sqlite3IsMemJournal(x))) { \
48: void *pTstAlloc = sqlite3Malloc(10); \
49: if (!pTstAlloc) return SQLITE_IOERR_NOMEM; \
50: sqlite3_free(pTstAlloc); \
51: }
52: #else
53: #define DO_OS_MALLOC_TEST(x)
54: #endif
55:
56: /*
57: ** The following routines are convenience wrappers around methods
58: ** of the sqlite3_file object. This is mostly just syntactic sugar. All
59: ** of this would be completely automatic if SQLite were coded using
60: ** C++ instead of plain old C.
61: */
62: int sqlite3OsClose(sqlite3_file *pId){
63: int rc = SQLITE_OK;
64: if( pId->pMethods ){
65: rc = pId->pMethods->xClose(pId);
66: pId->pMethods = 0;
67: }
68: return rc;
69: }
70: int sqlite3OsRead(sqlite3_file *id, void *pBuf, int amt, i64 offset){
71: DO_OS_MALLOC_TEST(id);
72: return id->pMethods->xRead(id, pBuf, amt, offset);
73: }
74: int sqlite3OsWrite(sqlite3_file *id, const void *pBuf, int amt, i64 offset){
75: DO_OS_MALLOC_TEST(id);
76: return id->pMethods->xWrite(id, pBuf, amt, offset);
77: }
78: int sqlite3OsTruncate(sqlite3_file *id, i64 size){
79: return id->pMethods->xTruncate(id, size);
80: }
81: int sqlite3OsSync(sqlite3_file *id, int flags){
82: DO_OS_MALLOC_TEST(id);
83: return id->pMethods->xSync(id, flags);
84: }
85: int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){
86: DO_OS_MALLOC_TEST(id);
87: return id->pMethods->xFileSize(id, pSize);
88: }
89: int sqlite3OsLock(sqlite3_file *id, int lockType){
90: DO_OS_MALLOC_TEST(id);
91: return id->pMethods->xLock(id, lockType);
92: }
93: int sqlite3OsUnlock(sqlite3_file *id, int lockType){
94: return id->pMethods->xUnlock(id, lockType);
95: }
96: int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut){
97: DO_OS_MALLOC_TEST(id);
98: return id->pMethods->xCheckReservedLock(id, pResOut);
99: }
100:
101: /*
102: ** Use sqlite3OsFileControl() when we are doing something that might fail
103: ** and we need to know about the failures. Use sqlite3OsFileControlHint()
104: ** when simply tossing information over the wall to the VFS and we do not
105: ** really care if the VFS receives and understands the information since it
106: ** is only a hint and can be safely ignored. The sqlite3OsFileControlHint()
107: ** routine has no return value since the return value would be meaningless.
108: */
109: int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){
110: DO_OS_MALLOC_TEST(id);
111: return id->pMethods->xFileControl(id, op, pArg);
112: }
113: void sqlite3OsFileControlHint(sqlite3_file *id, int op, void *pArg){
114: (void)id->pMethods->xFileControl(id, op, pArg);
115: }
116:
117: int sqlite3OsSectorSize(sqlite3_file *id){
118: int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize;
119: return (xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE);
120: }
121: int sqlite3OsDeviceCharacteristics(sqlite3_file *id){
122: return id->pMethods->xDeviceCharacteristics(id);
123: }
124: int sqlite3OsShmLock(sqlite3_file *id, int offset, int n, int flags){
125: return id->pMethods->xShmLock(id, offset, n, flags);
126: }
127: void sqlite3OsShmBarrier(sqlite3_file *id){
128: id->pMethods->xShmBarrier(id);
129: }
130: int sqlite3OsShmUnmap(sqlite3_file *id, int deleteFlag){
131: return id->pMethods->xShmUnmap(id, deleteFlag);
132: }
133: int sqlite3OsShmMap(
134: sqlite3_file *id, /* Database file handle */
135: int iPage,
136: int pgsz,
137: int bExtend, /* True to extend file if necessary */
138: void volatile **pp /* OUT: Pointer to mapping */
139: ){
140: DO_OS_MALLOC_TEST(id);
141: return id->pMethods->xShmMap(id, iPage, pgsz, bExtend, pp);
142: }
143:
144: /*
145: ** The next group of routines are convenience wrappers around the
146: ** VFS methods.
147: */
148: int sqlite3OsOpen(
149: sqlite3_vfs *pVfs,
150: const char *zPath,
151: sqlite3_file *pFile,
152: int flags,
153: int *pFlagsOut
154: ){
155: int rc;
156: DO_OS_MALLOC_TEST(0);
157: /* 0x87f7f is a mask of SQLITE_OPEN_ flags that are valid to be passed
158: ** down into the VFS layer. Some SQLITE_OPEN_ flags (for example,
159: ** SQLITE_OPEN_FULLMUTEX or SQLITE_OPEN_SHAREDCACHE) are blocked before
160: ** reaching the VFS. */
161: rc = pVfs->xOpen(pVfs, zPath, pFile, flags & 0x87f7f, pFlagsOut);
162: assert( rc==SQLITE_OK || pFile->pMethods==0 );
163: return rc;
164: }
165: int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
166: DO_OS_MALLOC_TEST(0);
167: assert( dirSync==0 || dirSync==1 );
168: return pVfs->xDelete(pVfs, zPath, dirSync);
169: }
170: int sqlite3OsAccess(
171: sqlite3_vfs *pVfs,
172: const char *zPath,
173: int flags,
174: int *pResOut
175: ){
176: DO_OS_MALLOC_TEST(0);
177: return pVfs->xAccess(pVfs, zPath, flags, pResOut);
178: }
179: int sqlite3OsFullPathname(
180: sqlite3_vfs *pVfs,
181: const char *zPath,
182: int nPathOut,
183: char *zPathOut
184: ){
185: DO_OS_MALLOC_TEST(0);
186: zPathOut[0] = 0;
187: return pVfs->xFullPathname(pVfs, zPath, nPathOut, zPathOut);
188: }
189: #ifndef SQLITE_OMIT_LOAD_EXTENSION
190: void *sqlite3OsDlOpen(sqlite3_vfs *pVfs, const char *zPath){
191: return pVfs->xDlOpen(pVfs, zPath);
192: }
193: void sqlite3OsDlError(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
194: pVfs->xDlError(pVfs, nByte, zBufOut);
195: }
196: void (*sqlite3OsDlSym(sqlite3_vfs *pVfs, void *pHdle, const char *zSym))(void){
197: return pVfs->xDlSym(pVfs, pHdle, zSym);
198: }
199: void sqlite3OsDlClose(sqlite3_vfs *pVfs, void *pHandle){
200: pVfs->xDlClose(pVfs, pHandle);
201: }
202: #endif /* SQLITE_OMIT_LOAD_EXTENSION */
203: int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
204: return pVfs->xRandomness(pVfs, nByte, zBufOut);
205: }
206: int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){
207: return pVfs->xSleep(pVfs, nMicro);
208: }
209: int sqlite3OsCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){
210: int rc;
211: /* IMPLEMENTATION-OF: R-49045-42493 SQLite will use the xCurrentTimeInt64()
212: ** method to get the current date and time if that method is available
213: ** (if iVersion is 2 or greater and the function pointer is not NULL) and
214: ** will fall back to xCurrentTime() if xCurrentTimeInt64() is
215: ** unavailable.
216: */
217: if( pVfs->iVersion>=2 && pVfs->xCurrentTimeInt64 ){
218: rc = pVfs->xCurrentTimeInt64(pVfs, pTimeOut);
219: }else{
220: double r;
221: rc = pVfs->xCurrentTime(pVfs, &r);
222: *pTimeOut = (sqlite3_int64)(r*86400000.0);
223: }
224: return rc;
225: }
226:
227: int sqlite3OsOpenMalloc(
228: sqlite3_vfs *pVfs,
229: const char *zFile,
230: sqlite3_file **ppFile,
231: int flags,
232: int *pOutFlags
233: ){
234: int rc = SQLITE_NOMEM;
235: sqlite3_file *pFile;
236: pFile = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile);
237: if( pFile ){
238: rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags);
239: if( rc!=SQLITE_OK ){
240: sqlite3_free(pFile);
241: }else{
242: *ppFile = pFile;
243: }
244: }
245: return rc;
246: }
247: int sqlite3OsCloseFree(sqlite3_file *pFile){
248: int rc = SQLITE_OK;
249: assert( pFile );
250: rc = sqlite3OsClose(pFile);
251: sqlite3_free(pFile);
252: return rc;
253: }
254:
255: /*
256: ** This function is a wrapper around the OS specific implementation of
257: ** sqlite3_os_init(). The purpose of the wrapper is to provide the
258: ** ability to simulate a malloc failure, so that the handling of an
259: ** error in sqlite3_os_init() by the upper layers can be tested.
260: */
261: int sqlite3OsInit(void){
262: void *p = sqlite3_malloc(10);
263: if( p==0 ) return SQLITE_NOMEM;
264: sqlite3_free(p);
265: return sqlite3_os_init();
266: }
267:
268: /*
269: ** The list of all registered VFS implementations.
270: */
271: static sqlite3_vfs * SQLITE_WSD vfsList = 0;
272: #define vfsList GLOBAL(sqlite3_vfs *, vfsList)
273:
274: /*
275: ** Locate a VFS by name. If no name is given, simply return the
276: ** first VFS on the list.
277: */
278: sqlite3_vfs *sqlite3_vfs_find(const char *zVfs){
279: sqlite3_vfs *pVfs = 0;
280: #if SQLITE_THREADSAFE
281: sqlite3_mutex *mutex;
282: #endif
283: #ifndef SQLITE_OMIT_AUTOINIT
284: int rc = sqlite3_initialize();
285: if( rc ) return 0;
286: #endif
287: #if SQLITE_THREADSAFE
288: mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
289: #endif
290: sqlite3_mutex_enter(mutex);
291: for(pVfs = vfsList; pVfs; pVfs=pVfs->pNext){
292: if( zVfs==0 ) break;
293: if( strcmp(zVfs, pVfs->zName)==0 ) break;
294: }
295: sqlite3_mutex_leave(mutex);
296: return pVfs;
297: }
298:
299: /*
300: ** Unlink a VFS from the linked list
301: */
302: static void vfsUnlink(sqlite3_vfs *pVfs){
303: assert( sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)) );
304: if( pVfs==0 ){
305: /* No-op */
306: }else if( vfsList==pVfs ){
307: vfsList = pVfs->pNext;
308: }else if( vfsList ){
309: sqlite3_vfs *p = vfsList;
310: while( p->pNext && p->pNext!=pVfs ){
311: p = p->pNext;
312: }
313: if( p->pNext==pVfs ){
314: p->pNext = pVfs->pNext;
315: }
316: }
317: }
318:
319: /*
320: ** Register a VFS with the system. It is harmless to register the same
321: ** VFS multiple times. The new VFS becomes the default if makeDflt is
322: ** true.
323: */
324: int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
325: MUTEX_LOGIC(sqlite3_mutex *mutex;)
326: #ifndef SQLITE_OMIT_AUTOINIT
327: int rc = sqlite3_initialize();
328: if( rc ) return rc;
329: #endif
330: MUTEX_LOGIC( mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
331: sqlite3_mutex_enter(mutex);
332: vfsUnlink(pVfs);
333: if( makeDflt || vfsList==0 ){
334: pVfs->pNext = vfsList;
335: vfsList = pVfs;
336: }else{
337: pVfs->pNext = vfsList->pNext;
338: vfsList->pNext = pVfs;
339: }
340: assert(vfsList);
341: sqlite3_mutex_leave(mutex);
342: return SQLITE_OK;
343: }
344:
345: /*
346: ** Unregister a VFS so that it is no longer accessible.
347: */
348: int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){
349: #if SQLITE_THREADSAFE
350: sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
351: #endif
352: sqlite3_mutex_enter(mutex);
353: vfsUnlink(pVfs);
354: sqlite3_mutex_leave(mutex);
355: return SQLITE_OK;
356: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>