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