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