blob: 0593654007bd4f200e14d2b12c11d964e6307274 [file] [log] [blame]
danielk1977a7a8e142008-02-13 18:25:27 +00001/*
drh054889e2005-11-30 03:20:31 +00002** 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*/
drh3f459022006-01-07 16:06:07 +000016#define _SQLITE_OS_C_ 1
drh054889e2005-11-30 03:20:31 +000017#include "sqliteInt.h"
drhbd08af42007-04-05 21:58:33 +000018#undef _SQLITE_OS_C_
drh054889e2005-11-30 03:20:31 +000019
20/*
danielk1977ae72d982007-10-03 08:46:44 +000021** 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*/
danielk197798c21902008-09-23 16:41:29 +000037#if defined(SQLITE_TEST) && (SQLITE_OS_WIN==0)
danielk1977b5a19202009-07-27 11:41:20 +000038 #define DO_OS_MALLOC_TEST(x) if (!x || !sqlite3IsMemJournal(x)) { \
39 void *pTstAlloc = sqlite3Malloc(10); \
40 if (!pTstAlloc) return SQLITE_IOERR_NOMEM; \
41 sqlite3_free(pTstAlloc); \
danielk1977ae72d982007-10-03 08:46:44 +000042 }
43#else
danielk1977b5a19202009-07-27 11:41:20 +000044 #define DO_OS_MALLOC_TEST(x)
danielk1977ae72d982007-10-03 08:46:44 +000045#endif
46
47/*
drh054889e2005-11-30 03:20:31 +000048** The following routines are convenience wrappers around methods
danielk197762079062007-08-15 17:08:46 +000049** of the sqlite3_file object. This is mostly just syntactic sugar. All
drh054889e2005-11-30 03:20:31 +000050** of this would be completely automatic if SQLite were coded using
51** C++ instead of plain old C.
52*/
danielk1977b4b47412007-08-17 15:53:36 +000053int sqlite3OsClose(sqlite3_file *pId){
danielk1977c7b60172007-08-22 11:22:03 +000054 int rc = SQLITE_OK;
55 if( pId->pMethods ){
56 rc = pId->pMethods->xClose(pId);
57 pId->pMethods = 0;
58 }
59 return rc;
drh054889e2005-11-30 03:20:31 +000060}
danielk197762079062007-08-15 17:08:46 +000061int sqlite3OsRead(sqlite3_file *id, void *pBuf, int amt, i64 offset){
danielk1977b5a19202009-07-27 11:41:20 +000062 DO_OS_MALLOC_TEST(id);
danielk197762079062007-08-15 17:08:46 +000063 return id->pMethods->xRead(id, pBuf, amt, offset);
drh054889e2005-11-30 03:20:31 +000064}
danielk197762079062007-08-15 17:08:46 +000065int sqlite3OsWrite(sqlite3_file *id, const void *pBuf, int amt, i64 offset){
danielk1977b5a19202009-07-27 11:41:20 +000066 DO_OS_MALLOC_TEST(id);
danielk197762079062007-08-15 17:08:46 +000067 return id->pMethods->xWrite(id, pBuf, amt, offset);
drh054889e2005-11-30 03:20:31 +000068}
danielk197762079062007-08-15 17:08:46 +000069int sqlite3OsTruncate(sqlite3_file *id, i64 size){
70 return id->pMethods->xTruncate(id, size);
drh054889e2005-11-30 03:20:31 +000071}
danielk197790949c22007-08-17 16:50:38 +000072int sqlite3OsSync(sqlite3_file *id, int flags){
danielk1977b5a19202009-07-27 11:41:20 +000073 DO_OS_MALLOC_TEST(id);
danielk197790949c22007-08-17 16:50:38 +000074 return id->pMethods->xSync(id, flags);
drh054889e2005-11-30 03:20:31 +000075}
danielk197762079062007-08-15 17:08:46 +000076int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){
danielk1977b5a19202009-07-27 11:41:20 +000077 DO_OS_MALLOC_TEST(id);
danielk197762079062007-08-15 17:08:46 +000078 return id->pMethods->xFileSize(id, pSize);
drh054889e2005-11-30 03:20:31 +000079}
danielk197762079062007-08-15 17:08:46 +000080int sqlite3OsLock(sqlite3_file *id, int lockType){
danielk1977b5a19202009-07-27 11:41:20 +000081 DO_OS_MALLOC_TEST(id);
danielk197762079062007-08-15 17:08:46 +000082 return id->pMethods->xLock(id, lockType);
drh054889e2005-11-30 03:20:31 +000083}
danielk197762079062007-08-15 17:08:46 +000084int sqlite3OsUnlock(sqlite3_file *id, int lockType){
85 return id->pMethods->xUnlock(id, lockType);
drh054889e2005-11-30 03:20:31 +000086}
danielk1977861f7452008-06-05 11:39:11 +000087int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut){
danielk1977b5a19202009-07-27 11:41:20 +000088 DO_OS_MALLOC_TEST(id);
danielk1977861f7452008-06-05 11:39:11 +000089 return id->pMethods->xCheckReservedLock(id, pResOut);
drh054889e2005-11-30 03:20:31 +000090}
drhcc6bb3e2007-08-31 16:11:35 +000091int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){
danielk1977861f7452008-06-05 11:39:11 +000092 return id->pMethods->xFileControl(id, op, pArg);
drhcc6bb3e2007-08-31 16:11:35 +000093}
danielk1977bf260972008-01-22 11:50:13 +000094int sqlite3OsSectorSize(sqlite3_file *id){
95 int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize;
96 return (xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE);
97}
98int sqlite3OsDeviceCharacteristics(sqlite3_file *id){
99 return id->pMethods->xDeviceCharacteristics(id);
100}
drhd9e5c4f2010-05-12 18:01:39 +0000101int sqlite3OsShmOpen(sqlite3_file *id){
102 return id->pMethods->xShmOpen(id);
103}
104int sqlite3OsShmSize(sqlite3_file *id, int reqSize, int *pNewSize){
105 return id->pMethods->xShmSize(id, reqSize, pNewSize);
106}
drh5939f442010-05-18 13:27:12 +0000107int sqlite3OsShmGet(sqlite3_file *id,int reqSize,int *pSize,void volatile **pp){
drhd9e5c4f2010-05-12 18:01:39 +0000108 return id->pMethods->xShmGet(id, reqSize, pSize, pp);
109}
110int sqlite3OsShmRelease(sqlite3_file *id){
111 return id->pMethods->xShmRelease(id);
112}
113int sqlite3OsShmLock(sqlite3_file *id, int desiredLock, int *pGotLock){
114 return id->pMethods->xShmLock(id, desiredLock, pGotLock);
115}
drh286a2882010-05-20 23:51:06 +0000116void sqlite3OsShmBarrier(sqlite3_file *id){
117 id->pMethods->xShmBarrier(id);
118}
drhd9e5c4f2010-05-12 18:01:39 +0000119int sqlite3OsShmClose(sqlite3_file *id, int deleteFlag){
120 return id->pMethods->xShmClose(id, deleteFlag);
121}
drh3f459022006-01-07 16:06:07 +0000122
drhd677b3d2007-08-20 22:48:41 +0000123/*
124** The next group of routines are convenience wrappers around the
125** VFS methods.
126*/
danielk1977b4b47412007-08-17 15:53:36 +0000127int sqlite3OsOpen(
128 sqlite3_vfs *pVfs,
129 const char *zPath,
130 sqlite3_file *pFile,
131 int flags,
132 int *pFlagsOut
133){
drh072db2f2009-03-25 14:24:41 +0000134 int rc;
danielk1977b5a19202009-07-27 11:41:20 +0000135 DO_OS_MALLOC_TEST(0);
drh10a76c92010-01-26 01:25:26 +0000136 /* 0x7f3f is a mask of SQLITE_OPEN_ flags that are valid to be passed
drhf1f12682009-09-09 14:17:52 +0000137 ** down into the VFS layer. Some SQLITE_OPEN_ flags (for example,
138 ** SQLITE_OPEN_FULLMUTEX or SQLITE_OPEN_SHAREDCACHE) are blocked before
139 ** reaching the VFS. */
drh10a76c92010-01-26 01:25:26 +0000140 rc = pVfs->xOpen(pVfs, zPath, pFile, flags & 0x7f3f, pFlagsOut);
drh072db2f2009-03-25 14:24:41 +0000141 assert( rc==SQLITE_OK || pFile->pMethods==0 );
142 return rc;
drh3f459022006-01-07 16:06:07 +0000143}
danielk1977fee2d252007-08-18 10:59:19 +0000144int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
drh153c62c2007-08-24 03:51:33 +0000145 return pVfs->xDelete(pVfs, zPath, dirSync);
danielk1977b4b47412007-08-17 15:53:36 +0000146}
danielk1977861f7452008-06-05 11:39:11 +0000147int sqlite3OsAccess(
148 sqlite3_vfs *pVfs,
149 const char *zPath,
150 int flags,
151 int *pResOut
152){
danielk1977b5a19202009-07-27 11:41:20 +0000153 DO_OS_MALLOC_TEST(0);
danielk1977861f7452008-06-05 11:39:11 +0000154 return pVfs->xAccess(pVfs, zPath, flags, pResOut);
danielk1977b4b47412007-08-17 15:53:36 +0000155}
danielk1977adfb9b02007-09-17 07:02:56 +0000156int sqlite3OsFullPathname(
157 sqlite3_vfs *pVfs,
158 const char *zPath,
159 int nPathOut,
160 char *zPathOut
161){
drh68ff78b2009-11-16 23:36:33 +0000162 zPathOut[0] = 0;
danielk1977adfb9b02007-09-17 07:02:56 +0000163 return pVfs->xFullPathname(pVfs, zPath, nPathOut, zPathOut);
danielk1977b4b47412007-08-17 15:53:36 +0000164}
shane75998ab2008-05-29 02:52:59 +0000165#ifndef SQLITE_OMIT_LOAD_EXTENSION
danielk1977b4b47412007-08-17 15:53:36 +0000166void *sqlite3OsDlOpen(sqlite3_vfs *pVfs, const char *zPath){
drh153c62c2007-08-24 03:51:33 +0000167 return pVfs->xDlOpen(pVfs, zPath);
danielk1977b4b47412007-08-17 15:53:36 +0000168}
169void sqlite3OsDlError(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
drh153c62c2007-08-24 03:51:33 +0000170 pVfs->xDlError(pVfs, nByte, zBufOut);
danielk1977b4b47412007-08-17 15:53:36 +0000171}
drh1875f7a2008-12-08 18:19:17 +0000172void (*sqlite3OsDlSym(sqlite3_vfs *pVfs, void *pHdle, const char *zSym))(void){
173 return pVfs->xDlSym(pVfs, pHdle, zSym);
danielk1977b4b47412007-08-17 15:53:36 +0000174}
175void sqlite3OsDlClose(sqlite3_vfs *pVfs, void *pHandle){
drh153c62c2007-08-24 03:51:33 +0000176 pVfs->xDlClose(pVfs, pHandle);
danielk1977b4b47412007-08-17 15:53:36 +0000177}
shane75998ab2008-05-29 02:52:59 +0000178#endif /* SQLITE_OMIT_LOAD_EXTENSION */
danielk1977b4b47412007-08-17 15:53:36 +0000179int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
drh153c62c2007-08-24 03:51:33 +0000180 return pVfs->xRandomness(pVfs, nByte, zBufOut);
danielk1977b4b47412007-08-17 15:53:36 +0000181}
182int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){
drh153c62c2007-08-24 03:51:33 +0000183 return pVfs->xSleep(pVfs, nMicro);
danielk1977b4b47412007-08-17 15:53:36 +0000184}
drhb7e8ea22010-05-03 14:32:30 +0000185int sqlite3OsCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){
186 int rc;
187 if( pVfs->iVersion>=2 && pVfs->xCurrentTimeInt64 ){
188 rc = pVfs->xCurrentTimeInt64(pVfs, pTimeOut);
189 }else{
190 double r;
191 rc = pVfs->xCurrentTime(pVfs, &r);
192 *pTimeOut = (sqlite3_int64)(r*86400000.0);
193 }
194 return rc;
danielk1977b4b47412007-08-17 15:53:36 +0000195}
196
197int sqlite3OsOpenMalloc(
198 sqlite3_vfs *pVfs,
199 const char *zFile,
200 sqlite3_file **ppFile,
danielk1977967a4a12007-08-20 14:23:44 +0000201 int flags,
202 int *pOutFlags
danielk1977b4b47412007-08-17 15:53:36 +0000203){
204 int rc = SQLITE_NOMEM;
205 sqlite3_file *pFile;
drhe5ae5732008-06-15 02:51:47 +0000206 pFile = (sqlite3_file *)sqlite3Malloc(pVfs->szOsFile);
danielk1977b4b47412007-08-17 15:53:36 +0000207 if( pFile ){
danielk1977967a4a12007-08-20 14:23:44 +0000208 rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags);
danielk1977b4b47412007-08-17 15:53:36 +0000209 if( rc!=SQLITE_OK ){
210 sqlite3_free(pFile);
211 }else{
212 *ppFile = pFile;
213 }
214 }
215 return rc;
216}
217int sqlite3OsCloseFree(sqlite3_file *pFile){
218 int rc = SQLITE_OK;
mlcreech40032982008-04-08 03:09:22 +0000219 assert( pFile );
220 rc = sqlite3OsClose(pFile);
221 sqlite3_free(pFile);
danielk1977b4b47412007-08-17 15:53:36 +0000222 return rc;
223}
224
drhd677b3d2007-08-20 22:48:41 +0000225/*
dan3d6e0602009-08-17 15:52:25 +0000226** This function is a wrapper around the OS specific implementation of
227** sqlite3_os_init(). The purpose of the wrapper is to provide the
228** ability to simulate a malloc failure, so that the handling of an
229** error in sqlite3_os_init() by the upper layers can be tested.
230*/
231int sqlite3OsInit(void){
drhadad77a2009-08-17 16:01:11 +0000232 void *p = sqlite3_malloc(10);
233 if( p==0 ) return SQLITE_NOMEM;
234 sqlite3_free(p);
dan3d6e0602009-08-17 15:52:25 +0000235 return sqlite3_os_init();
236}
237
238/*
danielk1977c0fa4c52008-06-25 17:19:00 +0000239** The list of all registered VFS implementations.
drhd677b3d2007-08-20 22:48:41 +0000240*/
danielk197795e80d62008-09-02 17:18:51 +0000241static sqlite3_vfs * SQLITE_WSD vfsList = 0;
danielk19775c8f8582008-09-02 10:22:00 +0000242#define vfsList GLOBAL(sqlite3_vfs *, vfsList)
drhd677b3d2007-08-20 22:48:41 +0000243
244/*
245** Locate a VFS by name. If no name is given, simply return the
246** first VFS on the list.
247*/
248sqlite3_vfs *sqlite3_vfs_find(const char *zVfs){
drha4189802008-06-19 16:07:07 +0000249 sqlite3_vfs *pVfs = 0;
drh18472fa2008-10-07 15:25:48 +0000250#if SQLITE_THREADSAFE
drh40257ff2008-06-13 18:24:27 +0000251 sqlite3_mutex *mutex;
252#endif
253#ifndef SQLITE_OMIT_AUTOINIT
254 int rc = sqlite3_initialize();
255 if( rc ) return 0;
256#endif
drh18472fa2008-10-07 15:25:48 +0000257#if SQLITE_THREADSAFE
danielk197759f8c082008-06-18 17:09:10 +0000258 mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
drh7e8b8482008-01-23 03:03:05 +0000259#endif
drhd677b3d2007-08-20 22:48:41 +0000260 sqlite3_mutex_enter(mutex);
261 for(pVfs = vfsList; pVfs; pVfs=pVfs->pNext){
262 if( zVfs==0 ) break;
263 if( strcmp(zVfs, pVfs->zName)==0 ) break;
264 }
drhd677b3d2007-08-20 22:48:41 +0000265 sqlite3_mutex_leave(mutex);
266 return pVfs;
danielk1977b4b47412007-08-17 15:53:36 +0000267}
268
drhd677b3d2007-08-20 22:48:41 +0000269/*
drhd677b3d2007-08-20 22:48:41 +0000270** Unlink a VFS from the linked list
271*/
272static void vfsUnlink(sqlite3_vfs *pVfs){
danielk197759f8c082008-06-18 17:09:10 +0000273 assert( sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)) );
drh9bc54492007-10-23 14:49:59 +0000274 if( pVfs==0 ){
275 /* No-op */
276 }else if( vfsList==pVfs ){
drhd677b3d2007-08-20 22:48:41 +0000277 vfsList = pVfs->pNext;
drh9bc54492007-10-23 14:49:59 +0000278 }else if( vfsList ){
drhd677b3d2007-08-20 22:48:41 +0000279 sqlite3_vfs *p = vfsList;
280 while( p->pNext && p->pNext!=pVfs ){
281 p = p->pNext;
282 }
283 if( p->pNext==pVfs ){
284 p->pNext = pVfs->pNext;
285 }
286 }
287}
288
289/*
290** Register a VFS with the system. It is harmless to register the same
291** VFS multiple times. The new VFS becomes the default if makeDflt is
292** true.
293*/
294int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
danielk1977c0fa4c52008-06-25 17:19:00 +0000295 sqlite3_mutex *mutex = 0;
drh40257ff2008-06-13 18:24:27 +0000296#ifndef SQLITE_OMIT_AUTOINIT
297 int rc = sqlite3_initialize();
298 if( rc ) return rc;
299#endif
danielk197771bc31c2008-06-26 08:29:34 +0000300 mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
drhd677b3d2007-08-20 22:48:41 +0000301 sqlite3_mutex_enter(mutex);
302 vfsUnlink(pVfs);
303 if( makeDflt || vfsList==0 ){
304 pVfs->pNext = vfsList;
305 vfsList = pVfs;
306 }else{
307 pVfs->pNext = vfsList->pNext;
danielk197795c8a542007-09-01 06:51:27 +0000308 vfsList->pNext = pVfs;
drhd677b3d2007-08-20 22:48:41 +0000309 }
danielk1977f1da17a2007-08-21 13:07:46 +0000310 assert(vfsList);
drhd677b3d2007-08-20 22:48:41 +0000311 sqlite3_mutex_leave(mutex);
312 return SQLITE_OK;
313}
314
315/*
316** Unregister a VFS so that it is no longer accessible.
317*/
318int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){
drh18472fa2008-10-07 15:25:48 +0000319#if SQLITE_THREADSAFE
danielk197759f8c082008-06-18 17:09:10 +0000320 sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
drh7e8b8482008-01-23 03:03:05 +0000321#endif
drhd677b3d2007-08-20 22:48:41 +0000322 sqlite3_mutex_enter(mutex);
323 vfsUnlink(pVfs);
324 sqlite3_mutex_leave(mutex);
325 return SQLITE_OK;
326}