blob: f71ab56e656c0f93290660eb8e4e906d618184d8 [file] [log] [blame]
drh054889e2005-11-30 03:20:31 +00001/*
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*/
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/*
21** The following routines are convenience wrappers around methods
danielk197762079062007-08-15 17:08:46 +000022** of the sqlite3_file object. This is mostly just syntactic sugar. All
drh054889e2005-11-30 03:20:31 +000023** of this would be completely automatic if SQLite were coded using
24** C++ instead of plain old C.
25*/
danielk1977b4b47412007-08-17 15:53:36 +000026int sqlite3OsClose(sqlite3_file *pId){
27 if( !pId->pMethods ) return SQLITE_OK;
28 return pId->pMethods->xClose(pId);
drh054889e2005-11-30 03:20:31 +000029}
danielk197762079062007-08-15 17:08:46 +000030int sqlite3OsRead(sqlite3_file *id, void *pBuf, int amt, i64 offset){
31 return id->pMethods->xRead(id, pBuf, amt, offset);
drh054889e2005-11-30 03:20:31 +000032}
danielk197762079062007-08-15 17:08:46 +000033int sqlite3OsWrite(sqlite3_file *id, const void *pBuf, int amt, i64 offset){
34 return id->pMethods->xWrite(id, pBuf, amt, offset);
drh054889e2005-11-30 03:20:31 +000035}
danielk197762079062007-08-15 17:08:46 +000036int sqlite3OsTruncate(sqlite3_file *id, i64 size){
37 return id->pMethods->xTruncate(id, size);
drh054889e2005-11-30 03:20:31 +000038}
danielk197790949c22007-08-17 16:50:38 +000039int sqlite3OsSync(sqlite3_file *id, int flags){
40 return id->pMethods->xSync(id, flags);
drh054889e2005-11-30 03:20:31 +000041}
danielk197762079062007-08-15 17:08:46 +000042int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){
43 return id->pMethods->xFileSize(id, pSize);
drh054889e2005-11-30 03:20:31 +000044}
danielk197762079062007-08-15 17:08:46 +000045int sqlite3OsLock(sqlite3_file *id, int lockType){
46 return id->pMethods->xLock(id, lockType);
drh054889e2005-11-30 03:20:31 +000047}
danielk197762079062007-08-15 17:08:46 +000048int sqlite3OsUnlock(sqlite3_file *id, int lockType){
49 return id->pMethods->xUnlock(id, lockType);
drh054889e2005-11-30 03:20:31 +000050}
danielk197762079062007-08-15 17:08:46 +000051int sqlite3OsBreakLock(sqlite3_file *id){
52 return id->pMethods->xBreakLock(id);
drh054889e2005-11-30 03:20:31 +000053}
danielk197762079062007-08-15 17:08:46 +000054int sqlite3OsCheckReservedLock(sqlite3_file *id){
55 return id->pMethods->xCheckReservedLock(id);
drh054889e2005-11-30 03:20:31 +000056}
danielk197762079062007-08-15 17:08:46 +000057int sqlite3OsSectorSize(sqlite3_file *id){
58 int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize;
danielk1977967a4a12007-08-20 14:23:44 +000059 return (xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE);
danielk1977b4721172007-03-19 05:54:48 +000060}
danielk197762079062007-08-15 17:08:46 +000061int sqlite3OsDeviceCharacteristics(sqlite3_file *id){
62 return id->pMethods->xDeviceCharacteristics(id);
63}
drh3f459022006-01-07 16:06:07 +000064
drh87cc3b32007-05-08 21:45:27 +000065#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
66 /* These methods are currently only used for testing and debugging. */
danielk197762079062007-08-15 17:08:46 +000067 int sqlite3OsFileHandle(sqlite3_file *id){
68 /* return id->pMethods->xFileHandle(id); */
69 return 0;
drh87cc3b32007-05-08 21:45:27 +000070 }
danielk197762079062007-08-15 17:08:46 +000071 int sqlite3OsLockState(sqlite3_file *id){
danielk197790949c22007-08-17 16:50:38 +000072 return id->pMethods->xLockState(id);
drh87cc3b32007-05-08 21:45:27 +000073 }
74#endif
75
drhd677b3d2007-08-20 22:48:41 +000076/*
77** The next group of routines are convenience wrappers around the
78** VFS methods.
79*/
danielk1977b4b47412007-08-17 15:53:36 +000080int sqlite3OsOpen(
81 sqlite3_vfs *pVfs,
82 const char *zPath,
83 sqlite3_file *pFile,
84 int flags,
85 int *pFlagsOut
86){
87 return pVfs->xOpen(pVfs->pAppData, zPath, pFile, flags, pFlagsOut);
drh3f459022006-01-07 16:06:07 +000088}
danielk1977fee2d252007-08-18 10:59:19 +000089int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
90 return pVfs->xDelete(pVfs->pAppData, zPath, dirSync);
danielk1977b4b47412007-08-17 15:53:36 +000091}
92int sqlite3OsAccess(sqlite3_vfs *pVfs, const char *zPath, int flags){
93 return pVfs->xAccess(pVfs->pAppData, zPath, flags);
94}
95int sqlite3OsGetTempName(sqlite3_vfs *pVfs, char *zBufOut){
96 return pVfs->xGetTempName(pVfs->pAppData, zBufOut);
97}
98int sqlite3OsFullPathname(sqlite3_vfs *pVfs, const char *zPath, char *zPathOut){
99 return pVfs->xFullPathname(pVfs->pAppData, zPath, zPathOut);
100}
101void *sqlite3OsDlOpen(sqlite3_vfs *pVfs, const char *zPath){
102 return pVfs->xDlOpen(pVfs->pAppData, zPath);
103}
104void sqlite3OsDlError(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
105 pVfs->xDlError(pVfs->pAppData, nByte, zBufOut);
106}
107void *sqlite3OsDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){
108 return pVfs->xDlSym(pHandle, zSymbol);
109}
110void sqlite3OsDlClose(sqlite3_vfs *pVfs, void *pHandle){
111 pVfs->xDlClose(pHandle);
112}
113int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
114 return pVfs->xRandomness(pVfs->pAppData, nByte, zBufOut);
115}
116int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){
117 return pVfs->xSleep(pVfs->pAppData, nMicro);
118}
119int sqlite3OsCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
120 return pVfs->xCurrentTime(pVfs->pAppData, pTimeOut);
121}
122
123int sqlite3OsOpenMalloc(
124 sqlite3_vfs *pVfs,
125 const char *zFile,
126 sqlite3_file **ppFile,
danielk1977967a4a12007-08-20 14:23:44 +0000127 int flags,
128 int *pOutFlags
danielk1977b4b47412007-08-17 15:53:36 +0000129){
130 int rc = SQLITE_NOMEM;
131 sqlite3_file *pFile;
132 pFile = (sqlite3_file *)sqlite3_malloc(pVfs->szOsFile);
133 if( pFile ){
danielk1977967a4a12007-08-20 14:23:44 +0000134 rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags);
danielk1977b4b47412007-08-17 15:53:36 +0000135 if( rc!=SQLITE_OK ){
136 sqlite3_free(pFile);
137 }else{
138 *ppFile = pFile;
139 }
140 }
141 return rc;
142}
143int sqlite3OsCloseFree(sqlite3_file *pFile){
144 int rc = SQLITE_OK;
145 if( pFile ){
146 rc = sqlite3OsClose(pFile);
147 sqlite3_free(pFile);
148 }
149 return rc;
150}
151
152/*
153** Default vfs implementation. Defined by the various os_X.c implementations.
154*/
155extern sqlite3_vfs sqlite3DefaultVfs;
156
drhd677b3d2007-08-20 22:48:41 +0000157/*
158** The list of all registered VFS implementations.
159*/
160static sqlite3_vfs *vfsList = &sqlite3DefaultVfs;
161
162/*
163** Locate a VFS by name. If no name is given, simply return the
164** first VFS on the list.
165*/
166sqlite3_vfs *sqlite3_vfs_find(const char *zVfs){
167 sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
168 sqlite3_vfs *pVfs;
169 sqlite3_mutex_enter(mutex);
170 for(pVfs = vfsList; pVfs; pVfs=pVfs->pNext){
171 if( zVfs==0 ) break;
172 if( strcmp(zVfs, pVfs->zName)==0 ) break;
173 }
174 if( pVfs ){
175 pVfs->nRef++;
176 assert( pVfs->nRef==1 || pVfs->vfsMutex!=0 );
177 assert( pVfs->nRef>1 || pVfs->vfsMutex==0 );
178 if( pVfs->vfsMutex==0 ){
179 pVfs->vfsMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
180 }
181 }
182 sqlite3_mutex_leave(mutex);
183 return pVfs;
danielk1977b4b47412007-08-17 15:53:36 +0000184}
185
drhd677b3d2007-08-20 22:48:41 +0000186/*
187** Release a VFS once it is no longer needed.
188*/
189int sqlite3_vfs_release(sqlite3_vfs *pVfs){
190 sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
191 sqlite3_mutex_enter(mutex);
192 assert( pVfs->nRef>0 );
193 pVfs->nRef--;
194 if( pVfs->nRef==0 ){
195 sqlite3_mutex_free(pVfs->vfsMutex);
196 pVfs->vfsMutex = 0;
197 }
198 sqlite3_mutex_leave(mutex);
199 return SQLITE_OK;
200}
201
202/*
203** Unlink a VFS from the linked list
204*/
205static void vfsUnlink(sqlite3_vfs *pVfs){
206 assert( sqlite3_mutex_held(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)) );
207 if( vfsList==pVfs ){
208 vfsList = pVfs->pNext;
209 }else{
210 sqlite3_vfs *p = vfsList;
211 while( p->pNext && p->pNext!=pVfs ){
212 p = p->pNext;
213 }
214 if( p->pNext==pVfs ){
215 p->pNext = pVfs->pNext;
216 }
217 }
218}
219
220/*
221** Register a VFS with the system. It is harmless to register the same
222** VFS multiple times. The new VFS becomes the default if makeDflt is
223** true.
224*/
225int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
226 sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
227 sqlite3_mutex_enter(mutex);
228 vfsUnlink(pVfs);
229 if( makeDflt || vfsList==0 ){
230 pVfs->pNext = vfsList;
231 vfsList = pVfs;
232 }else{
233 pVfs->pNext = vfsList->pNext;
234 pVfs->pNext = pVfs;
235 }
danielk1977f1da17a2007-08-21 13:07:46 +0000236 assert(vfsList);
drhd677b3d2007-08-20 22:48:41 +0000237 sqlite3_mutex_leave(mutex);
238 return SQLITE_OK;
239}
240
241/*
242** Unregister a VFS so that it is no longer accessible.
243*/
244int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){
245 sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
246 sqlite3_mutex_enter(mutex);
247 vfsUnlink(pVfs);
danielk1977f1da17a2007-08-21 13:07:46 +0000248 assert(vfsList);
drhd677b3d2007-08-20 22:48:41 +0000249 sqlite3_mutex_leave(mutex);
250 return SQLITE_OK;
251}