00001 /* 00002 ** 2005 November 29 00003 ** 00004 ** The author disclaims copyright to this source code. In place of 00005 ** a legal notice, here is a blessing: 00006 ** 00007 ** May you do good and not evil. 00008 ** May you find forgiveness for yourself and forgive others. 00009 ** May you share freely, never taking more than you give. 00010 ** 00011 ****************************************************************************** 00012 ** 00013 ** This file contains OS interface code that is common to all 00014 ** architectures. 00015 ** 00016 ** $Id: os.c,v 1.124 2008/10/07 15:25:48 drh Exp $ 00017 */ 00018 #define _SQLITE_OS_C_ 1 00019 #include "sqliteInt.h" 00020 #undef _SQLITE_OS_C_ 00021 00022 /* 00023 ** The default SQLite sqlite3_vfs implementations do not allocate 00024 ** memory (actually, os_unix.c allocates a small amount of memory 00025 ** from within OsOpen()), but some third-party implementations may. 00026 ** So we test the effects of a malloc() failing and the sqlite3OsXXX() 00027 ** function returning SQLITE_IOERR_NOMEM using the DO_OS_MALLOC_TEST macro. 00028 ** 00029 ** The following functions are instrumented for malloc() failure 00030 ** testing: 00031 ** 00032 ** sqlite3OsOpen() 00033 ** sqlite3OsRead() 00034 ** sqlite3OsWrite() 00035 ** sqlite3OsSync() 00036 ** sqlite3OsLock() 00037 ** 00038 */ 00039 #if defined(SQLITE_TEST) && (SQLITE_OS_WIN==0) 00040 #define DO_OS_MALLOC_TEST if (1) { \ 00041 void *pTstAlloc = sqlite3Malloc(10); \ 00042 if (!pTstAlloc) return SQLITE_IOERR_NOMEM; \ 00043 sqlite3_free(pTstAlloc); \ 00044 } 00045 #else 00046 #define DO_OS_MALLOC_TEST 00047 #endif 00048 00049 /* 00050 ** The following routines are convenience wrappers around methods 00051 ** of the sqlite3_file object. This is mostly just syntactic sugar. All 00052 ** of this would be completely automatic if SQLite were coded using 00053 ** C++ instead of plain old C. 00054 */ 00055 int sqlite3OsClose(sqlite3_file *pId){ 00056 int rc = SQLITE_OK; 00057 if( pId->pMethods ){ 00058 rc = pId->pMethods->xClose(pId); 00059 pId->pMethods = 0; 00060 } 00061 return rc; 00062 } 00063 int sqlite3OsRead(sqlite3_file *id, void *pBuf, int amt, i64 offset){ 00064 DO_OS_MALLOC_TEST; 00065 return id->pMethods->xRead(id, pBuf, amt, offset); 00066 } 00067 int sqlite3OsWrite(sqlite3_file *id, const void *pBuf, int amt, i64 offset){ 00068 DO_OS_MALLOC_TEST; 00069 return id->pMethods->xWrite(id, pBuf, amt, offset); 00070 } 00071 int sqlite3OsTruncate(sqlite3_file *id, i64 size){ 00072 return id->pMethods->xTruncate(id, size); 00073 } 00074 int sqlite3OsSync(sqlite3_file *id, int flags){ 00075 DO_OS_MALLOC_TEST; 00076 return id->pMethods->xSync(id, flags); 00077 } 00078 int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){ 00079 DO_OS_MALLOC_TEST; 00080 return id->pMethods->xFileSize(id, pSize); 00081 } 00082 int sqlite3OsLock(sqlite3_file *id, int lockType){ 00083 DO_OS_MALLOC_TEST; 00084 return id->pMethods->xLock(id, lockType); 00085 } 00086 int sqlite3OsUnlock(sqlite3_file *id, int lockType){ 00087 return id->pMethods->xUnlock(id, lockType); 00088 } 00089 int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut){ 00090 DO_OS_MALLOC_TEST; 00091 return id->pMethods->xCheckReservedLock(id, pResOut); 00092 } 00093 int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){ 00094 return id->pMethods->xFileControl(id, op, pArg); 00095 } 00096 int sqlite3OsSectorSize(sqlite3_file *id){ 00097 int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize; 00098 return (xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE); 00099 } 00100 int sqlite3OsDeviceCharacteristics(sqlite3_file *id){ 00101 return id->pMethods->xDeviceCharacteristics(id); 00102 } 00103 00104 /* 00105 ** The next group of routines are convenience wrappers around the 00106 ** VFS methods. 00107 */ 00108 int sqlite3OsOpen( 00109 sqlite3_vfs *pVfs, 00110 const char *zPath, 00111 sqlite3_file *pFile, 00112 int flags, 00113 int *pFlagsOut 00114 ){ 00115 DO_OS_MALLOC_TEST; 00116 return pVfs->xOpen(pVfs, zPath, pFile, flags, pFlagsOut); 00117 } 00118 int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ 00119 return pVfs->xDelete(pVfs, zPath, dirSync); 00120 } 00121 int sqlite3OsAccess( 00122 sqlite3_vfs *pVfs, 00123 const char *zPath, 00124 int flags, 00125 int *pResOut 00126 ){ 00127 DO_OS_MALLOC_TEST; 00128 return pVfs->xAccess(pVfs, zPath, flags, pResOut); 00129 } 00130 int sqlite3OsFullPathname( 00131 sqlite3_vfs *pVfs, 00132 const char *zPath, 00133 int nPathOut, 00134 char *zPathOut 00135 ){ 00136 return pVfs->xFullPathname(pVfs, zPath, nPathOut, zPathOut); 00137 } 00138 #ifndef SQLITE_OMIT_LOAD_EXTENSION 00139 void *sqlite3OsDlOpen(sqlite3_vfs *pVfs, const char *zPath){ 00140 return pVfs->xDlOpen(pVfs, zPath); 00141 } 00142 void sqlite3OsDlError(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ 00143 pVfs->xDlError(pVfs, nByte, zBufOut); 00144 } 00145 void *sqlite3OsDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){ 00146 return pVfs->xDlSym(pVfs, pHandle, zSymbol); 00147 } 00148 void sqlite3OsDlClose(sqlite3_vfs *pVfs, void *pHandle){ 00149 pVfs->xDlClose(pVfs, pHandle); 00150 } 00151 #endif /* SQLITE_OMIT_LOAD_EXTENSION */ 00152 int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ 00153 return pVfs->xRandomness(pVfs, nByte, zBufOut); 00154 } 00155 int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){ 00156 return pVfs->xSleep(pVfs, nMicro); 00157 } 00158 int sqlite3OsCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){ 00159 return pVfs->xCurrentTime(pVfs, pTimeOut); 00160 } 00161 00162 int sqlite3OsOpenMalloc( 00163 sqlite3_vfs *pVfs, 00164 const char *zFile, 00165 sqlite3_file **ppFile, 00166 int flags, 00167 int *pOutFlags 00168 ){ 00169 int rc = SQLITE_NOMEM; 00170 sqlite3_file *pFile; 00171 pFile = (sqlite3_file *)sqlite3Malloc(pVfs->szOsFile); 00172 if( pFile ){ 00173 rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags); 00174 if( rc!=SQLITE_OK ){ 00175 sqlite3_free(pFile); 00176 }else{ 00177 *ppFile = pFile; 00178 } 00179 } 00180 return rc; 00181 } 00182 int sqlite3OsCloseFree(sqlite3_file *pFile){ 00183 int rc = SQLITE_OK; 00184 assert( pFile ); 00185 rc = sqlite3OsClose(pFile); 00186 sqlite3_free(pFile); 00187 return rc; 00188 } 00189 00190 /* 00191 ** The list of all registered VFS implementations. 00192 */ 00193 static sqlite3_vfs * SQLITE_WSD vfsList = 0; 00194 #define vfsList GLOBAL(sqlite3_vfs *, vfsList) 00195 00196 /* 00197 ** Locate a VFS by name. If no name is given, simply return the 00198 ** first VFS on the list. 00199 */ 00200 sqlite3_vfs *sqlite3_vfs_find(const char *zVfs){ 00201 sqlite3_vfs *pVfs = 0; 00202 #if SQLITE_THREADSAFE 00203 sqlite3_mutex *mutex; 00204 #endif 00205 #ifndef SQLITE_OMIT_AUTOINIT 00206 int rc = sqlite3_initialize(); 00207 if( rc ) return 0; 00208 #endif 00209 #if SQLITE_THREADSAFE 00210 mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); 00211 #endif 00212 sqlite3_mutex_enter(mutex); 00213 for(pVfs = vfsList; pVfs; pVfs=pVfs->pNext){ 00214 if( zVfs==0 ) break; 00215 if( strcmp(zVfs, pVfs->zName)==0 ) break; 00216 } 00217 sqlite3_mutex_leave(mutex); 00218 return pVfs; 00219 } 00220 00221 /* 00222 ** Unlink a VFS from the linked list 00223 */ 00224 static void vfsUnlink(sqlite3_vfs *pVfs){ 00225 assert( sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)) ); 00226 if( pVfs==0 ){ 00227 /* No-op */ 00228 }else if( vfsList==pVfs ){ 00229 vfsList = pVfs->pNext; 00230 }else if( vfsList ){ 00231 sqlite3_vfs *p = vfsList; 00232 while( p->pNext && p->pNext!=pVfs ){ 00233 p = p->pNext; 00234 } 00235 if( p->pNext==pVfs ){ 00236 p->pNext = pVfs->pNext; 00237 } 00238 } 00239 } 00240 00241 /* 00242 ** Register a VFS with the system. It is harmless to register the same 00243 ** VFS multiple times. The new VFS becomes the default if makeDflt is 00244 ** true. 00245 */ 00246 int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){ 00247 sqlite3_mutex *mutex = 0; 00248 #ifndef SQLITE_OMIT_AUTOINIT 00249 int rc = sqlite3_initialize(); 00250 if( rc ) return rc; 00251 #endif 00252 mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); 00253 sqlite3_mutex_enter(mutex); 00254 vfsUnlink(pVfs); 00255 if( makeDflt || vfsList==0 ){ 00256 pVfs->pNext = vfsList; 00257 vfsList = pVfs; 00258 }else{ 00259 pVfs->pNext = vfsList->pNext; 00260 vfsList->pNext = pVfs; 00261 } 00262 assert(vfsList); 00263 sqlite3_mutex_leave(mutex); 00264 return SQLITE_OK; 00265 } 00266 00267 /* 00268 ** Unregister a VFS so that it is no longer accessible. 00269 */ 00270 int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){ 00271 #if SQLITE_THREADSAFE 00272 sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); 00273 #endif 00274 sqlite3_mutex_enter(mutex); 00275 vfsUnlink(pVfs); 00276 sqlite3_mutex_leave(mutex); 00277 return SQLITE_OK; 00278 }
ContextLogger2—ContextLogger2 Logger Daemon Internals—Generated on Mon May 2 13:49:55 2011 by Doxygen 1.6.1