PageRenderTime 46ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/hphp/util/embedded-vfs.cpp

https://gitlab.com/iranjith4/hhvm
C++ | 275 lines | 211 code | 43 blank | 21 comment | 18 complexity | 8a779c3fe289ec98a90359348ca62671 MD5 | raw file
  1. /*
  2. +----------------------------------------------------------------------+
  3. | HipHop for PHP |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 2010-2016 Facebook, Inc. (http://www.facebook.com) |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 3.01 of the PHP license, |
  8. | that is bundled with this package in the file LICENSE, and is |
  9. | available through the world-wide-web at the following url: |
  10. | http://www.php.net/license/3_01.txt |
  11. | If you did not receive a copy of the PHP license and are unable to |
  12. | obtain it through the world-wide-web, please send a note to |
  13. | license@php.net so we can mail you a copy immediately. |
  14. +----------------------------------------------------------------------+
  15. */
  16. #include "hphp/util/embedded-vfs.h"
  17. /*
  18. * based on test_demovfs.c and test_multiplex.c in sqlite3
  19. */
  20. #include <sqlite3.h>
  21. #include <string.h>
  22. #include <assert.h>
  23. #include <stdlib.h>
  24. #include <stdio.h>
  25. #include <unistd.h>
  26. #include <sys/types.h>
  27. #include <sys/stat.h>
  28. #include <fcntl.h>
  29. #ifndef SQLITE_CORE
  30. #define SQLITE_CORE 1 /* Disable the API redefinition in sqlite3ext.h */
  31. #endif
  32. #include <sqlite3ext.h>
  33. namespace HPHP {
  34. /*
  35. ** For a build without mutexes, no-op the mutex calls.
  36. */
  37. #if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE==0
  38. #define sqlite3_mutex_alloc(X) ((sqlite3_mutex*)8)
  39. #define sqlite3_mutex_free(X)
  40. #define sqlite3_mutex_enter(X)
  41. #define sqlite3_mutex_try(X) SQLITE_OK
  42. #define sqlite3_mutex_leave(X)
  43. #define sqlite3_mutex_held(X) ((void)(X),1)
  44. #define sqlite3_mutex_notheld(X) ((void)(X),1)
  45. #endif /* SQLITE_THREADSAFE==0 */
  46. struct embeddedConn {
  47. sqlite3_file base;
  48. int fd;
  49. size_t offset;
  50. size_t len;
  51. };
  52. static struct {
  53. sqlite3_vfs* pOrigVfs;
  54. sqlite3_vfs sThisVfs;
  55. sqlite3_io_methods sIoMethodsV1;
  56. sqlite3_mutex* pMutex;
  57. int isInitialized;
  58. } gEmbedded;
  59. static void embeddedEnter() { sqlite3_mutex_enter(gEmbedded.pMutex); }
  60. static void embeddedLeave() { sqlite3_mutex_leave(gEmbedded.pMutex); }
  61. static int embeddedOpen(sqlite3_vfs *pVfs, const char *zName,
  62. sqlite3_file *pConn, int flags,
  63. int *pOutFlags) {
  64. memset(pConn, 0, pVfs->szOsFile);
  65. assert(zName || (flags & SQLITE_OPEN_DELETEONCLOSE));
  66. if (zName) {
  67. const char *p = strchr(zName, ':');
  68. unsigned long off, len;
  69. char c;
  70. if (p && sscanf(p + 1, "%lu:%lu%c", &off, &len, &c) == 2) {
  71. embeddedConn *eConn = (embeddedConn*)pConn;
  72. eConn->base.pMethods = &gEmbedded.sIoMethodsV1;
  73. char *tmp = strdup(zName);
  74. tmp[p - zName] = 0;
  75. eConn->fd = open(tmp, O_RDONLY, 0);
  76. free(tmp);
  77. if (eConn->fd < 0) return SQLITE_CANTOPEN;
  78. eConn->offset = off;
  79. eConn->len = len;
  80. *pOutFlags = SQLITE_OPEN_READONLY;
  81. return SQLITE_OK;
  82. }
  83. }
  84. sqlite3_vfs *pOrigVfs = gEmbedded.pOrigVfs; /* Real VFS */
  85. return pOrigVfs->xOpen(pOrigVfs, zName, pConn, flags, pOutFlags);
  86. }
  87. static int embeddedDelete(sqlite3_vfs* pVfs, const char* zName, int syncDir) {
  88. return gEmbedded.pOrigVfs->xDelete(gEmbedded.pOrigVfs, zName, syncDir);
  89. }
  90. static int embeddedAccess(sqlite3_vfs* a, const char* b, int c, int* d) {
  91. return gEmbedded.pOrigVfs->xAccess(gEmbedded.pOrigVfs, b, c, d);
  92. }
  93. static int embeddedFullPathname(sqlite3_vfs* a, const char* b, int c, char* d) {
  94. return gEmbedded.pOrigVfs->xFullPathname(gEmbedded.pOrigVfs, b, c, d);
  95. }
  96. static void* embeddedDlOpen(sqlite3_vfs* a, const char* b) {
  97. return gEmbedded.pOrigVfs->xDlOpen(gEmbedded.pOrigVfs, b);
  98. }
  99. static void embeddedDlError(sqlite3_vfs* a, int b, char* c) {
  100. gEmbedded.pOrigVfs->xDlError(gEmbedded.pOrigVfs, b, c);
  101. }
  102. static void (*embeddedDlSym(sqlite3_vfs* a, void* b, const char* c))() {
  103. return gEmbedded.pOrigVfs->xDlSym(gEmbedded.pOrigVfs, b, c);
  104. }
  105. static void embeddedDlClose(sqlite3_vfs* a, void* b) {
  106. gEmbedded.pOrigVfs->xDlClose(gEmbedded.pOrigVfs, b);
  107. }
  108. static int embeddedRandomness(sqlite3_vfs* a, int b, char* c) {
  109. return gEmbedded.pOrigVfs->xRandomness(gEmbedded.pOrigVfs, b, c);
  110. }
  111. static int embeddedSleep(sqlite3_vfs* a, int b) {
  112. return gEmbedded.pOrigVfs->xSleep(gEmbedded.pOrigVfs, b);
  113. }
  114. static int embeddedCurrentTime(sqlite3_vfs* a, double* b) {
  115. return gEmbedded.pOrigVfs->xCurrentTime(gEmbedded.pOrigVfs, b);
  116. }
  117. static int embeddedGetLastError(sqlite3_vfs* a, int b, char* c) {
  118. return gEmbedded.pOrigVfs->xGetLastError(gEmbedded.pOrigVfs, b, c);
  119. }
  120. static int embeddedCurrentTimeInt64(sqlite3_vfs* a, sqlite3_int64* b) {
  121. return gEmbedded.pOrigVfs->xCurrentTimeInt64(gEmbedded.pOrigVfs, b);
  122. }
  123. static int embeddedClose(sqlite3_file* pConn) {
  124. embeddedConn* p = (embeddedConn*)pConn;
  125. return close(p->fd) ? SQLITE_OK : SQLITE_ERROR;
  126. }
  127. static int embeddedRead(sqlite3_file* pConn, void* pBuf,
  128. int iAmt, sqlite3_int64 iOfst) {
  129. embeddedConn* p = (embeddedConn*)pConn;
  130. if (iOfst > p->len) return SQLITE_IOERR_READ;
  131. int rc = SQLITE_OK;
  132. if (iAmt + iOfst > p->len) {
  133. rc = SQLITE_IOERR_SHORT_READ;
  134. iAmt = p->len - iOfst;
  135. }
  136. iOfst += p->offset;
  137. embeddedEnter();
  138. if (lseek(p->fd, iOfst, SEEK_SET) != iOfst) {
  139. rc = SQLITE_IOERR_READ;
  140. } else if (read(p->fd, pBuf, iAmt) != iAmt) {
  141. rc = SQLITE_IOERR_READ;
  142. }
  143. embeddedLeave();
  144. return rc;
  145. }
  146. static int embeddedWrite(sqlite3_file* pConn, const void* pBuf,
  147. int iAmt, sqlite3_int64 iOfst) {
  148. return SQLITE_IOERR_WRITE;
  149. }
  150. static int embeddedTruncate(sqlite3_file* pConn, sqlite3_int64 size) {
  151. return SQLITE_IOERR_TRUNCATE;
  152. }
  153. static int embeddedSync(sqlite3_file* pConn, int flags) {
  154. return SQLITE_OK;
  155. }
  156. static int embeddedFileSize(sqlite3_file* pConn, sqlite3_int64* pSize) {
  157. embeddedConn* p = (embeddedConn*)pConn;
  158. *pSize = p->len;
  159. return SQLITE_OK;
  160. }
  161. static int embeddedLock(sqlite3_file* pConn, int lock) {
  162. return SQLITE_OK;
  163. }
  164. static int embeddedUnlock(sqlite3_file* pConn, int lock) {
  165. return SQLITE_OK;
  166. }
  167. static int embeddedCheckReservedLock(sqlite3_file* pConn, int* pResOut) {
  168. return SQLITE_IOERR_CHECKRESERVEDLOCK;
  169. }
  170. static int embeddedFileControl(sqlite3_file* pConn, int op, void* pArg) {
  171. return SQLITE_OK;
  172. }
  173. static int embeddedSectorSize(sqlite3_file* pConn) {
  174. return 0;
  175. }
  176. static int embeddedDeviceCharacteristics(sqlite3_file* pConn) {
  177. return 0;
  178. }
  179. int sqlite3_embedded_initialize(const char* zOrigVfsName, int makeDefault) {
  180. sqlite3_vfs* pOrigVfs;
  181. if (gEmbedded.isInitialized) return SQLITE_MISUSE;
  182. pOrigVfs = sqlite3_vfs_find(zOrigVfsName);
  183. if (pOrigVfs==0) return SQLITE_ERROR;
  184. assert(pOrigVfs!=&gEmbedded.sThisVfs);
  185. gEmbedded.pMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
  186. if (!gEmbedded.pMutex) {
  187. return SQLITE_NOMEM;
  188. }
  189. gEmbedded.isInitialized = 1;
  190. gEmbedded.pOrigVfs = pOrigVfs;
  191. gEmbedded.sThisVfs = *pOrigVfs;
  192. gEmbedded.sThisVfs.szOsFile += sizeof(embeddedConn);
  193. gEmbedded.sThisVfs.zName = "embedded";
  194. gEmbedded.sThisVfs.xOpen = embeddedOpen;
  195. gEmbedded.sThisVfs.xDelete = embeddedDelete;
  196. gEmbedded.sThisVfs.xAccess = embeddedAccess;
  197. gEmbedded.sThisVfs.xFullPathname = embeddedFullPathname;
  198. gEmbedded.sThisVfs.xDlOpen = embeddedDlOpen;
  199. gEmbedded.sThisVfs.xDlError = embeddedDlError;
  200. gEmbedded.sThisVfs.xDlSym = embeddedDlSym;
  201. gEmbedded.sThisVfs.xDlClose = embeddedDlClose;
  202. gEmbedded.sThisVfs.xRandomness = embeddedRandomness;
  203. gEmbedded.sThisVfs.xSleep = embeddedSleep;
  204. gEmbedded.sThisVfs.xCurrentTime = embeddedCurrentTime;
  205. gEmbedded.sThisVfs.xGetLastError = embeddedGetLastError;
  206. gEmbedded.sThisVfs.xCurrentTimeInt64 = embeddedCurrentTimeInt64;
  207. gEmbedded.sIoMethodsV1.iVersion = 1;
  208. gEmbedded.sIoMethodsV1.xClose = embeddedClose;
  209. gEmbedded.sIoMethodsV1.xRead = embeddedRead;
  210. gEmbedded.sIoMethodsV1.xWrite = embeddedWrite;
  211. gEmbedded.sIoMethodsV1.xTruncate = embeddedTruncate;
  212. gEmbedded.sIoMethodsV1.xSync = embeddedSync;
  213. gEmbedded.sIoMethodsV1.xFileSize = embeddedFileSize;
  214. gEmbedded.sIoMethodsV1.xLock = embeddedLock;
  215. gEmbedded.sIoMethodsV1.xUnlock = embeddedUnlock;
  216. gEmbedded.sIoMethodsV1.xCheckReservedLock = embeddedCheckReservedLock;
  217. gEmbedded.sIoMethodsV1.xFileControl = embeddedFileControl;
  218. gEmbedded.sIoMethodsV1.xSectorSize = embeddedSectorSize;
  219. gEmbedded.sIoMethodsV1.xDeviceCharacteristics =
  220. embeddedDeviceCharacteristics;
  221. sqlite3_vfs_register(&gEmbedded.sThisVfs, makeDefault);
  222. return SQLITE_OK;
  223. }
  224. int sqlite3_embedded_shutdown() {
  225. if ( gEmbedded.isInitialized==0 ) return SQLITE_MISUSE;
  226. gEmbedded.isInitialized = 0;
  227. sqlite3_mutex_free(gEmbedded.pMutex);
  228. sqlite3_vfs_unregister(&gEmbedded.sThisVfs);
  229. memset(&gEmbedded, 0, sizeof(gEmbedded));
  230. return SQLITE_OK;
  231. }
  232. }