Here's a new version of the get_offset patch that initializes the TZ offset from apr_initialize. I've attached the new include file that it uses, apr/include/arch/unix/internal_time.h
--Brian
Index: apr/misc/unix/start.c =================================================================== RCS file: /home/cvspublic/apr/misc/unix/start.c,v retrieving revision 1.52 diff -u -r1.52 start.c --- apr/misc/unix/start.c 2001/08/02 22:27:02 1.52 +++ apr/misc/unix/start.c 2001/08/28 18:11:54 @@ -60,7 +60,9 @@ #include "misc.h" /* for WSAHighByte / WSALowByte */ #include "locks.h" /* for apr_unix_setup_lock() */
+#include "internal_time.h"
+ static int initialized = 0; static apr_pool_t *global_apr_pool;
@@ -83,6 +85,7 @@
#if !defined(BEOS) && !defined(OS2) && !defined(WIN32) && !defined(NETWARE) apr_unix_setup_lock(); + apr_unix_setup_time(); #elif defined WIN32 || defined(NETWARE) iVersionRequested = MAKEWORD(WSAHighByte, WSALowByte); err = WSAStartup((WORD) iVersionRequested, &wsaData); Index: apr/time/unix/time.c =================================================================== RCS file: /home/cvspublic/apr/time/unix/time.c,v retrieving revision 1.51 diff -u -r1.51 time.c --- apr/time/unix/time.c 2001/08/10 21:04:49 1.51 +++ apr/time/unix/time.c 2001/08/28 18:11:54 @@ -70,6 +70,10 @@ #endif /* End System Headers */
+#if !defined(HAVE_GMTOFF) && !defined(HAVE___OFFSET) +static apr_int32_t server_gmt_offset; +#endif /* if !defined(HAVE_GMTOFF) && !defined(HAVE___OFFSET) */ + static apr_int32_t get_offset(struct tm *tm) { #ifdef HAVE_GMTOFF @@ -77,30 +81,8 @@ #elif defined(HAVE___OFFSET) return tm->__tm_gmtoff; #else - /* We don't have an offset field to use, so calculate it. - mktime() is the inverse of localtime(); so, presumably, - passing in a struct tm made by gmtime() let's us calculate - the true GMT offset. However, there's a catch: if daylight - savings is in effect, gmtime()will set the tm_isdst field - and confuse mktime() into returning a time that's offset - by one hour. In that case, we must adjust the calculated GMT - offset. */ - { - time_t t1 = time(0), t2 = 0; - struct tm t; - int was_dst; - -#if APR_HAS_THREADS && defined(_POSIX_THREAD_SAFE_FUNCTIONS) - gmtime_r(&t1, &t); -#else - t = *gmtime(&t1); + return server_gmt_offset; #endif - was_dst = (t.tm_isdst > 0); - t.tm_isdst = -1; - t2 = mktime(&t); - return (apr_int32_t) difftime(t1, t2) + (was_dst ? 3600 : 0); - } -#endif }
APR_DECLARE(apr_status_t) apr_ansi_time_to_apr_time(apr_time_t *result,
@@ -308,3 +290,37 @@
return APR_SUCCESS;
}
#endif
+
+APR_DECLARE(void) apr_unix_setup_time(void)
+{
+#if !defined(HAVE_GMTOFF) && !defined(HAVE___OFFSET)
+ /* Precompute the offset from GMT on systems where it's not
+ in struct tm.
+ mktime() is the inverse of localtime(); so, presumably,
+ passing in a struct tm made by gmtime() let's us calculate
+ the true GMT offset. However, there's a catch: if daylight
+ savings is in effect, gmtime()will set the tm_isdst field
+ and confuse mktime() into returning a time that's offset
+ by one hour. In that case, we must adjust the calculated GMT
+ offset. */
+
+ struct timeval now;
+ time_t t1, t2;
+ struct tm t;
+ int was_dst;
+
+ gettimeofday(&now, NULL);
+ t1 = now.tv_sec;
+ t2 = 0;
+
+#if APR_HAS_THREADS && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
+ gmtime_r(&t1, &t);
+#else
+ t = *gmtime(&t1);
+#endif
+ was_dst = (t.tm_isdst > 0);
+ t.tm_isdst = -1;
+ t2 = mktime(&t);
+ server_gmt_offset = (apr_int32_t) difftime(t1, t2) + (was_dst ? 3600 : 0);
+#endif
+}
/* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Apache" and "Apache Software Foundation" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */
#ifndef TIME_INTERNAL_H #define TIME_INTERNAL_H #include "apr.h" void apr_unix_setup_time(void); #endif /* TIME_INTERNAL_H */