/ Check-in [5b68dae3]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Simplifications to the localtime() interface. Fix the case where localtime_r() is available so that it works. Ticket [bd484a090c8077].
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 5b68dae320d0fa3dc433826811e5018a47461de7
User & Date: drh 2011-06-21 14:35:30
Context
2011-06-21
15:01
Rework the localtime logic yet again in order to make all branches reachable and to follow GNU standards for HAVE_LOCALTIME_R-type macros. Ticket [bd484a090c8077]. check-in: 17624809 user: drh tags: trunk
14:35
Simplifications to the localtime() interface. Fix the case where localtime_r() is available so that it works. Ticket [bd484a090c8077]. check-in: 5b68dae3 user: drh tags: trunk
13:46
Change the error message returned when localtime_r() fails to "local time unavailable". Ticket [bd484a090c8077] check-in: 0e82175f user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/date.c.

   408    408   static void clearYMD_HMS_TZ(DateTime *p){
   409    409     p->validYMD = 0;
   410    410     p->validHMS = 0;
   411    411     p->validTZ = 0;
   412    412   }
   413    413   
   414    414   #ifndef SQLITE_OMIT_LOCALTIME
   415         -
   416    415   /*
   417         -** The following three functions - osLocaltime_r(), osLocaltime_s() and
   418         -** osLocaltime() - are wrappers around system functions localtime_r(),
   419         -** localtime_s() and localtime(), respectively.
          416  +** The following routine implements the rough equivalent of localtime_r()
          417  +** using whatever operating-system specific localtime facility that
          418  +** is available.  This routine returns 0 on success and
          419  +** non-zero on any kind of error.
   420    420   **
   421         -** If the sqlite3GlobalConfig.bLocaltimeFault variable is true when one
   422         -** of the following wrappers is called, it returns an error.
          421  +** If the sqlite3GlobalConfig.bLocaltimeFault variable is true then this
          422  +** routine will always fail.
   423    423   */
          424  +int osLocaltime(time_t *t, struct tm *pTm){
          425  +  int rc;
   424    426   #ifndef SQLITE_OMIT_BUILTIN_TEST
   425         -
          427  +  if( sqlite3GlobalConfig.bLocaltimeFault ) return 1;
          428  +#endif
   426    429   #ifdef HAVE_LOCALTIME_R
   427         -static struct tm * osLocaltime_r(time_t *t, struct tm *pTm){
   428         -  if( sqlite3GlobalConfig.bLocaltimeFault ) return 0;
   429         -  return localtime_r(t);
   430         -}
          430  +  rc = localtime_r(t, pTm)==0;
   431    431   #elif defined(HAVE_LOCALTIME_S) && HAVE_LOCALTIME_S
   432         -static int osLocaltime_s(struct tm *pTm, time_t *t){
   433         -  if( sqlite3GlobalConfig.bLocaltimeFault ) return 1;
   434         -  return (int)localtime_s(pTm, t);
   435         -}
          432  +  rc = localtime_s(pTm, t);
   436    433   #else
   437         -static struct tm * osLocaltime(time_t *t){
   438         -  if( sqlite3GlobalConfig.bLocaltimeFault ) return 0;
   439         -  return localtime(t);
   440         -}
          434  +  {
          435  +    struct tm *pX;
          436  +    sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
          437  +    sqlite3_mutex_enter(mutex);
          438  +    pX = localtime(t);
          439  +    if( pX ) *pTm = *pX;
          440  +    sqlite3_mutex_leave(mutex);
          441  +    rc = pX==0;
          442  +  }
   441    443   #endif
   442         -
   443         -#else
   444         -# define osLocaltime_r(x,y) localtime_r(x,y)
   445         -# define osLocaltime_s(x,y) localtime_s(x,y)
   446         -# define osLocaltime(x)     localtime(x)
   447         -#endif
          444  +  return rc;
          445  +}
          446  +#endif /* SQLITE_OMIT_LOCALTIME */
   448    447   
   449    448   
          449  +#ifndef SQLITE_OMIT_LOCALTIME
   450    450   /*
   451    451   ** Compute the difference (in milliseconds) between localtime and UTC
   452    452   ** (a.k.a. GMT) for the time value p where p is in UTC. If no error occurs,
   453    453   ** return this value and set *pRc to SQLITE_OK. 
   454    454   **
   455    455   ** Or, if an error does occur, set *pRc to SQLITE_ERROR. The returned value
   456    456   ** is undefined in this case.
................................................................................
   458    458   static sqlite3_int64 localtimeOffset(
   459    459     DateTime *p,                    /* Date at which to calculate offset */
   460    460     sqlite3_context *pCtx,          /* Write error here if one occurs */
   461    461     int *pRc                        /* OUT: Error code. SQLITE_OK or ERROR */
   462    462   ){
   463    463     DateTime x, y;
   464    464     time_t t;
          465  +  struct tm sLocal;
          466  +
   465    467     x = *p;
   466    468     computeYMD_HMS(&x);
   467    469     if( x.Y<1971 || x.Y>=2038 ){
   468    470       x.Y = 2000;
   469    471       x.M = 1;
   470    472       x.D = 1;
   471    473       x.h = 0;
................................................................................
   475    477       int s = (int)(x.s + 0.5);
   476    478       x.s = s;
   477    479     }
   478    480     x.tz = 0;
   479    481     x.validJD = 0;
   480    482     computeJD(&x);
   481    483     t = (time_t)(x.iJD/1000 - 21086676*(i64)10000);
   482         -#ifdef HAVE_LOCALTIME_R
   483         -  {
   484         -    struct tm sLocal;
   485         -    if( 0==osLocaltime_r(&t, &sLocal) ){
   486         -      sqlite3_result_error(pCtx, "local time unavailable", -1);
   487         -      *pRc = SQLITE_ERROR;
   488         -      return 0;
   489         -    }
   490         -    y.Y = sLocal.tm_year + 1900;
   491         -    y.M = sLocal.tm_mon + 1;
   492         -    y.D = sLocal.tm_mday;
   493         -    y.h = sLocal.tm_hour;
   494         -    y.m = sLocal.tm_min;
   495         -    y.s = sLocal.tm_sec;
   496         -  }
   497         -#elif defined(HAVE_LOCALTIME_S) && HAVE_LOCALTIME_S
   498         -  {
   499         -    struct tm sLocal;
   500         -    if( 0!=osLocaltime_s(&sLocal, &t) ){
   501         -      sqlite3_result_error(pCtx, "local time unavailable", -1);
   502         -      *pRc = SQLITE_ERROR;
   503         -      return 0;
   504         -    }
   505         -    y.Y = sLocal.tm_year + 1900;
   506         -    y.M = sLocal.tm_mon + 1;
   507         -    y.D = sLocal.tm_mday;
   508         -    y.h = sLocal.tm_hour;
   509         -    y.m = sLocal.tm_min;
   510         -    y.s = sLocal.tm_sec;
   511         -  }
   512         -#else
   513         -  {
   514         -    struct tm *pTm;
   515         -    sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
   516         -    pTm = osLocaltime(&t);
   517         -    if( pTm ){
   518         -      y.Y = pTm->tm_year + 1900;
   519         -      y.M = pTm->tm_mon + 1;
   520         -      y.D = pTm->tm_mday;
   521         -      y.h = pTm->tm_hour;
   522         -      y.m = pTm->tm_min;
   523         -      y.s = pTm->tm_sec;
   524         -    }
   525         -    sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
   526         -    if( !pTm ){
   527         -      sqlite3_result_error(pCtx, "local time unavailable", -1);
   528         -      *pRc = SQLITE_ERROR;
   529         -      return 0;
   530         -    }
   531         -  }
   532         -#endif
          484  +  if( osLocaltime(&t, &sLocal) ){
          485  +    sqlite3_result_error(pCtx, "local time unavailable", -1);
          486  +    *pRc = SQLITE_ERROR;
          487  +    return 0;
          488  +  }
          489  +  y.Y = sLocal.tm_year + 1900;
          490  +  y.M = sLocal.tm_mon + 1;
          491  +  y.D = sLocal.tm_mday;
          492  +  y.h = sLocal.tm_hour;
          493  +  y.m = sLocal.tm_min;
          494  +  y.s = sLocal.tm_sec;
   533    495     y.validYMD = 1;
   534    496     y.validHMS = 1;
   535    497     y.validJD = 0;
   536    498     y.validTZ = 0;
   537    499     computeJD(&y);
   538    500     *pRc = SQLITE_OK;
   539    501     return y.iJD - x.iJD;