2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2014 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 +----------------------------------------------------------------------+
16 #include "hphp/util/embedded-vfs.h"
19 * based on test_demovfs.c and test_multiplex.c in sqlite3
28 #include <sys/types.h>
34 #define SQLITE_CORE 1 /* Disable the API redefinition in sqlite3ext.h */
36 #include <sqlite3ext.h>
41 ** For a build without mutexes, no-op the mutex calls.
43 #if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE==0
44 #define sqlite3_mutex_alloc(X) ((sqlite3_mutex*)8)
45 #define sqlite3_mutex_free(X)
46 #define sqlite3_mutex_enter(X)
47 #define sqlite3_mutex_try(X) SQLITE_OK
48 #define sqlite3_mutex_leave(X)
49 #define sqlite3_mutex_held(X) ((void)(X),1)
50 #define sqlite3_mutex_notheld(X) ((void)(X),1)
51 #endif /* SQLITE_THREADSAFE==0 */
61 sqlite3_vfs
* pOrigVfs
;
63 sqlite3_io_methods sIoMethodsV1
;
64 sqlite3_mutex
* pMutex
;
68 static void embeddedEnter() { sqlite3_mutex_enter(gEmbedded
.pMutex
); }
69 static void embeddedLeave() { sqlite3_mutex_leave(gEmbedded
.pMutex
); }
71 static int embeddedOpen(sqlite3_vfs
*pVfs
, const char *zName
,
72 sqlite3_file
*pConn
, int flags
,
74 memset(pConn
, 0, pVfs
->szOsFile
);
75 assert(zName
|| (flags
& SQLITE_OPEN_DELETEONCLOSE
));
78 const char *p
= strchr(zName
, ':');
79 unsigned long off
, len
;
81 if (p
&& sscanf(p
+ 1, "%lu:%lu%c", &off
, &len
, &c
) == 2) {
82 embeddedConn
*eConn
= (embeddedConn
*)pConn
;
83 eConn
->base
.pMethods
= &gEmbedded
.sIoMethodsV1
;
84 char *tmp
= strdup(zName
);
86 eConn
->fd
= open(tmp
, O_RDONLY
, 0);
88 if (eConn
->fd
< 0) return SQLITE_CANTOPEN
;
91 *pOutFlags
= SQLITE_OPEN_READONLY
;
96 sqlite3_vfs
*pOrigVfs
= gEmbedded
.pOrigVfs
; /* Real VFS */
97 return pOrigVfs
->xOpen(pOrigVfs
, zName
, pConn
, flags
, pOutFlags
);
100 static int embeddedDelete(sqlite3_vfs
* pVfs
, const char* zName
, int syncDir
) {
101 return gEmbedded
.pOrigVfs
->xDelete(gEmbedded
.pOrigVfs
, zName
, syncDir
);
104 static int embeddedAccess(sqlite3_vfs
* a
, const char* b
, int c
, int* d
) {
105 return gEmbedded
.pOrigVfs
->xAccess(gEmbedded
.pOrigVfs
, b
, c
, d
);
108 static int embeddedFullPathname(sqlite3_vfs
* a
, const char* b
, int c
, char* d
) {
109 return gEmbedded
.pOrigVfs
->xFullPathname(gEmbedded
.pOrigVfs
, b
, c
, d
);
112 static void* embeddedDlOpen(sqlite3_vfs
* a
, const char* b
) {
113 return gEmbedded
.pOrigVfs
->xDlOpen(gEmbedded
.pOrigVfs
, b
);
116 static void embeddedDlError(sqlite3_vfs
* a
, int b
, char* c
) {
117 gEmbedded
.pOrigVfs
->xDlError(gEmbedded
.pOrigVfs
, b
, c
);
120 static void (*embeddedDlSym(sqlite3_vfs
* a
, void* b
, const char* c
))() {
121 return gEmbedded
.pOrigVfs
->xDlSym(gEmbedded
.pOrigVfs
, b
, c
);
124 static void embeddedDlClose(sqlite3_vfs
* a
, void* b
) {
125 gEmbedded
.pOrigVfs
->xDlClose(gEmbedded
.pOrigVfs
, b
);
128 static int embeddedRandomness(sqlite3_vfs
* a
, int b
, char* c
) {
129 return gEmbedded
.pOrigVfs
->xRandomness(gEmbedded
.pOrigVfs
, b
, c
);
132 static int embeddedSleep(sqlite3_vfs
* a
, int b
) {
133 return gEmbedded
.pOrigVfs
->xSleep(gEmbedded
.pOrigVfs
, b
);
136 static int embeddedCurrentTime(sqlite3_vfs
* a
, double* b
) {
137 return gEmbedded
.pOrigVfs
->xCurrentTime(gEmbedded
.pOrigVfs
, b
);
140 static int embeddedGetLastError(sqlite3_vfs
* a
, int b
, char* c
) {
141 return gEmbedded
.pOrigVfs
->xGetLastError(gEmbedded
.pOrigVfs
, b
, c
);
144 static int embeddedCurrentTimeInt64(sqlite3_vfs
* a
, sqlite3_int64
* b
) {
145 return gEmbedded
.pOrigVfs
->xCurrentTimeInt64(gEmbedded
.pOrigVfs
, b
);
148 static int embeddedClose(sqlite3_file
* pConn
) {
149 embeddedConn
* p
= (embeddedConn
*)pConn
;
150 return close(p
->fd
) ? SQLITE_OK
: SQLITE_ERROR
;
153 static int embeddedRead(sqlite3_file
* pConn
, void* pBuf
,
154 int iAmt
, sqlite3_int64 iOfst
) {
155 embeddedConn
* p
= (embeddedConn
*)pConn
;
156 if (iOfst
> p
->len
) return SQLITE_IOERR_READ
;
158 if (iAmt
+ iOfst
> p
->len
) {
159 rc
= SQLITE_IOERR_SHORT_READ
;
160 iAmt
= p
->len
- iOfst
;
164 if (lseek(p
->fd
, iOfst
, SEEK_SET
) != iOfst
) {
165 rc
= SQLITE_IOERR_READ
;
166 } else if (read(p
->fd
, pBuf
, iAmt
) != iAmt
) {
167 rc
= SQLITE_IOERR_READ
;
173 static int embeddedWrite(sqlite3_file
* pConn
, const void* pBuf
,
174 int iAmt
, sqlite3_int64 iOfst
) {
175 return SQLITE_IOERR_WRITE
;
178 static int embeddedTruncate(sqlite3_file
* pConn
, sqlite3_int64 size
) {
179 return SQLITE_IOERR_TRUNCATE
;
182 static int embeddedSync(sqlite3_file
* pConn
, int flags
) {
186 static int embeddedFileSize(sqlite3_file
* pConn
, sqlite3_int64
* pSize
) {
187 embeddedConn
* p
= (embeddedConn
*)pConn
;
192 static int embeddedLock(sqlite3_file
* pConn
, int lock
) {
196 static int embeddedUnlock(sqlite3_file
* pConn
, int lock
) {
200 static int embeddedCheckReservedLock(sqlite3_file
* pConn
, int* pResOut
) {
201 return SQLITE_IOERR_CHECKRESERVEDLOCK
;
204 static int embeddedFileControl(sqlite3_file
* pConn
, int op
, void* pArg
) {
208 static int embeddedSectorSize(sqlite3_file
* pConn
) {
212 static int embeddedDeviceCharacteristics(sqlite3_file
* pConn
) {
216 int sqlite3_embedded_initialize(const char* zOrigVfsName
, int makeDefault
) {
217 sqlite3_vfs
* pOrigVfs
;
218 if (gEmbedded
.isInitialized
) return SQLITE_MISUSE
;
219 pOrigVfs
= sqlite3_vfs_find(zOrigVfsName
);
220 if (pOrigVfs
==0) return SQLITE_ERROR
;
221 assert(pOrigVfs
!=&gEmbedded
.sThisVfs
);
222 gEmbedded
.pMutex
= sqlite3_mutex_alloc(SQLITE_MUTEX_FAST
);
223 if (!gEmbedded
.pMutex
) {
227 gEmbedded
.isInitialized
= 1;
228 gEmbedded
.pOrigVfs
= pOrigVfs
;
229 gEmbedded
.sThisVfs
= *pOrigVfs
;
230 gEmbedded
.sThisVfs
.szOsFile
+= sizeof(embeddedConn
);
231 gEmbedded
.sThisVfs
.zName
= "embedded";
232 gEmbedded
.sThisVfs
.xOpen
= embeddedOpen
;
233 gEmbedded
.sThisVfs
.xDelete
= embeddedDelete
;
234 gEmbedded
.sThisVfs
.xAccess
= embeddedAccess
;
235 gEmbedded
.sThisVfs
.xFullPathname
= embeddedFullPathname
;
236 gEmbedded
.sThisVfs
.xDlOpen
= embeddedDlOpen
;
237 gEmbedded
.sThisVfs
.xDlError
= embeddedDlError
;
238 gEmbedded
.sThisVfs
.xDlSym
= embeddedDlSym
;
239 gEmbedded
.sThisVfs
.xDlClose
= embeddedDlClose
;
240 gEmbedded
.sThisVfs
.xRandomness
= embeddedRandomness
;
241 gEmbedded
.sThisVfs
.xSleep
= embeddedSleep
;
242 gEmbedded
.sThisVfs
.xCurrentTime
= embeddedCurrentTime
;
243 gEmbedded
.sThisVfs
.xGetLastError
= embeddedGetLastError
;
244 gEmbedded
.sThisVfs
.xCurrentTimeInt64
= embeddedCurrentTimeInt64
;
246 gEmbedded
.sIoMethodsV1
.iVersion
= 1;
247 gEmbedded
.sIoMethodsV1
.xClose
= embeddedClose
;
248 gEmbedded
.sIoMethodsV1
.xRead
= embeddedRead
;
249 gEmbedded
.sIoMethodsV1
.xWrite
= embeddedWrite
;
250 gEmbedded
.sIoMethodsV1
.xTruncate
= embeddedTruncate
;
251 gEmbedded
.sIoMethodsV1
.xSync
= embeddedSync
;
252 gEmbedded
.sIoMethodsV1
.xFileSize
= embeddedFileSize
;
253 gEmbedded
.sIoMethodsV1
.xLock
= embeddedLock
;
254 gEmbedded
.sIoMethodsV1
.xUnlock
= embeddedUnlock
;
255 gEmbedded
.sIoMethodsV1
.xCheckReservedLock
= embeddedCheckReservedLock
;
256 gEmbedded
.sIoMethodsV1
.xFileControl
= embeddedFileControl
;
257 gEmbedded
.sIoMethodsV1
.xSectorSize
= embeddedSectorSize
;
258 gEmbedded
.sIoMethodsV1
.xDeviceCharacteristics
=
259 embeddedDeviceCharacteristics
;
261 sqlite3_vfs_register(&gEmbedded
.sThisVfs
, makeDefault
);
266 int sqlite3_embedded_shutdown() {
267 if ( gEmbedded
.isInitialized
==0 ) return SQLITE_MISUSE
;
268 gEmbedded
.isInitialized
= 0;
269 sqlite3_mutex_free(gEmbedded
.pMutex
);
270 sqlite3_vfs_unregister(&gEmbedded
.sThisVfs
);
271 memset(&gEmbedded
, 0, sizeof(gEmbedded
));