From 5c6f1819d5033b2443a165b12b81b0343bec6456 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Fri, 20 Nov 2015 09:43:58 -0500 Subject: [svn-r28416] Description: Refactor time conversion code to put all the system-specific changes into one routine, H5_make_time, in H5system.c. Tested on: MacOSX/64 10.11.1 (amazon) w/serial & parallel (h5committest forthcoming) --- src/H5Omtime.c | 45 +++++------------------------ src/H5private.h | 11 ++------ src/H5system.c | 87 +++++++++++++++++++++++++++++++++++++++++++-------------- 3 files changed, 76 insertions(+), 67 deletions(-) diff --git a/src/H5Omtime.c b/src/H5Omtime.c index 272e54a..c61fa66 100644 --- a/src/H5Omtime.c +++ b/src/H5Omtime.c @@ -96,9 +96,6 @@ const H5O_msg_class_t H5O_MSG_MTIME_NEW[1] = {{ /* Current version of new mtime information */ #define H5O_MTIME_VERSION 1 -/* Track whether tzset routine was called */ -static hbool_t ntzset = FALSE; - /* Declare a free list to manage the time_t struct */ H5FL_DEFINE(time_t); @@ -148,7 +145,7 @@ H5O_mtime_new_decode(H5F_t H5_ATTR_UNUSED *f, hid_t H5_ATTR_UNUSED dxpl_id, H5O_ /* The return value */ if (NULL==(mesg = H5FL_MALLOC(time_t))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); *mesg = (time_t)tmp_time; /* Set return value */ @@ -183,8 +180,8 @@ H5O_mtime_decode(H5F_t H5_ATTR_UNUSED *f, hid_t H5_ATTR_UNUSED dxpl_id, H5O_t H5 unsigned H5_ATTR_UNUSED mesg_flags, unsigned H5_ATTR_UNUSED *ioflags, const uint8_t *p) { time_t *mesg, the_time; - int i; struct tm tm; + int i; /* Local index variable */ void *ret_value = NULL; /* Return value */ FUNC_ENTER_NOAPI_NOINIT @@ -193,50 +190,22 @@ H5O_mtime_decode(H5F_t H5_ATTR_UNUSED *f, hid_t H5_ATTR_UNUSED dxpl_id, H5O_t H5 HDassert(f); HDassert(p); - /* Initialize time zone information */ - if(!ntzset) { - HDtzset(); - ntzset = TRUE; - } /* end if */ - /* decode */ for(i = 0; i < 14; i++) if(!HDisdigit(p[i])) HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "badly formatted modification time message") - /* - * Convert YYYYMMDDhhmmss UTC to a time_t. This is a little problematic - * because mktime() operates on local times. We convert to local time - * and then figure out the adjustment based on the local time zone and - * daylight savings setting. - */ + /* Convert YYYYMMDDhhmmss UTC to a time_t. */ HDmemset(&tm, 0, sizeof tm); - tm.tm_year = (p[0]-'0')*1000 + (p[1]-'0')*100 + - (p[2]-'0')*10 + (p[3]-'0') - 1900; + tm.tm_year = (p[0]-'0')*1000 + (p[1]-'0')*100 + (p[2]-'0')*10 + (p[3]-'0') - 1900; tm.tm_mon = (p[4]-'0')*10 + (p[5]-'0') - 1; tm.tm_mday = (p[6]-'0')*10 + (p[7]-'0'); tm.tm_hour = (p[8]-'0')*10 + (p[9]-'0'); tm.tm_min = (p[10]-'0')*10 + (p[11]-'0'); tm.tm_sec = (p[12]-'0')*10 + (p[13]-'0'); - tm.tm_isdst = -1; /*figure it out*/ - if((time_t)-1 == (the_time = HDmktime(&tm))) - HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "badly formatted modification time message") - -#if defined(H5_HAVE_TM_GMTOFF) - /* BSD-like systems */ - the_time += tm.tm_gmtoff; -#elif defined(H5_HAVE_TIMEZONE) - the_time -= HDgettimezone() - (tm.tm_isdst ? 3600 : 0); -#else - /* - * The catch-all. If we can't convert a character string universal - * coordinated time to a time_t value reliably then we can't decode the - * modification time message. This really isn't as bad as it sounds -- the - * only way a user can get the modification time is from our internal - * query routines, which can gracefully recover. - */ - HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to obtain local timezone information") -#endif + tm.tm_isdst = -1; /* (figure it out) */ + if((time_t)-1 == (the_time = H5_make_time(&tm))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "can't construct time info") /* The return value */ if(NULL == (mesg = H5FL_MALLOC(time_t))) diff --git a/src/H5private.h b/src/H5private.h index b678512..837ca75 100644 --- a/src/H5private.h +++ b/src/H5private.h @@ -935,14 +935,6 @@ H5_DLL int HDfprintf (FILE *stream, const char *fmt, ...); #ifndef HDgets #define HDgets(S) gets(S) #endif /* HDgets */ -#ifndef H5_HAVE_TM_GMTOFF -#ifdef H5_HAVE_TIMEZONE - #ifndef HDgettimezone - #define HDgettimezone() HDget_timezone() - #endif /* HDgettimezone */ - H5_DLL long int HDget_timezone(void); -#endif /* H5_HAVE_TIMEZONE */ -#endif /* H5_HAVE_TM_GMTOFF */ #ifndef HDgettimeofday #define HDgettimeofday(S,P) gettimeofday(S,P) #endif /* HDgettimeofday */ @@ -2505,6 +2497,9 @@ H5_DLL uint32_t H5_checksum_lookup3(const void *data, size_t len, uint32_t initv H5_DLL uint32_t H5_checksum_metadata(const void *data, size_t len, uint32_t initval); H5_DLL uint32_t H5_hash_string(const char *str); +/* Time related routines */ +H5_DLL time_t H5_make_time(struct tm *tm); + /* Functions for building paths, etc. */ H5_DLL herr_t H5_build_extpath(const char *, char ** /*out*/ ); diff --git a/src/H5system.c b/src/H5system.c index 0de920c..05f1a70 100644 --- a/src/H5system.c +++ b/src/H5system.c @@ -73,6 +73,9 @@ /* Local Variables */ /*******************/ +/* Track whether tzset routine was called */ +static hbool_t H5_ntzset = FALSE; + /*------------------------------------------------------------------------- * Function: HDfprintf @@ -584,43 +587,85 @@ void HDsrand(unsigned int seed) } #endif /* H5_HAVE_RAND_R */ - + /*------------------------------------------------------------------------- - * Function: HDget_timezone + * Function: H5_make_time * - * Purpose: Wrapper function for global variable timezone, if it exists - * on this system, or use the function if VS2015 + * Purpose: Portability routine to abstract converting a 'tm' struct into + * a time_t value. * - * VS2015 removed the deprecated global variable timezone. + * Note: This is a little problematic because mktime() operates on + * local times. We convert to local time and then figure out the + * adjustment based on the local time zone and daylight savings + * setting. * - * Return: Success: The value of timezone + * Return: Success: The value of timezone + * Failure: -1 * - * Failure: Cannot fail. + * Programmer: Quincey Koziol + * November 18, 2015 * *------------------------------------------------------------------------- */ -#ifndef H5_HAVE_TM_GMTOFF -#ifdef H5_HAVE_TIMEZONE - -long int HDget_timezone(void) +time_t +H5_make_time(struct tm *tm) { -#ifdef H5_HAVE_VISUAL_STUDIO -#if _MSC_VER >= 1900 /* VS 2015 */ + time_t the_time; /* The converted time */ +#if defined(H5_HAVE_VISUAL_STUDIO) && (_MSC_VER >= 1900) /* VS 2015 */ + /* In gcc and in Visual Studio prior to VS 2015 'timezone' is a global + * variable declared in time.h. That variable was deprecated and in + * VS 2015 is removed, with _get_timezone replacing it. + */ + long timezone = 0; +#endif /* defined(H5_HAVE_VISUAL_STUDIO) && (_MSC_VER >= 1900) */ + time_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Sanity check */ + HDassert(tm); + + /* Initialize timezone information */ + if(!H5_ntzset) { + HDtzset(); + H5_ntzset = TRUE; + } /* end if */ + + /* Perform base conversion */ + if((time_t)-1 == (the_time = HDmktime(tm))) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTCONVERT, FAIL, "badly formatted modification time message") + /* Adjust for timezones */ +#if defined(H5_HAVE_TM_GMTOFF) + /* BSD-like systems */ + the_time += tm->tm_gmtoff; +#elif defined(H5_HAVE_TIMEZONE) +#if defined(H5_HAVE_VISUAL_STUDIO) && (_MSC_VER >= 1900) /* VS 2015 */ /* In gcc and in Visual Studio prior to VS 2015 'timezone' is a global * variable declared in time.h. That variable was deprecated and in * VS 2015 is removed, with _get_timezone replacing it. */ - long int timezone = 0; + _get_timezone(&timezone); +#endif /* defined(H5_HAVE_VISUAL_STUDIO) && (_MSC_VER >= 1900) */ - #define HDget_timezone(V) _get_timezone(V); - HDget_timezone(&timezone); -#endif + the_time -= timezone - (tm->tm_isdst ? 3600 : 0); +#else + /* + * The catch-all. If we can't convert a character string universal + * coordinated time to a time_t value reliably then we can't decode the + * modification time message. This really isn't as bad as it sounds -- the + * only way a user can get the modification time is from our internal + * query routines, which can gracefully recover. + */ + HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "unable to obtain local timezone information") #endif - return timezone; -} -#endif /* H5_HAVE_TIMEZONE */ -#endif /* H5_HAVE_TM_GMTOFF */ + + /* Set return value */ + ret_value = the_time; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5_make_time() */ /*------------------------------------------------------------------------- * Function: Wgettimeofday -- cgit v0.12