blob: 22ea193186e5c75b4bd6f6b55f62204abf628542 [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.
danielk1977822a5162008-05-16 04:51:54 +000015**
danielk197795e80d62008-09-02 17:18:51 +000016** $Id: os.c,v 1.122 2008/09/02 17:18:52 danielk1977 Exp $
drh054889e2005-11-30 03:20:31 +000017*/
drh3f459022006-01-07 16:06:07 +000018#define _SQLITE_OS_C_ 1
drh054889e2005-11-30 03:20:31 +000019#include "sqliteInt.h"
drhbd08af42007-04-05 21:58:33 +000020#undef _SQLITE_OS_C_
drh054889e2005-11-30 03:20:31 +000021
22/*
danielk1977ae72d982007-10-03 08:46:44 +000023** The default SQLite sqlite3_vfs implementations do not allocate
24** memory (actually, os_unix.c allocates a small amount of memory
25** from within OsOpen()), but some third-party implementations may.
26** So we test the effects of a malloc() failing and the sqlite3OsXXX()
27** function returning SQLITE_IOERR_NOMEM using the DO_OS_MALLOC_TEST macro.
28**
29** The following functions are instrumented for malloc() failure
30** testing:
31**
32** sqlite3OsOpen()
33** sqlite3OsRead()
34** sqlite3OsWrite()
35** sqlite3OsSync()
36** sqlite3OsLock()
37**
38*/
drh633e6d52008-07-28 19:34:53 +000039#if defined(SQLITE_TEST) && (SQLITE_OS_WIN==0) && 0
danielk1977ae72d982007-10-03 08:46:44 +000040 #define DO_OS_MALLOC_TEST if (1) { \
drhe5ae5732008-06-15 02:51:47 +000041 void *pTstAlloc = sqlite3Malloc(10); \
danielk1977ae72d982007-10-03 08:46:44 +000042 if (!pTstAlloc) return SQLITE_IOERR_NOMEM; \
43 sqlite3_free(pTstAlloc); \
44 }
45#else
46 #define DO_OS_MALLOC_TEST
47#endif
48
49/*
drh054889e2005-11-30 03:20:31 +000050** The following routines are convenience wrappers around methods
danielk197762079062007-08-15 17:08:46 +000051** of the sqlite3_file object. This is mostly just syntactic sugar. All
drh054889e2005-11-30 03:20:31 +000052** of this would be completely automatic if SQLite were coded using
53** C++ instead of plain old C.
54*/
danielk1977b4b47412007-08-17 15:53:36 +000055int sqlite3OsClose(sqlite3_file *pId){
danielk1977c7b60172007-08-22 11:22:03 +000056 int rc = SQLITE_OK;
57 if( pId->pMethods ){
58 rc = pId->pMethods->xClose(pId);
59 pId->pMethods = 0;
60 }
61 return rc;
drh054889e2005-11-30 03:20:31 +000062}
danielk197762079062007-08-15 17:08:46 +000063int sqlite3OsRead(sqlite3_file *id, void *pBuf, int amt, i64 offset){
danielk1977ae72d982007-10-03 08:46:44 +000064 DO_OS_MALLOC_TEST;
danielk197762079062007-08-15 17:08:46 +000065 return id->pMethods->xRead(id, pBuf, amt, offset);
drh054889e2005-11-30 03:20:31 +000066}
danielk197762079062007-08-15 17:08:46 +000067int sqlite3OsWrite(sqlite3_file *id, const void *pBuf, int amt, i64 offset){
danielk1977ae72d982007-10-03 08:46:44 +000068 DO_OS_MALLOC_TEST;
danielk197762079062007-08-15 17:08:46 +000069 return id->pMethods->xWrite(id, pBuf, amt, offset);
drh054889e2005-11-30 03:20:31 +000070}
danielk197762079062007-08-15 17:08:46 +000071int sqlite3OsTruncate(sqlite3_file *id, i64 size){
72 return id->pMethods->xTruncate(id, size);
drh054889e2005-11-30 03:20:31 +000073}
danielk197790949c22007-08-17 16:50:38 +000074int sqlite3OsSync(sqlite3_file *id, int flags){
danielk1977ae72d982007-10-03 08:46:44 +000075 DO_OS_MALLOC_TEST;
danielk197790949c22007-08-17 16:50:38 +000076 return id->pMethods->xSync(id, flags);
drh054889e2005-11-30 03:20:31 +000077}
danielk197762079062007-08-15 17:08:46 +000078int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){
danielk1977861f7452008-06-05 11:39:11 +000079 DO_OS_MALLOC_TEST;
danielk197762079062007-08-15 17:08:46 +000080 return id->pMethods->xFileSize(id, pSize);
drh054889e2005-11-30 03:20:31 +000081}
danielk197762079062007-08-15 17:08:46 +000082int sqlite3OsLock(sqlite3_file *id, int lockType){
danielk1977ae72d982007-10-03 08:46:44 +000083 DO_OS_MALLOC_TEST;
danielk197762079062007-08-15 17:08:46 +000084 return id->pMethods->xLock(id, lockType);
drh054889e2005-11-30 03:20:31 +000085}
danielk197762079062007-08-15 17:08:46 +000086int sqlite3OsUnlock(sqlite3_file *id, int lockType){
87 return id->pMethods->xUnlock(id, lockType);
drh054889e2005-11-30 03:20:31 +000088}
danielk1977861f7452008-06-05 11:39:11 +000089int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut){
90 DO_OS_MALLOC_TEST;
91 return id->pMethods->xCheckReservedLock(id, pResOut);
drh054889e2005-11-30 03:20:31 +000092}
drhcc6bb3e2007-08-31 16:11:35 +000093int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){
danielk1977861f7452008-06-05 11:39:11 +000094 return id->pMethods->xFileControl(id, op, pArg);
drhcc6bb3e2007-08-31 16:11:35 +000095}
danielk1977bf260972008-01-22 11:50:13 +000096int sqlite3OsSectorSize(sqlite3_file *id){
97 int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize;
98 return (xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE);
99}
100int sqlite3OsDeviceCharacteristics(sqlite3_file *id){
101 return id->pMethods->xDeviceCharacteristics(id);
102}
drh3f459022006-01-07 16:06:07 +0000103
drhd677b3d2007-08-20 22:48:41 +0000104/*
105** The next group of routines are convenience wrappers around the
106** VFS methods.
107*/
danielk1977b4b47412007-08-17 15:53:36 +0000108int sqlite3OsOpen(
109 sqlite3_vfs *pVfs,
110 const char *zPath,
111 sqlite3_file *pFile,
112 int flags,
113 int *pFlagsOut
114){
danielk1977ae72d982007-10-03 08:46:44 +0000115 DO_OS_MALLOC_TEST;
drh153c62c2007-08-24 03:51:33 +0000116 return pVfs->xOpen(pVfs, zPath, pFile, flags, pFlagsOut);
drh3f459022006-01-07 16:06:07 +0000117}
danielk1977fee2d252007-08-18 10:59:19 +0000118int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
drh153c62c2007-08-24 03:51:33 +0000119 return pVfs->xDelete(pVfs, zPath, dirSync);
danielk1977b4b47412007-08-17 15:53:36 +0000120}
danielk1977861f7452008-06-05 11:39:11 +0000121int sqlite3OsAccess(
122 sqlite3_vfs *pVfs,
123 const char *zPath,
124 int flags,
125 int *pResOut
126){
127 DO_OS_MALLOC_TEST;
128 return pVfs->xAccess(pVfs, zPath, flags, pResOut);
danielk1977b4b47412007-08-17 15:53:36 +0000129}
danielk1977adfb9b02007-09-17 07:02:56 +0000130int sqlite3OsFullPathname(
131 sqlite3_vfs *pVfs,
132 const char *zPath,
133 int nPathOut,
134 char *zPathOut
135){
136 return pVfs->xFullPathname(pVfs, zPath, nPathOut, zPathOut);
danielk1977b4b47412007-08-17 15:53:36 +0000137}
shane75998ab2008-05-29 02:52:59 +0000138#ifndef SQLITE_OMIT_LOAD_EXTENSION
danielk1977b4b47412007-08-17 15:53:36 +0000139void *sqlite3OsDlOpen(sqlite3_vfs *pVfs, const char *zPath){
drh153c62c2007-08-24 03:51:33 +0000140 return pVfs->xDlOpen(pVfs, zPath);
danielk1977b4b47412007-08-17 15:53:36 +0000141}
142void sqlite3OsDlError(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
drh153c62c2007-08-24 03:51:33 +0000143 pVfs->xDlError(pVfs, nByte, zBufOut);
danielk1977b4b47412007-08-17 15:53:36 +0000144}
145void *sqlite3OsDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){
drh153c62c2007-08-24 03:51:33 +0000146 return pVfs->xDlSym(pVfs, pHandle, zSymbol);
danielk1977b4b47412007-08-17 15:53:36 +0000147}
148void sqlite3OsDlClose(sqlite3_vfs *pVfs, void *pHandle){
drh153c62c2007-08-24 03:51:33 +0000149 pVfs->xDlClose(pVfs, pHandle);
danielk1977b4b47412007-08-17 15:53:36 +0000150}
shane75998ab2008-05-29 02:52:59 +0000151#endif /* SQLITE_OMIT_LOAD_EXTENSION */
danielk1977b4b47412007-08-17 15:53:36 +0000152int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
drh153c62c2007-08-24 03:51:33 +0000153 return pVfs->xRandomness(pVfs, nByte, zBufOut);
danielk1977b4b47412007-08-17 15:53:36 +0000154}
155int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){
drh153c62c2007-08-24 03:51:33 +0000156 return pVfs->xSleep(pVfs, nMicro);
danielk1977b4b47412007-08-17 15:53:36 +0000157}
158int sqlite3OsCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
drh153c62c2007-08-24 03:51:33 +0000159 return pVfs->xCurrentTime(pVfs, pTimeOut);
danielk1977b4b47412007-08-17 15:53:36 +0000160}
161
162int sqlite3OsOpenMalloc(
163 sqlite3_vfs *pVfs,
164 const char *zFile,
165 sqlite3_file **ppFile,
danielk1977967a4a12007-08-20 14:23:44 +0000166 int flags,
167 int *pOutFlags
danielk1977b4b47412007-08-17 15:53:36 +0000168){
169 int rc = SQLITE_NOMEM;
170 sqlite3_file *pFile;
drhe5ae5732008-06-15 02:51:47 +0000171 pFile = (sqlite3_file *)sqlite3Malloc(pVfs->szOsFile);
danielk1977b4b47412007-08-17 15:53:36 +0000172 if( pFile ){
danielk1977967a4a12007-08-20 14:23:44 +0000173 rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags);
danielk1977b4b47412007-08-17 15:53:36 +0000174 if( rc!=SQLITE_OK ){
175 sqlite3_free(pFile);
176 }else{
177 *ppFile = pFile;
178 }
179 }
180 return rc;
181}
182int sqlite3OsCloseFree(sqlite3_file *pFile){
183 int rc = SQLITE_OK;
mlcreech40032982008-04-08 03:09:22 +0000184 assert( pFile );
185 rc = sqlite3OsClose(pFile);
186 sqlite3_free(pFile);
danielk1977b4b47412007-08-17 15:53:36 +0000187 return rc;
188}
189
drhd677b3d2007-08-20 22:48:41 +0000190/*
danielk1977c0fa4c52008-06-25 17:19:00 +0000191** The list of all registered VFS implementations.
drhd677b3d2007-08-20 22:48:41 +0000192*/
danielk197795e80d62008-09-02 17:18:51 +0000193static sqlite3_vfs * SQLITE_WSD vfsList = 0;
danielk19775c8f8582008-09-02 10:22:00 +0000194#define vfsList GLOBAL(sqlite3_vfs *, vfsList)
drhd677b3d2007-08-20 22:48:41 +0000195
196/*
197** Locate a VFS by name. If no name is given, simply return the
198** first VFS on the list.
199*/
200sqlite3_vfs *sqlite3_vfs_find(const char *zVfs){
drha4189802008-06-19 16:07:07 +0000201 sqlite3_vfs *pVfs = 0;
drh7e8b8482008-01-23 03:03:05 +0000202#ifndef SQLITE_MUTEX_NOOP
drh40257ff2008-06-13 18:24:27 +0000203 sqlite3_mutex *mutex;
204#endif
205#ifndef SQLITE_OMIT_AUTOINIT
206 int rc = sqlite3_initialize();
207 if( rc ) return 0;
208#endif
209#ifndef SQLITE_MUTEX_NOOP
danielk197759f8c082008-06-18 17:09:10 +0000210 mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
drh7e8b8482008-01-23 03:03:05 +0000211#endif
drhd677b3d2007-08-20 22:48:41 +0000212 sqlite3_mutex_enter(mutex);
213 for(pVfs = vfsList; pVfs; pVfs=pVfs->pNext){
214 if( zVfs==0 ) break;
215 if( strcmp(zVfs, pVfs->zName)==0 ) break;
216 }
drhd677b3d2007-08-20 22:48:41 +0000217 sqlite3_mutex_leave(mutex);
218 return pVfs;
danielk1977b4b47412007-08-17 15:53:36 +0000219}
220
drhd677b3d2007-08-20 22:48:41 +0000221/*
drhd677b3d2007-08-20 22:48:41 +0000222** Unlink a VFS from the linked list
223*/
224static void vfsUnlink(sqlite3_vfs *pVfs){
danielk197759f8c082008-06-18 17:09:10 +0000225 assert( sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)) );
drh9bc54492007-10-23 14:49:59 +0000226 if( pVfs==0 ){
227 /* No-op */
228 }else if( vfsList==pVfs ){
drhd677b3d2007-08-20 22:48:41 +0000229 vfsList = pVfs->pNext;
drh9bc54492007-10-23 14:49:59 +0000230 }else if( vfsList ){
drhd677b3d2007-08-20 22:48:41 +0000231 sqlite3_vfs *p = vfsList;
232 while( p->pNext && p->pNext!=pVfs ){
233 p = p->pNext;
234 }
235 if( p->pNext==pVfs ){
236 p->pNext = pVfs->pNext;
237 }
238 }
239}
240
241/*
242** Register a VFS with the system. It is harmless to register the same
243** VFS multiple times. The new VFS becomes the default if makeDflt is
244** true.
245*/
246int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
danielk1977c0fa4c52008-06-25 17:19:00 +0000247 sqlite3_mutex *mutex = 0;
drh40257ff2008-06-13 18:24:27 +0000248#ifndef SQLITE_OMIT_AUTOINIT
249 int rc = sqlite3_initialize();
250 if( rc ) return rc;
251#endif
danielk197771bc31c2008-06-26 08:29:34 +0000252 mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
drhd677b3d2007-08-20 22:48:41 +0000253 sqlite3_mutex_enter(mutex);
254 vfsUnlink(pVfs);
255 if( makeDflt || vfsList==0 ){
256 pVfs->pNext = vfsList;
257 vfsList = pVfs;
258 }else{
259 pVfs->pNext = vfsList->pNext;
danielk197795c8a542007-09-01 06:51:27 +0000260 vfsList->pNext = pVfs;
drhd677b3d2007-08-20 22:48:41 +0000261 }
danielk1977f1da17a2007-08-21 13:07:46 +0000262 assert(vfsList);
drhd677b3d2007-08-20 22:48:41 +0000263 sqlite3_mutex_leave(mutex);
264 return SQLITE_OK;
265}
266
267/*
268** Unregister a VFS so that it is no longer accessible.
269*/
270int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){
drh7e8b8482008-01-23 03:03:05 +0000271#ifndef SQLITE_MUTEX_NOOP
danielk197759f8c082008-06-18 17:09:10 +0000272 sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
drh7e8b8482008-01-23 03:03:05 +0000273#endif
drhd677b3d2007-08-20 22:48:41 +0000274 sqlite3_mutex_enter(mutex);
275 vfsUnlink(pVfs);
276 sqlite3_mutex_leave(mutex);
277 return SQLITE_OK;
278}