xref: /sqlite-3.40.0/src/os.c (revision 8a29dfde)
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 #ifdef SQLITE_TEST
38   #define DO_OS_MALLOC_TEST if (1) {            \
39     void *pTstAlloc = sqlite3_malloc(10);       \
40     if (!pTstAlloc) return SQLITE_IOERR_NOMEM;  \
41     sqlite3_free(pTstAlloc);                    \
42   }
43 #else
44   #define DO_OS_MALLOC_TEST
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;
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;
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;
74   return id->pMethods->xSync(id, flags);
75 }
76 int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){
77   return id->pMethods->xFileSize(id, pSize);
78 }
79 int sqlite3OsLock(sqlite3_file *id, int lockType){
80   DO_OS_MALLOC_TEST;
81   return id->pMethods->xLock(id, lockType);
82 }
83 int sqlite3OsUnlock(sqlite3_file *id, int lockType){
84   return id->pMethods->xUnlock(id, lockType);
85 }
86 int sqlite3OsCheckReservedLock(sqlite3_file *id){
87   return id->pMethods->xCheckReservedLock(id);
88 }
89 int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){
90   return id->pMethods->xFileControl(id,op,pArg);
91 }
92 int sqlite3OsSectorSize(sqlite3_file *id){
93   int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize;
94   return (xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE);
95 }
96 int sqlite3OsDeviceCharacteristics(sqlite3_file *id){
97   return id->pMethods->xDeviceCharacteristics(id);
98 }
99 
100 /*
101 ** The next group of routines are convenience wrappers around the
102 ** VFS methods.
103 */
104 int sqlite3OsOpen(
105   sqlite3_vfs *pVfs,
106   const char *zPath,
107   sqlite3_file *pFile,
108   int flags,
109   int *pFlagsOut
110 ){
111   DO_OS_MALLOC_TEST;
112   return pVfs->xOpen(pVfs, zPath, pFile, flags, pFlagsOut);
113 }
114 int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
115   return pVfs->xDelete(pVfs, zPath, dirSync);
116 }
117 int sqlite3OsAccess(sqlite3_vfs *pVfs, const char *zPath, int flags){
118   int rc;
119 #ifdef SQLITE_TEST
120   void *pTstAlloc = sqlite3_malloc(10);
121   if (!pTstAlloc) return -1;
122   sqlite3_free(pTstAlloc);
123 #endif
124   rc = pVfs->xAccess(pVfs, zPath, flags);
125   assert( rc==0 || rc==1 );
126   return rc;
127 }
128 int sqlite3OsGetTempname(sqlite3_vfs *pVfs, int nBufOut, char *zBufOut){
129   return pVfs->xGetTempname(pVfs, nBufOut, zBufOut);
130 }
131 int sqlite3OsFullPathname(
132   sqlite3_vfs *pVfs,
133   const char *zPath,
134   int nPathOut,
135   char *zPathOut
136 ){
137   return pVfs->xFullPathname(pVfs, zPath, nPathOut, zPathOut);
138 }
139 void *sqlite3OsDlOpen(sqlite3_vfs *pVfs, const char *zPath){
140   return pVfs->xDlOpen(pVfs, zPath);
141 }
142 void sqlite3OsDlError(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
143   pVfs->xDlError(pVfs, nByte, zBufOut);
144 }
145 void *sqlite3OsDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){
146   return pVfs->xDlSym(pVfs, pHandle, zSymbol);
147 }
148 void sqlite3OsDlClose(sqlite3_vfs *pVfs, void *pHandle){
149   pVfs->xDlClose(pVfs, pHandle);
150 }
151 int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
152   return pVfs->xRandomness(pVfs, nByte, zBufOut);
153 }
154 int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){
155   return pVfs->xSleep(pVfs, nMicro);
156 }
157 int sqlite3OsCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
158   return pVfs->xCurrentTime(pVfs, pTimeOut);
159 }
160 
161 int sqlite3OsOpenMalloc(
162   sqlite3_vfs *pVfs,
163   const char *zFile,
164   sqlite3_file **ppFile,
165   int flags,
166   int *pOutFlags
167 ){
168   int rc = SQLITE_NOMEM;
169   sqlite3_file *pFile;
170   pFile = (sqlite3_file *)sqlite3_malloc(pVfs->szOsFile);
171   if( pFile ){
172     rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags);
173     if( rc!=SQLITE_OK ){
174       sqlite3_free(pFile);
175     }else{
176       *ppFile = pFile;
177     }
178   }
179   return rc;
180 }
181 int sqlite3OsCloseFree(sqlite3_file *pFile){
182   int rc = SQLITE_OK;
183   assert( pFile );
184   rc = sqlite3OsClose(pFile);
185   sqlite3_free(pFile);
186   return rc;
187 }
188 
189 /*
190 ** The list of all registered VFS implementations.  This list is
191 ** initialized to the single VFS returned by sqlite3OsDefaultVfs()
192 ** upon the first call to sqlite3_vfs_find().
193 */
194 static sqlite3_vfs *vfsList = 0;
195 
196 /*
197 ** Locate a VFS by name.  If no name is given, simply return the
198 ** first VFS on the list.
199 */
200 sqlite3_vfs *sqlite3_vfs_find(const char *zVfs){
201 #ifndef SQLITE_MUTEX_NOOP
202   sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
203 #endif
204   sqlite3_vfs *pVfs = 0;
205   static int isInit = 0;
206   sqlite3_mutex_enter(mutex);
207   if( !isInit ){
208     vfsList = sqlite3OsDefaultVfs();
209     isInit = 1;
210   }
211   for(pVfs = vfsList; pVfs; pVfs=pVfs->pNext){
212     if( zVfs==0 ) break;
213     if( strcmp(zVfs, pVfs->zName)==0 ) break;
214   }
215   sqlite3_mutex_leave(mutex);
216   return pVfs;
217 }
218 
219 /*
220 ** Unlink a VFS from the linked list
221 */
222 static void vfsUnlink(sqlite3_vfs *pVfs){
223   assert( sqlite3_mutex_held(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)) );
224   if( pVfs==0 ){
225     /* No-op */
226   }else if( vfsList==pVfs ){
227     vfsList = pVfs->pNext;
228   }else if( vfsList ){
229     sqlite3_vfs *p = vfsList;
230     while( p->pNext && p->pNext!=pVfs ){
231       p = p->pNext;
232     }
233     if( p->pNext==pVfs ){
234       p->pNext = pVfs->pNext;
235     }
236   }
237 }
238 
239 /*
240 ** Register a VFS with the system.  It is harmless to register the same
241 ** VFS multiple times.  The new VFS becomes the default if makeDflt is
242 ** true.
243 */
244 int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
245 #ifndef SQLITE_MUTEX_NOOP
246   sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
247 #endif
248   sqlite3_vfs_find(0);  /* Make sure we are initialized */
249   sqlite3_mutex_enter(mutex);
250   vfsUnlink(pVfs);
251   if( makeDflt || vfsList==0 ){
252     pVfs->pNext = vfsList;
253     vfsList = pVfs;
254   }else{
255     pVfs->pNext = vfsList->pNext;
256     vfsList->pNext = pVfs;
257   }
258   assert(vfsList);
259   sqlite3_mutex_leave(mutex);
260   return SQLITE_OK;
261 }
262 
263 /*
264 ** Unregister a VFS so that it is no longer accessible.
265 */
266 int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){
267 #ifndef SQLITE_MUTEX_NOOP
268   sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
269 #endif
270   sqlite3_mutex_enter(mutex);
271   vfsUnlink(pVfs);
272   sqlite3_mutex_leave(mutex);
273   return SQLITE_OK;
274 }
275 
276 /*
277 ** Provide a default sqlite3OsDefaultVfs() implementation in the
278 ** cases where none of the standard backends are used.
279 */
280 #if !OS_UNIX && !OS_WIN && !OS_OS2
281 sqlite3_vfs *sqlite3OsDefaultVfs(void){ return 0; }
282 #endif
283