PageRenderTime 45ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/src/test/sqlite3/sqlite-src-3070900/src/os.c

https://github.com/rogerz/uffs
C | 331 lines | 244 code | 10 blank | 77 comment | 23 complexity | 67936611299908c2e626612414b2a69b MD5 | raw file
  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. ** The default SQLite sqlite3_vfs implementations do not allocate
  21. ** memory (actually, os_unix.c allocates a small amount of memory
  22. ** from within OsOpen()), but some third-party implementations may.
  23. ** So we test the effects of a malloc() failing and the sqlite3OsXXX()
  24. ** function returning SQLITE_IOERR_NOMEM using the DO_OS_MALLOC_TEST macro.
  25. **
  26. ** The following functions are instrumented for malloc() failure
  27. ** testing:
  28. **
  29. ** sqlite3OsOpen()
  30. ** sqlite3OsRead()
  31. ** sqlite3OsWrite()
  32. ** sqlite3OsSync()
  33. ** sqlite3OsLock()
  34. **
  35. */
  36. #if defined(SQLITE_TEST)
  37. int sqlite3_memdebug_vfs_oom_test = 1;
  38. #define DO_OS_MALLOC_TEST(x) \
  39. if (sqlite3_memdebug_vfs_oom_test && (!x || !sqlite3IsMemJournal(x))) { \
  40. void *pTstAlloc = sqlite3Malloc(10); \
  41. if (!pTstAlloc) return SQLITE_IOERR_NOMEM; \
  42. sqlite3_free(pTstAlloc); \
  43. }
  44. #else
  45. #define DO_OS_MALLOC_TEST(x)
  46. #endif
  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. int sqlite3OsShmLock(sqlite3_file *id, int offset, int n, int flags){
  102. return id->pMethods->xShmLock(id, offset, n, flags);
  103. }
  104. void sqlite3OsShmBarrier(sqlite3_file *id){
  105. id->pMethods->xShmBarrier(id);
  106. }
  107. int sqlite3OsShmUnmap(sqlite3_file *id, int deleteFlag){
  108. return id->pMethods->xShmUnmap(id, deleteFlag);
  109. }
  110. int sqlite3OsShmMap(
  111. sqlite3_file *id, /* Database file handle */
  112. int iPage,
  113. int pgsz,
  114. int bExtend, /* True to extend file if necessary */
  115. void volatile **pp /* OUT: Pointer to mapping */
  116. ){
  117. return id->pMethods->xShmMap(id, iPage, pgsz, bExtend, pp);
  118. }
  119. /*
  120. ** The next group of routines are convenience wrappers around the
  121. ** VFS methods.
  122. */
  123. int sqlite3OsOpen(
  124. sqlite3_vfs *pVfs,
  125. const char *zPath,
  126. sqlite3_file *pFile,
  127. int flags,
  128. int *pFlagsOut
  129. ){
  130. int rc;
  131. DO_OS_MALLOC_TEST(0);
  132. /* 0x87f3f is a mask of SQLITE_OPEN_ flags that are valid to be passed
  133. ** down into the VFS layer. Some SQLITE_OPEN_ flags (for example,
  134. ** SQLITE_OPEN_FULLMUTEX or SQLITE_OPEN_SHAREDCACHE) are blocked before
  135. ** reaching the VFS. */
  136. rc = pVfs->xOpen(pVfs, zPath, pFile, flags & 0x87f7f, pFlagsOut);
  137. assert( rc==SQLITE_OK || pFile->pMethods==0 );
  138. return rc;
  139. }
  140. int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
  141. return pVfs->xDelete(pVfs, zPath, dirSync);
  142. }
  143. int sqlite3OsAccess(
  144. sqlite3_vfs *pVfs,
  145. const char *zPath,
  146. int flags,
  147. int *pResOut
  148. ){
  149. DO_OS_MALLOC_TEST(0);
  150. return pVfs->xAccess(pVfs, zPath, flags, pResOut);
  151. }
  152. int sqlite3OsFullPathname(
  153. sqlite3_vfs *pVfs,
  154. const char *zPath,
  155. int nPathOut,
  156. char *zPathOut
  157. ){
  158. zPathOut[0] = 0;
  159. return pVfs->xFullPathname(pVfs, zPath, nPathOut, zPathOut);
  160. }
  161. #ifndef SQLITE_OMIT_LOAD_EXTENSION
  162. void *sqlite3OsDlOpen(sqlite3_vfs *pVfs, const char *zPath){
  163. return pVfs->xDlOpen(pVfs, zPath);
  164. }
  165. void sqlite3OsDlError(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
  166. pVfs->xDlError(pVfs, nByte, zBufOut);
  167. }
  168. void (*sqlite3OsDlSym(sqlite3_vfs *pVfs, void *pHdle, const char *zSym))(void){
  169. return pVfs->xDlSym(pVfs, pHdle, zSym);
  170. }
  171. void sqlite3OsDlClose(sqlite3_vfs *pVfs, void *pHandle){
  172. pVfs->xDlClose(pVfs, pHandle);
  173. }
  174. #endif /* SQLITE_OMIT_LOAD_EXTENSION */
  175. int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
  176. return pVfs->xRandomness(pVfs, nByte, zBufOut);
  177. }
  178. int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){
  179. return pVfs->xSleep(pVfs, nMicro);
  180. }
  181. int sqlite3OsCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){
  182. int rc;
  183. /* IMPLEMENTATION-OF: R-49045-42493 SQLite will use the xCurrentTimeInt64()
  184. ** method to get the current date and time if that method is available
  185. ** (if iVersion is 2 or greater and the function pointer is not NULL) and
  186. ** will fall back to xCurrentTime() if xCurrentTimeInt64() is
  187. ** unavailable.
  188. */
  189. if( pVfs->iVersion>=2 && pVfs->xCurrentTimeInt64 ){
  190. rc = pVfs->xCurrentTimeInt64(pVfs, pTimeOut);
  191. }else{
  192. double r;
  193. rc = pVfs->xCurrentTime(pVfs, &r);
  194. *pTimeOut = (sqlite3_int64)(r*86400000.0);
  195. }
  196. return rc;
  197. }
  198. int sqlite3OsOpenMalloc(
  199. sqlite3_vfs *pVfs,
  200. const char *zFile,
  201. sqlite3_file **ppFile,
  202. int flags,
  203. int *pOutFlags
  204. ){
  205. int rc = SQLITE_NOMEM;
  206. sqlite3_file *pFile;
  207. pFile = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile);
  208. if( pFile ){
  209. rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags);
  210. if( rc!=SQLITE_OK ){
  211. sqlite3_free(pFile);
  212. }else{
  213. *ppFile = pFile;
  214. }
  215. }
  216. return rc;
  217. }
  218. int sqlite3OsCloseFree(sqlite3_file *pFile){
  219. int rc = SQLITE_OK;
  220. assert( pFile );
  221. rc = sqlite3OsClose(pFile);
  222. sqlite3_free(pFile);
  223. return rc;
  224. }
  225. /*
  226. ** This function is a wrapper around the OS specific implementation of
  227. ** sqlite3_os_init(). The purpose of the wrapper is to provide the
  228. ** ability to simulate a malloc failure, so that the handling of an
  229. ** error in sqlite3_os_init() by the upper layers can be tested.
  230. */
  231. int sqlite3OsInit(void){
  232. void *p = sqlite3_malloc(10);
  233. if( p==0 ) return SQLITE_NOMEM;
  234. sqlite3_free(p);
  235. return sqlite3_os_init();
  236. }
  237. /*
  238. ** The list of all registered VFS implementations.
  239. */
  240. static sqlite3_vfs * SQLITE_WSD vfsList = 0;
  241. #define vfsList GLOBAL(sqlite3_vfs *, vfsList)
  242. /*
  243. ** Locate a VFS by name. If no name is given, simply return the
  244. ** first VFS on the list.
  245. */
  246. sqlite3_vfs *sqlite3_vfs_find(const char *zVfs){
  247. sqlite3_vfs *pVfs = 0;
  248. #if SQLITE_THREADSAFE
  249. sqlite3_mutex *mutex;
  250. #endif
  251. #ifndef SQLITE_OMIT_AUTOINIT
  252. int rc = sqlite3_initialize();
  253. if( rc ) return 0;
  254. #endif
  255. #if SQLITE_THREADSAFE
  256. mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
  257. #endif
  258. sqlite3_mutex_enter(mutex);
  259. for(pVfs = vfsList; pVfs; pVfs=pVfs->pNext){
  260. if( zVfs==0 ) break;
  261. if( strcmp(zVfs, pVfs->zName)==0 ) break;
  262. }
  263. sqlite3_mutex_leave(mutex);
  264. return pVfs;
  265. }
  266. /*
  267. ** Unlink a VFS from the linked list
  268. */
  269. static void vfsUnlink(sqlite3_vfs *pVfs){
  270. assert( sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)) );
  271. if( pVfs==0 ){
  272. /* No-op */
  273. }else if( vfsList==pVfs ){
  274. vfsList = pVfs->pNext;
  275. }else if( vfsList ){
  276. sqlite3_vfs *p = vfsList;
  277. while( p->pNext && p->pNext!=pVfs ){
  278. p = p->pNext;
  279. }
  280. if( p->pNext==pVfs ){
  281. p->pNext = pVfs->pNext;
  282. }
  283. }
  284. }
  285. /*
  286. ** Register a VFS with the system. It is harmless to register the same
  287. ** VFS multiple times. The new VFS becomes the default if makeDflt is
  288. ** true.
  289. */
  290. int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
  291. MUTEX_LOGIC(sqlite3_mutex *mutex;)
  292. #ifndef SQLITE_OMIT_AUTOINIT
  293. int rc = sqlite3_initialize();
  294. if( rc ) return rc;
  295. #endif
  296. MUTEX_LOGIC( mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
  297. sqlite3_mutex_enter(mutex);
  298. vfsUnlink(pVfs);
  299. if( makeDflt || vfsList==0 ){
  300. pVfs->pNext = vfsList;
  301. vfsList = pVfs;
  302. }else{
  303. pVfs->pNext = vfsList->pNext;
  304. vfsList->pNext = pVfs;
  305. }
  306. assert(vfsList);
  307. sqlite3_mutex_leave(mutex);
  308. return SQLITE_OK;
  309. }
  310. /*
  311. ** Unregister a VFS so that it is no longer accessible.
  312. */
  313. int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){
  314. #if SQLITE_THREADSAFE
  315. sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
  316. #endif
  317. sqlite3_mutex_enter(mutex);
  318. vfsUnlink(pVfs);
  319. sqlite3_mutex_leave(mutex);
  320. return SQLITE_OK;
  321. }