aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <>2022-02-10 21:26:53 +0000
committerdrh <>2022-02-10 21:26:53 +0000
commitd7e185ce5d6699e94db1f8431b38c809ac204a6c (patch)
treebd172263c5497b6012a0c7095ac4933037f74361 /src
parenteadccaa9269560e567b4ae0440de6e24745e6142 (diff)
downloadsqlite-d7e185ce5d6699e94db1f8431b38c809ac204a6c.tar.gz
sqlite-d7e185ce5d6699e94db1f8431b38c809ac204a6c.zip
Enhance SQLITE_TESTCTRL_LOCALTIME_FAULT so that is able to install an
alternative localtime() interface so that the localtime logic an be better tested. FossilOrigin-Name: 6e25cb0890e8cdc63c9a21e841844d066267fc32ad143527843f7c8d05612b53
Diffstat (limited to 'src')
-rw-r--r--src/date.c22
-rw-r--r--src/global.c1
-rw-r--r--src/main.c20
-rw-r--r--src/sqliteInt.h1
-rw-r--r--src/test1.c2
5 files changed, 38 insertions, 8 deletions
diff --git a/src/date.c b/src/date.c
index 3225a5528..1306847f8 100644
--- a/src/date.c
+++ b/src/date.c
@@ -503,8 +503,10 @@ static void clearYMD_HMS_TZ(DateTime *p){
** is available. This routine returns 0 on success and
** non-zero on any kind of error.
**
-** If the sqlite3GlobalConfig.bLocaltimeFault variable is true then this
-** routine will always fail.
+** If the sqlite3GlobalConfig.bLocaltimeFault variable is non-zero then this
+** routine will always fail. If bLocaltimeFault is nonzero and
+** sqlite3GlobalConfig.xAltLocaltime is not NULL, then xAltLocaltime() is
+** invoked in place of the OS-defined localtime() function.
**
** EVIDENCE-OF: R-62172-00036 In this implementation, the standard C
** library function localtime_r() is used to assist in the calculation of
@@ -520,7 +522,13 @@ static int osLocaltime(time_t *t, struct tm *pTm){
sqlite3_mutex_enter(mutex);
pX = localtime(t);
#ifndef SQLITE_UNTESTABLE
- if( sqlite3GlobalConfig.bLocaltimeFault ) pX = 0;
+ if( sqlite3GlobalConfig.bLocaltimeFault ){
+ if( sqlite3GlobalConfig.xAltLocaltime!=0 ){
+ return sqlite3GlobalConfig.xAltLocaltime((const void*)t,(void*)pTm);
+ }else{
+ pX = 0;
+ }
+ }
#endif
if( pX ) *pTm = *pX;
#if SQLITE_THREADSAFE>0
@@ -529,7 +537,13 @@ static int osLocaltime(time_t *t, struct tm *pTm){
rc = pX==0;
#else
#ifndef SQLITE_UNTESTABLE
- if( sqlite3GlobalConfig.bLocaltimeFault ) return 1;
+ if( sqlite3GlobalConfig.bLocaltimeFault ){
+ if( sqlite3GlobalConfig.xAltLocaltime!=0 ){
+ return sqlite3GlobalConfig.xAltLocaltime((const void*)t,(void*)pTm);
+ }else{
+ return 1;
+ }
+ }
#endif
#if HAVE_LOCALTIME_R
rc = localtime_r(t, pTm)==0;
diff --git a/src/global.c b/src/global.c
index 34b7d9583..6ad3bb465 100644
--- a/src/global.c
+++ b/src/global.c
@@ -286,6 +286,7 @@ SQLITE_WSD struct Sqlite3Config sqlite3Config = {
0, /* xTestCallback */
#endif
0, /* bLocaltimeFault */
+ 0, /* xAltLocaltime */
0x7ffffffe, /* iOnceResetThreshold */
SQLITE_DEFAULT_SORTERREF_SIZE, /* szSorterRef */
0, /* iPrngSeed */
diff --git a/src/main.c b/src/main.c
index e8b775a21..f34e981d5 100644
--- a/src/main.c
+++ b/src/main.c
@@ -4161,13 +4161,27 @@ int sqlite3_test_control(int op, ...){
break;
}
- /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, int onoff);
+ /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, onoff, xAlt);
**
- ** If parameter onoff is non-zero, subsequent calls to localtime()
- ** and its variants fail. If onoff is zero, undo this setting.
+ ** If parameter onoff is 1, subsequent calls to localtime() fail.
+ ** If 2, then invoke xAlt() instead of localtime(). If 0, normal
+ ** processing.
+ **
+ ** xAlt arguments are void pointers, but they really want to be:
+ **
+ ** int xAlt(const time_t*, struct tm*);
+ **
+ ** xAlt should write results in to struct tm object of its 2nd argument
+ ** and return zero on success, or return non-zero on failure.
*/
case SQLITE_TESTCTRL_LOCALTIME_FAULT: {
sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int);
+ if( sqlite3GlobalConfig.bLocaltimeFault==2 ){
+ sqlite3GlobalConfig.xAltLocaltime =
+ va_arg(ap, int(*)(const void*,void*));
+ }else{
+ sqlite3GlobalConfig.xAltLocaltime = 0;
+ }
break;
}
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 1ed600f4d..c8dbec2f1 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -3936,6 +3936,7 @@ struct Sqlite3Config {
int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */
#endif
int bLocaltimeFault; /* True to fail localtime() calls */
+ int (*xAltLocaltime)(const void*,void*); /* Alternative localtime() routine */
int iOnceResetThreshold; /* When to reset OP_Once counters */
u32 szSorterRef; /* Min size in bytes to use sorter-refs */
unsigned int iPrngSeed; /* Alternative fixed seed for the PRNG */
diff --git a/src/test1.c b/src/test1.c
index 05aa97539..3eba08449 100644
--- a/src/test1.c
+++ b/src/test1.c
@@ -7258,7 +7258,7 @@ static int SQLITE_TCLAPI test_test_control(
return TCL_ERROR;
}
if( Tcl_GetBooleanFromObj(interp, objv[2], &val) ) return TCL_ERROR;
- sqlite3_test_control(iFlag, val);
+ sqlite3_test_control(iFlag, val!=0);
break;
}