xref: /sqlite-3.40.0/src/os.c (revision 5d00d0a8)
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 ** $Id: os.c,v 1.127 2009/07/27 11:41:21 danielk1977 Exp $
17 */
18 #define _SQLITE_OS_C_ 1
19 #include "sqliteInt.h"
20 #undef _SQLITE_OS_C_
21 
22 /*
23 ** 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 */
39 #if defined(SQLITE_TEST) && (SQLITE_OS_WIN==0)
40   #define DO_OS_MALLOC_TEST(x) if (!x || !sqlite3IsMemJournal(x)) {     \
41     void *pTstAlloc = sqlite3Malloc(10);                             \
42     if (!pTstAlloc) return SQLITE_IOERR_NOMEM;                       \
43     sqlite3_free(pTstAlloc);                                         \
44   }
45 #else
46   #define DO_OS_MALLOC_TEST(x)
47 #endif
48 
49 /*
50 ** The following routines are convenience wrappers around methods
51 ** of the sqlite3_file object.  This is mostly just syntactic sugar. All
52 ** of this would be completely automatic if SQLite were coded using
53 ** C++ instead of plain old C.
54 */
55 int sqlite3OsClose(sqlite3_file *pId){
56   int rc = SQLITE_OK;
57   if( pId->pMethods ){
58     rc = pId->pMethods->xClose(pId);
59     pId->pMethods = 0;
60   }
61   return rc;
62 }
63 int sqlite3OsRead(sqlite3_file *id, void *pBuf, int amt, i64 offset){
64   DO_OS_MALLOC_TEST(id);
65   return id->pMethods->xRead(id, pBuf, amt, offset);
66 }
67 int sqlite3OsWrite(sqlite3_file *id, const void *pBuf, int amt, i64 offset){
68   DO_OS_MALLOC_TEST(id);
69   return id->pMethods->xWrite(id, pBuf, amt, offset);
70 }
71 int sqlite3OsTruncate(sqlite3_file *id, i64 size){
72   return id->pMethods->xTruncate(id, size);
73 }
74 int sqlite3OsSync(sqlite3_file *id, int flags){
75   DO_OS_MALLOC_TEST(id);
76   return id->pMethods->xSync(id, flags);
77 }
78 int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){
79   DO_OS_MALLOC_TEST(id);
80   return id->pMethods->xFileSize(id, pSize);
81 }
82 int sqlite3OsLock(sqlite3_file *id, int lockType){
83   DO_OS_MALLOC_TEST(id);
84   return id->pMethods->xLock(id, lockType);
85 }
86 int sqlite3OsUnlock(sqlite3_file *id, int lockType){
87   return id->pMethods->xUnlock(id, lockType);
88 }
89 int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut){
90   DO_OS_MALLOC_TEST(id);
91   return id->pMethods->xCheckReservedLock(id, pResOut);
92 }
93 int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){
94   return id->pMethods->xFileControl(id, op, pArg);
95 }
96 int sqlite3OsSectorSize(sqlite3_file *id){
97   int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize;
98   return (xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE);
99 }
100 int sqlite3OsDeviceCharacteristics(sqlite3_file *id){
101   return id->pMethods->xDeviceCharacteristics(id);
102 }
103 
104 /*
105 ** The next group of routines are convenience wrappers around the
106 ** VFS methods.
107 */
108 int sqlite3OsOpen(
109   sqlite3_vfs *pVfs,
110   const char *zPath,
111   sqlite3_file *pFile,
112   int flags,
113   int *pFlagsOut
114 ){
115   int rc;
116   DO_OS_MALLOC_TEST(0);
117   rc = pVfs->xOpen(pVfs, zPath, pFile, flags, pFlagsOut);
118   assert( rc==SQLITE_OK || pFile->pMethods==0 );
119   return rc;
120 }
121 int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
122   return pVfs->xDelete(pVfs, zPath, dirSync);
123 }
124 int sqlite3OsAccess(
125   sqlite3_vfs *pVfs,
126   const char *zPath,
127   int flags,
128   int *pResOut
129 ){
130   DO_OS_MALLOC_TEST(0);
131   return pVfs->xAccess(pVfs, zPath, flags, pResOut);
132 }
133 int sqlite3OsFullPathname(
134   sqlite3_vfs *pVfs,
135   const char *zPath,
136   int nPathOut,
137   char *zPathOut
138 ){
139   return pVfs->xFullPathname(pVfs, zPath, nPathOut, zPathOut);
140 }
141 #ifndef SQLITE_OMIT_LOAD_EXTENSION
142 void *sqlite3OsDlOpen(sqlite3_vfs *pVfs, const char *zPath){
143   return pVfs->xDlOpen(pVfs, zPath);
144 }
145 void sqlite3OsDlError(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
146   pVfs->xDlError(pVfs, nByte, zBufOut);
147 }
148 void (*sqlite3OsDlSym(sqlite3_vfs *pVfs, void *pHdle, const char *zSym))(void){
149   return pVfs->xDlSym(pVfs, pHdle, zSym);
150 }
151 void sqlite3OsDlClose(sqlite3_vfs *pVfs, void *pHandle){
152   pVfs->xDlClose(pVfs, pHandle);
153 }
154 #endif /* SQLITE_OMIT_LOAD_EXTENSION */
155 int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
156   return pVfs->xRandomness(pVfs, nByte, zBufOut);
157 }
158 int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){
159   return pVfs->xSleep(pVfs, nMicro);
160 }
161 int sqlite3OsCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
162   return pVfs->xCurrentTime(pVfs, pTimeOut);
163 }
164 
165 int sqlite3OsOpenMalloc(
166   sqlite3_vfs *pVfs,
167   const char *zFile,
168   sqlite3_file **ppFile,
169   int flags,
170   int *pOutFlags
171 ){
172   int rc = SQLITE_NOMEM;
173   sqlite3_file *pFile;
174   pFile = (sqlite3_file *)sqlite3Malloc(pVfs->szOsFile);
175   if( pFile ){
176     rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags);
177     if( rc!=SQLITE_OK ){
178       sqlite3_free(pFile);
179     }else{
180       *ppFile = pFile;
181     }
182   }
183   return rc;
184 }
185 int sqlite3OsCloseFree(sqlite3_file *pFile){
186   int rc = SQLITE_OK;
187   assert( pFile );
188   rc = sqlite3OsClose(pFile);
189   sqlite3_free(pFile);
190   return rc;
191 }
192 
193 /*
194 ** This function is a wrapper around the OS specific implementation of
195 ** sqlite3_os_init(). The purpose of the wrapper is to provide the
196 ** ability to simulate a malloc failure, so that the handling of an
197 ** error in sqlite3_os_init() by the upper layers can be tested.
198 */
199 int sqlite3OsInit(void){
200   void *p = sqlite3_malloc(10);
201   if( p==0 ) return SQLITE_NOMEM;
202   sqlite3_free(p);
203   return sqlite3_os_init();
204 }
205 
206 /*
207 ** The list of all registered VFS implementations.
208 */
209 static sqlite3_vfs * SQLITE_WSD vfsList = 0;
210 #define vfsList GLOBAL(sqlite3_vfs *, vfsList)
211 
212 /*
213 ** Locate a VFS by name.  If no name is given, simply return the
214 ** first VFS on the list.
215 */
216 sqlite3_vfs *sqlite3_vfs_find(const char *zVfs){
217   sqlite3_vfs *pVfs = 0;
218 #if SQLITE_THREADSAFE
219   sqlite3_mutex *mutex;
220 #endif
221 #ifndef SQLITE_OMIT_AUTOINIT
222   int rc = sqlite3_initialize();
223   if( rc ) return 0;
224 #endif
225 #if SQLITE_THREADSAFE
226   mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
227 #endif
228   sqlite3_mutex_enter(mutex);
229   for(pVfs = vfsList; pVfs; pVfs=pVfs->pNext){
230     if( zVfs==0 ) break;
231     if( strcmp(zVfs, pVfs->zName)==0 ) break;
232   }
233   sqlite3_mutex_leave(mutex);
234   return pVfs;
235 }
236 
237 /*
238 ** Unlink a VFS from the linked list
239 */
240 static void vfsUnlink(sqlite3_vfs *pVfs){
241   assert( sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)) );
242   if( pVfs==0 ){
243     /* No-op */
244   }else if( vfsList==pVfs ){
245     vfsList = pVfs->pNext;
246   }else if( vfsList ){
247     sqlite3_vfs *p = vfsList;
248     while( p->pNext && p->pNext!=pVfs ){
249       p = p->pNext;
250     }
251     if( p->pNext==pVfs ){
252       p->pNext = pVfs->pNext;
253     }
254   }
255 }
256 
257 /*
258 ** Register a VFS with the system.  It is harmless to register the same
259 ** VFS multiple times.  The new VFS becomes the default if makeDflt is
260 ** true.
261 */
262 int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
263   sqlite3_mutex *mutex = 0;
264 #ifndef SQLITE_OMIT_AUTOINIT
265   int rc = sqlite3_initialize();
266   if( rc ) return rc;
267 #endif
268   mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
269   sqlite3_mutex_enter(mutex);
270   vfsUnlink(pVfs);
271   if( makeDflt || vfsList==0 ){
272     pVfs->pNext = vfsList;
273     vfsList = pVfs;
274   }else{
275     pVfs->pNext = vfsList->pNext;
276     vfsList->pNext = pVfs;
277   }
278   assert(vfsList);
279   sqlite3_mutex_leave(mutex);
280   return SQLITE_OK;
281 }
282 
283 /*
284 ** Unregister a VFS so that it is no longer accessible.
285 */
286 int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){
287 #if SQLITE_THREADSAFE
288   sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
289 #endif
290   sqlite3_mutex_enter(mutex);
291   vfsUnlink(pVfs);
292   sqlite3_mutex_leave(mutex);
293   return SQLITE_OK;
294 }
295