Thanks to visit codestin.com
Credit goes to chromium.googlesource.com

blob: 0c6ac8eb56ad91c31e6f70f23675a9feebd87cf8 [file] [log] [blame]
dane1ab2192009-08-17 15:16:191/*
2** 2009 August 17
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** The code in this file is used for testing SQLite. It is not part of
14** the source code used in production systems.
15**
16** Specifically, this file tests the effect of errors while initializing
17** the various pluggable sub-systems from within sqlite3_initialize().
18** If an error occurs in sqlite3_initialize() the following should be
19** true:
20**
21** 1) An error code is returned to the user, and
22** 2) A subsequent call to sqlite3_shutdown() calls the shutdown method
23** of those subsystems that were initialized, and
24** 3) A subsequent call to sqlite3_initialize() attempts to initialize
25** the remaining, uninitialized, subsystems.
26*/
27
28#include "sqliteInt.h"
29#include <string.h>
drh064b6812024-07-30 15:49:0230#include "tclsqlite.h"
dane1ab2192009-08-17 15:16:1931
32static struct Wrapped {
dan22e21ff2011-11-08 20:08:4433 sqlite3_pcache_methods2 pcache;
34 sqlite3_mem_methods mem;
35 sqlite3_mutex_methods mutex;
dane1ab2192009-08-17 15:16:1936
larrybrbc917382023-06-07 08:40:3137 int mem_init; /* True if mem subsystem is initialized */
38 int mem_fail; /* True to fail mem subsystem initialization */
39 int mutex_init; /* True if mutex subsystem is initialized */
40 int mutex_fail; /* True to fail mutex subsystem initialization */
41 int pcache_init; /* True if pcache subsystem is initialized */
42 int pcache_fail; /* True to fail pcache subsystem initialization */
dane1ab2192009-08-17 15:16:1943} wrapped;
44
45static int wrMemInit(void *pAppData){
46 int rc;
47 if( wrapped.mem_fail ){
48 rc = SQLITE_ERROR;
49 }else{
50 rc = wrapped.mem.xInit(wrapped.mem.pAppData);
51 }
52 if( rc==SQLITE_OK ){
53 wrapped.mem_init = 1;
54 }
55 return rc;
56}
57static void wrMemShutdown(void *pAppData){
58 wrapped.mem.xShutdown(wrapped.mem.pAppData);
59 wrapped.mem_init = 0;
60}
61static void *wrMemMalloc(int n) {return wrapped.mem.xMalloc(n);}
62static void wrMemFree(void *p) {wrapped.mem.xFree(p);}
63static void *wrMemRealloc(void *p, int n) {return wrapped.mem.xRealloc(p, n);}
64static int wrMemSize(void *p) {return wrapped.mem.xSize(p);}
65static int wrMemRoundup(int n) {return wrapped.mem.xRoundup(n);}
66
67
68static int wrMutexInit(void){
69 int rc;
70 if( wrapped.mutex_fail ){
71 rc = SQLITE_ERROR;
72 }else{
73 rc = wrapped.mutex.xMutexInit();
74 }
75 if( rc==SQLITE_OK ){
76 wrapped.mutex_init = 1;
77 }
78 return rc;
79}
80static int wrMutexEnd(void){
81 wrapped.mutex.xMutexEnd();
82 wrapped.mutex_init = 0;
83 return SQLITE_OK;
84}
85static sqlite3_mutex *wrMutexAlloc(int e){
86 return wrapped.mutex.xMutexAlloc(e);
87}
88static void wrMutexFree(sqlite3_mutex *p){
89 wrapped.mutex.xMutexFree(p);
90}
91static void wrMutexEnter(sqlite3_mutex *p){
92 wrapped.mutex.xMutexEnter(p);
93}
94static int wrMutexTry(sqlite3_mutex *p){
95 return wrapped.mutex.xMutexTry(p);
96}
97static void wrMutexLeave(sqlite3_mutex *p){
98 wrapped.mutex.xMutexLeave(p);
99}
100static int wrMutexHeld(sqlite3_mutex *p){
101 return wrapped.mutex.xMutexHeld(p);
102}
103static int wrMutexNotheld(sqlite3_mutex *p){
104 return wrapped.mutex.xMutexNotheld(p);
105}
106
107
108
109static int wrPCacheInit(void *pArg){
110 int rc;
111 if( wrapped.pcache_fail ){
112 rc = SQLITE_ERROR;
113 }else{
114 rc = wrapped.pcache.xInit(wrapped.pcache.pArg);
115 }
116 if( rc==SQLITE_OK ){
117 wrapped.pcache_init = 1;
118 }
119 return rc;
120}
121static void wrPCacheShutdown(void *pArg){
122 wrapped.pcache.xShutdown(wrapped.pcache.pArg);
123 wrapped.pcache_init = 0;
124}
125
dan22e21ff2011-11-08 20:08:44126static sqlite3_pcache *wrPCacheCreate(int a, int b, int c){
127 return wrapped.pcache.xCreate(a, b, c);
dane1ab2192009-08-17 15:16:19128}
129static void wrPCacheCachesize(sqlite3_pcache *p, int n){
130 wrapped.pcache.xCachesize(p, n);
131}
132static int wrPCachePagecount(sqlite3_pcache *p){
133 return wrapped.pcache.xPagecount(p);
134}
dan22e21ff2011-11-08 20:08:44135static sqlite3_pcache_page *wrPCacheFetch(sqlite3_pcache *p, unsigned a, int b){
dane1ab2192009-08-17 15:16:19136 return wrapped.pcache.xFetch(p, a, b);
137}
dan22e21ff2011-11-08 20:08:44138static void wrPCacheUnpin(sqlite3_pcache *p, sqlite3_pcache_page *a, int b){
dane1ab2192009-08-17 15:16:19139 wrapped.pcache.xUnpin(p, a, b);
140}
dan22e21ff2011-11-08 20:08:44141static void wrPCacheRekey(
142 sqlite3_pcache *p,
143 sqlite3_pcache_page *a,
144 unsigned b,
145 unsigned c
146){
dane1ab2192009-08-17 15:16:19147 wrapped.pcache.xRekey(p, a, b, c);
148}
149static void wrPCacheTruncate(sqlite3_pcache *p, unsigned a){
150 wrapped.pcache.xTruncate(p, a);
151}
152static void wrPCacheDestroy(sqlite3_pcache *p){
153 wrapped.pcache.xDestroy(p);
154}
155
156static void installInitWrappers(void){
157 sqlite3_mutex_methods mutexmethods = {
158 wrMutexInit, wrMutexEnd, wrMutexAlloc,
159 wrMutexFree, wrMutexEnter, wrMutexTry,
160 wrMutexLeave, wrMutexHeld, wrMutexNotheld
161 };
dan22e21ff2011-11-08 20:08:44162 sqlite3_pcache_methods2 pcachemethods = {
drh81ef0f92011-11-13 21:44:03163 1, 0,
dane1ab2192009-08-17 15:16:19164 wrPCacheInit, wrPCacheShutdown, wrPCacheCreate,
165 wrPCacheCachesize, wrPCachePagecount, wrPCacheFetch,
166 wrPCacheUnpin, wrPCacheRekey, wrPCacheTruncate,
167 wrPCacheDestroy
168 };
169 sqlite3_mem_methods memmethods = {
170 wrMemMalloc, wrMemFree, wrMemRealloc,
171 wrMemSize, wrMemRoundup, wrMemInit,
172 wrMemShutdown,
173 0
174 };
175
176 memset(&wrapped, 0, sizeof(wrapped));
177
178 sqlite3_shutdown();
179 sqlite3_config(SQLITE_CONFIG_GETMUTEX, &wrapped.mutex);
180 sqlite3_config(SQLITE_CONFIG_GETMALLOC, &wrapped.mem);
dan22e21ff2011-11-08 20:08:44181 sqlite3_config(SQLITE_CONFIG_GETPCACHE2, &wrapped.pcache);
dane1ab2192009-08-17 15:16:19182 sqlite3_config(SQLITE_CONFIG_MUTEX, &mutexmethods);
183 sqlite3_config(SQLITE_CONFIG_MALLOC, &memmethods);
dan22e21ff2011-11-08 20:08:44184 sqlite3_config(SQLITE_CONFIG_PCACHE2, &pcachemethods);
dane1ab2192009-08-17 15:16:19185}
186
mistachkin7617e4a2016-07-28 17:11:20187static int SQLITE_TCLAPI init_wrapper_install(
dane1ab2192009-08-17 15:16:19188 ClientData clientData, /* Unused */
189 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
190 int objc, /* Number of arguments */
191 Tcl_Obj *CONST objv[] /* Command arguments */
192){
193 int i;
194 installInitWrappers();
195 for(i=1; i<objc; i++){
196 char *z = Tcl_GetString(objv[i]);
197 if( strcmp(z, "mem")==0 ){
198 wrapped.mem_fail = 1;
199 }else if( strcmp(z, "mutex")==0 ){
200 wrapped.mutex_fail = 1;
201 }else if( strcmp(z, "pcache")==0 ){
202 wrapped.pcache_fail = 1;
dane1ab2192009-08-17 15:16:19203 }else{
stephan065c0a62025-03-08 06:53:06204 Tcl_AppendResult(interp, "Unknown argument: \"", z, "\"", NULL);
dane1ab2192009-08-17 15:16:19205 return TCL_ERROR;
206 }
207 }
208 return TCL_OK;
209}
210
mistachkin7617e4a2016-07-28 17:11:20211static int SQLITE_TCLAPI init_wrapper_uninstall(
dane1ab2192009-08-17 15:16:19212 ClientData clientData, /* Unused */
213 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
214 int objc, /* Number of arguments */
215 Tcl_Obj *CONST objv[] /* Command arguments */
216){
217 if( objc!=1 ){
218 Tcl_WrongNumArgs(interp, 1, objv, "");
219 return TCL_ERROR;
220 }
221
dane1ab2192009-08-17 15:16:19222 sqlite3_shutdown();
223 sqlite3_config(SQLITE_CONFIG_MUTEX, &wrapped.mutex);
224 sqlite3_config(SQLITE_CONFIG_MALLOC, &wrapped.mem);
dan22e21ff2011-11-08 20:08:44225 sqlite3_config(SQLITE_CONFIG_PCACHE2, &wrapped.pcache);
dane1ab2192009-08-17 15:16:19226 return TCL_OK;
227}
228
mistachkin7617e4a2016-07-28 17:11:20229static int SQLITE_TCLAPI init_wrapper_clear(
dane1ab2192009-08-17 15:16:19230 ClientData clientData, /* Unused */
231 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
232 int objc, /* Number of arguments */
233 Tcl_Obj *CONST objv[] /* Command arguments */
234){
235 if( objc!=1 ){
236 Tcl_WrongNumArgs(interp, 1, objv, "");
237 return TCL_ERROR;
238 }
239
240 wrapped.mem_fail = 0;
241 wrapped.mutex_fail = 0;
242 wrapped.pcache_fail = 0;
dane1ab2192009-08-17 15:16:19243 return TCL_OK;
244}
245
mistachkin7617e4a2016-07-28 17:11:20246static int SQLITE_TCLAPI init_wrapper_query(
dane1ab2192009-08-17 15:16:19247 ClientData clientData, /* Unused */
248 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
249 int objc, /* Number of arguments */
250 Tcl_Obj *CONST objv[] /* Command arguments */
251){
252 Tcl_Obj *pRet;
253
254 if( objc!=1 ){
255 Tcl_WrongNumArgs(interp, 1, objv, "");
256 return TCL_ERROR;
257 }
258
259 pRet = Tcl_NewObj();
260 if( wrapped.mutex_init ){
261 Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj("mutex", -1));
262 }
263 if( wrapped.mem_init ){
264 Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj("mem", -1));
265 }
266 if( wrapped.pcache_init ){
267 Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj("pcache", -1));
268 }
dane1ab2192009-08-17 15:16:19269
270 Tcl_SetObjResult(interp, pRet);
271 return TCL_OK;
272}
273
dane1ab2192009-08-17 15:16:19274int Sqlitetest_init_Init(Tcl_Interp *interp){
275 static struct {
276 char *zName;
277 Tcl_ObjCmdProc *xProc;
278 } aObjCmd[] = {
279 {"init_wrapper_install", init_wrapper_install},
280 {"init_wrapper_query", init_wrapper_query },
281 {"init_wrapper_uninstall", init_wrapper_uninstall},
282 {"init_wrapper_clear", init_wrapper_clear}
283 };
284 int i;
285
286 for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
287 Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, 0, 0);
288 }
289
290 return TCL_OK;
291}