Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PATCH] 5.8.8 Handle cases where localtime_r does not call tzset #8799

Closed
p5pRT opened this issue Feb 22, 2007 · 4 comments
Closed

[PATCH] 5.8.8 Handle cases where localtime_r does not call tzset #8799

p5pRT opened this issue Feb 22, 2007 · 4 comments

Comments

@p5pRT
Copy link

p5pRT commented Feb 22, 2007

Migrated from rt.perl.org#41591 (status was 'resolved')

Searchable as RT41591$

@p5pRT
Copy link
Author

p5pRT commented Feb 22, 2007

From @spotrh

This is a bug report for perl from tcallawa@​redhat.com,
generated with the help of perlbug 1.35 running under perl v5.8.8.


As part of the review process for Perl, I'm opening bugs for the
long list of patches to perl that Fedora has been carrying around
(in some cases, for years), in the hopes that these fixes can be
applied upstream. Unfortunately, I am not the original author of
these patches, so please be patient with me as I attempt to
describe why Fedora uses them.

In Fedora, we've found that our multi-threaded perl builds use
localtime_r which does not call tzset. Thus, this patch, which adds
a configure check to see if localtime_r calls tzset, and handles
both the cases in which it does and the cases in which it does not.

This was originally filed and discussed here​:
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=172396

Inline Patch
--- perl-5.8.8/config_h.SH.bz172396	2005-10-31 13:13:05.000000000 -0500
+++ perl-5.8.8/config_h.SH	2006-05-11 16:20:36.000000000 -0400
@@ -1912,7 +1912,18 @@
  */
 #$d_localtime_r HAS_LOCALTIME_R	   /**/
 #define LOCALTIME_R_PROTO $localtime_r_proto	   /**/
-
+/* LOCALTIME_R_NEEDS_TZSET :
+ *  many libc's localtime_r implementations do not call tzset,
+ *  making them differ from localtime(), and making timezone
+ *  changes using $ENV{TZ} without explicitly calling tzset
+ *  impossible. This symbol makes us call tzset before localtime_r:
+ */
+#$d_localtime_r_needs_tzset LOCALTIME_R_NEEDS_TZSET /**/
+#ifdef LOCALTIME_R_NEEDS_TZSET
+#define L_R_TZSET tzset(),
+#else
+#define L_R_TZSET
+#endif 
 /* HAS_LONG_DOUBLE:
  *	This symbol will be defined if the C compiler supports long
  *	doubles.
--- perl-5.8.8/reentr.inc.bz172396	2006-05-11 16:20:36.000000000 -0400
+++ perl-5.8.8/reentr.inc	2006-05-11 16:20:36.000000000 -0400
@@ -1368,10 +1368,10 @@
 #ifdef HAS_LOCALTIME_R
 #   undef localtime
 #   if !defined(localtime) && LOCALTIME_R_PROTO == REENTRANT_PROTO_S_TS
-#       define localtime(a) (localtime_r(a,
&PL_reentrant_buffer->_localtime_struct) ? &PL\_reentrant\_buffer\->\_localtime\_struct : 0\) \+\# define localtime\(a\) \( L\_R\_TZSET localtime\_r\(a\, &PL\_reentrant\_buffer\->\_localtime\_struct\) ? &PL\_reentrant\_buffer\->\_localtime\_struct : 0\) \# endif \# if \!defined\(localtime\) && LOCALTIME\_R\_PROTO == REENTRANT\_PROTO\_I\_TS \-\# define localtime\(a\) \(localtime\_r\(a\, &PL\_reentrant\_buffer\->\_localtime\_struct\) == 0 ? &PL\_reentrant\_buffer\->\_localtime\_struct : 0\) \+\# define localtime\(a\) \( L\_R\_TZSET localtime\_r\(a\, &PL\_reentrant\_buffer\->\_localtime\_struct\) == 0 ? &PL\_reentrant\_buffer\->\_localtime\_struct : 0\) \# endif \#endif /\* HAS\_LOCALTIME\_R \*/
Inline Patch
--- perl-5.8.8/Configure.bz172396	2006-05-11 16:20:36.000000000 -0400
+++ perl-5.8.8/Configure	2006-05-11 16:21:47.000000000 -0400
@@ -542,6 +542,7 @@
 d_libm_lib_version=''
 d_link=''
 d_localtime_r=''
+d_localtime_r_needs_tzset=''
 localtime_r_proto=''
 d_locconv=''
 d_lockf=''
@@ -14261,7 +14262,59 @@
 *)	localtime_r_proto=0
 	;;
 esac
+: see if localtime_r calls tzset
+case "$localtime_r_proto" in
+REENTRANT_PROTO*) 
+	$cat >try.c <<EOCP
+/*  Does our libc's localtime_r call tzset ?
+ *  return 0 if so, 1 otherwise.
+ */ 
+#include <sys/types.h>
+#include <unistd.h>
+#include <time.h>
+#include <string.h>
+#include <malloc.h>
+int main()
+{
+    time_t t = time(0L);
+    char w_tz[]="TZ=GMT+5",
+	 e_tz[]="TZ=GMT-5",
+	*tz_e = (char*)malloc(16),
+	*tz_w = (char*)malloc(16);
+    struct tm tm_e, tm_w;
+    memset(&tm_e,'\0',sizeof(struct tm));
+    memset(&tm_w,'\0',sizeof(struct tm));
+    strcpy(tz_e,e_tz);
+    strcpy(tz_w,w_tz);
 
+    putenv(tz_e);
+    localtime_r(&t, &tm_e);    
+    
+    putenv(tz_w);
+    localtime_r(&t, &tm_w);    
+
+    if( memcmp(&tm_e, &tm_w, sizeof(struct tm)) == 0 )
+	return 1;
+    return 0;
+}
+EOCP
+	set try
+	if eval $compile; then	
+	    if ./try; then
+		d_localtime_r_needs_tzset=undef;
+	    else
+		d_localtime_r_needs_tzset=define;
+	    fi;
+	    rm -f ./try;
+	else
+	    d_localtime_r_needs_tzset=undef;
+	fi;
+	rm -f try.c;
+     ;;
+  *)
+     d_localtime_r_needs_tzset=undef;
+     ;;
+esac
 : see if localeconv exists
 set localeconv d_locconv
 eval $inlibc
@@ -21220,6 +21273,7 @@
 d_libm_lib_version='$d_libm_lib_version'
 d_link='$d_link'
 d_localtime_r='$d_localtime_r'
+d_localtime_r_needs_tzset='$d_localtime_r_needs_tzset'
 d_locconv='$d_locconv'
 d_lockf='$d_lockf'
 d_longdbl='$d_longdbl'





-----------------------------------------------------------------
---
Flags:   category=core   severity=medium

This perlbug was built using Perl v5.8.8 in the Red Hat build system.
It is being executed now by Perl v5.8.8 - Wed Jan 24 08​:06​:27 EST 2007.

Site configuration information for perl v5.8.8​:

Configured by Red Hat, Inc. at Wed Jan 24 08​:06​:27 EST 2007.

Summary of my perl5 (revision 5 version 8 subversion 8) configuration​:
  Platform​:
  osname=linux, osvers=2.6.9-42.elsmp,
archname=i386-linux-thread-multi
  uname='linux ls20-bc1-13.build.redhat.com 2.6.9-42.elsmp #1 smp wed
jul 12 23​:32​:02 edt 2006 i686 athlon i386 gnulinux '
  config_args='-des -Doptimize=-O2 -g -pipe -Wall
-Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector
--param=ssp-buffer-size=4 -m32 -march=i386 -mtune=generic
-fasynchronous-unwind-tables -Dversion=5.8.8 -Dmyhostname=localhost
-Dperladmin=root@​localhost -Dcc=gcc -Dcf_by=Red Hat, Inc.
-Dinstallprefix=/usr -Dprefix=/usr -Darchname=i386-linux
-Dvendorprefix=/usr -Dsiteprefix=/usr -Duseshrplib -Dusethreads
-Duseithreads -Duselargefiles -Dd_dosuid -Dd_semctl_semun -Di_db
-Ui_ndbm -Di_gdbm -Di_shadow -Di_syslog -Dman3ext=3pm -Duseperlio
-Dinstallusrbinperl=n -Ubincompat5005 -Uversiononly
-Dpager=/usr/bin/less -isr -Dd_gethostent_r_proto -Ud_endhostent_r_proto
-Ud_sethostent_r_proto -Ud_endprotoent_r_proto -Ud_setprotoent_r_proto
-Ud_endservent_r_proto -Ud_setservent_r_proto -Dinc_version_list=5.8.7
5.8.6 5.8.5 -Dscriptdir=/usr/bin'
  hint=recommended, useposix=true, d_sigaction=define
  usethreads=define use5005threads=undef useithreads=define
usemultiplicity=define
  useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
  use64bitint=undef use64bitall=undef uselongdouble=undef
  usemymalloc=n, bincompat5005=undef
  Compiler​:
  cc='gcc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing
-pipe -Wdeclaration-after-statement -I/usr/local/include
-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/gdbm',
  optimize='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions
-fstack-protector --param=ssp-buffer-size=4 -m32 -march=i386
-mtune=generic -fasynchronous-unwind-tables',
  cppflags='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe
-Wdeclaration-after-statement -I/usr/local/include -I/usr/include/gdbm'
  ccversion='', gccversion='4.1.1 20070123 (Red Hat 4.1.1-54)',
gccosandvers=''
  intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
  d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
  ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t',
lseeksize=8
  alignbytes=4, prototype=define
  Linker and Libraries​:
  ld='gcc', ldflags =' -L/usr/local/lib'
  libpth=/usr/local/lib /lib /usr/lib
  libs=-lresolv -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lpthread
-lc
  perllibs=-lresolv -lnsl -ldl -lm -lcrypt -lutil -lpthread -lc
  libc=/lib/libc-2.5.90.so, so=so, useshrplib=true, libperl=libperl.so
  gnulibc_version='2.5.90'
  Dynamic Linking​:
  dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E
-Wl,-rpath,/usr/lib/perl5/5.8.8/i386-linux-thread-multi/CORE'
  cccdlflags='-fPIC', lddlflags='-shared -O2 -g -pipe -Wall
-Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector
--param=ssp-buffer-size=4 -m32 -march=i386 -mtune=generic
-fasynchronous-unwind-tables -L/usr/local/lib'

Locally applied patches​:
 


@​INC for perl v5.8.8​:
  /usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi
  /usr/lib/perl5/site_perl/5.8.7/i386-linux-thread-multi
  /usr/lib/perl5/site_perl/5.8.6/i386-linux-thread-multi
  /usr/lib/perl5/site_perl/5.8.5/i386-linux-thread-multi
  /usr/lib/perl5/site_perl/5.8.8
  /usr/lib/perl5/site_perl/5.8.7
  /usr/lib/perl5/site_perl/5.8.6
  /usr/lib/perl5/site_perl/5.8.5
  /usr/lib/perl5/site_perl
  /usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi
  /usr/lib/perl5/vendor_perl/5.8.7/i386-linux-thread-multi
  /usr/lib/perl5/vendor_perl/5.8.6/i386-linux-thread-multi
  /usr/lib/perl5/vendor_perl/5.8.5/i386-linux-thread-multi
  /usr/lib/perl5/vendor_perl/5.8.8
  /usr/lib/perl5/vendor_perl/5.8.7
  /usr/lib/perl5/vendor_perl/5.8.6
  /usr/lib/perl5/vendor_perl/5.8.5
  /usr/lib/perl5/vendor_perl
  /usr/lib/perl5/5.8.8/i386-linux-thread-multi
  /usr/lib/perl5/5.8.8
  .


Environment for perl v5.8.8​:
  HOME=/home/spot
  LANG=en_US.UTF-8
  LANGUAGE (unset)
  LD_LIBRARY_PATH (unset)
  LOGDIR (unset)

PATH=/usr/lib/qt-3.3/bin​:/usr/kerberos/bin​:/usr/local/bin​:/usr/bin​:/bin​:/usr/X11R6/bin​:/home/spot/bin​:/usr/java/j2re1.4.2_02/javaws/
  PERL_BADLANG (unset)
  SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Mar 9, 2007

From @Tux

On Thu, 22 Feb 2007 15​:19​:03 -0800, Tom Callaway (via RT)
<perlbug-followup@​perl.org> wrote​:

As part of the review process for Perl, I'm opening bugs for the
long list of patches to perl that Fedora has been carrying around
(in some cases, for years), in the hopes that these fixes can be
applied upstream. Unfortunately, I am not the original author of
these patches, so please be patient with me as I attempt to
describe why Fedora uses them.

In Fedora, we've found that our multi-threaded perl builds use
localtime_r which does not call tzset. Thus, this patch, which adds
a configure check to see if localtime_r calls tzset, and handles
both the cases in which it does and the cases in which it does not.

I don't exactly know whether this report was the source, but this
change is already in the current development version, entered as​:

http​://public.activestate.com/cgi-bin/perlbrowse/p/29207

Change 29207 by merijn@​merijn-lt09 on 2006/11/06 09​:27​:56

  RE​: [perl #26136] localtime(3) calls tzset(3), but localtime_r(3) may not.
  From​: "Benjamin Holzman" <bholzman@​longitude.com>
  Date​: Wed, 19 Jul 2006 07​:11​:09 -0400
  Message-ID​: <010801c6ab24$09b9ed30$ce0515ac@​office.iseoptions.com>

Affected files ...

... //depot/metaconfig/U/threads/d_localtime_r.U#20 edit

and shortly followed by

http​://public.activestate.com/cgi-bin/perlbrowse/p/29209

Change 29209 by merijn@​merijn-lt09 on 2006/11/06 09​:43​:30

  RE​: [perl #26136] localtime(3) calls tzset(3), but localtime_r(3) may not.
  From​: "Benjamin Holzman" <bholzman@​longitude.com>
  Date​: Wed, 19 Jul 2006 07​:11​:09 -0400
  Message-ID​: <010801c6ab24$09b9ed30$ce0515ac@​office.iseoptions.com>

Affected files ...

... //depot/perl/Configure#627 edit
... //depot/perl/Porting/Glossary#172 edit
... //depot/perl/config_h.SH#324 edit
... //depot/perl/reentr.h#31 edit
... //depot/perl/t/op/time.t#12 edit

BTW, it also looks like this particular patch has already made it to the
maint track, so the upcoming 5.8.9 will also have it

This was originally filed and discussed here​:
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=172396

--- perl-5.8.8/config_h.SH.bz172396 2005-10-31 13​:13​:05.000000000 -0500
+++ perl-5.8.8/config_h.SH 2006-05-11 16​:20​:36.000000000 -0400
@​@​ -1912,7 +1912,18 @​@​
*/
#$d_localtime_r HAS_LOCALTIME_R /**/
#define LOCALTIME_R_PROTO $localtime_r_proto /**/
-
+/* LOCALTIME_R_NEEDS_TZSET :
+ * many libc's localtime_r implementations do not call tzset,
+ * making them differ from localtime(), and making timezone
+ * changes using $ENV{TZ} without explicitly calling tzset
+ * impossible. This symbol makes us call tzset before localtime_r​:
+ */
+#$d_localtime_r_needs_tzset LOCALTIME_R_NEEDS_TZSET /**/
+#ifdef LOCALTIME_R_NEEDS_TZSET
+#define L_R_TZSET tzset(),
+#else
+#define L_R_TZSET
+#endif
/* HAS_LONG_DOUBLE​:
* This symbol will be defined if the C compiler supports long
* doubles.
--- perl-5.8.8/reentr.inc.bz172396 2006-05-11 16​:20​:36.000000000 -0400
+++ perl-5.8.8/reentr.inc 2006-05-11 16​:20​:36.000000000 -0400
@​@​ -1368,10 +1368,10 @​@​
#ifdef HAS_LOCALTIME_R
# undef localtime
# if !defined(localtime) && LOCALTIME_R_PROTO == REENTRANT_PROTO_S_TS
-# define localtime(a) (localtime_r(a,
&PL_reentrant_buffer->_localtime_struct) ?
&PL_reentrant_buffer->_localtime_struct : 0)
+# define localtime(a) ( L_R_TZSET localtime_r(a,
&PL_reentrant_buffer->_localtime_struct) ?
&PL_reentrant_buffer->_localtime_struct : 0)
# endif
# if !defined(localtime) && LOCALTIME_R_PROTO == REENTRANT_PROTO_I_TS
-# define localtime(a) (localtime_r(a,
&PL_reentrant_buffer->_localtime_struct) == 0 ?
&PL_reentrant_buffer->_localtime_struct : 0)
+# define localtime(a) ( L_R_TZSET localtime_r(a,
&PL_reentrant_buffer->_localtime_struct) == 0 ?
&PL_reentrant_buffer->_localtime_struct : 0)
# endif
#endif /* HAS_LOCALTIME_R */

--- perl-5.8.8/Configure.bz172396 2006-05-11 16​:20​:36.000000000 -0400
+++ perl-5.8.8/Configure 2006-05-11 16​:21​:47.000000000 -0400
@​@​ -542,6 +542,7 @​@​
d_libm_lib_version=''
d_link=''
d_localtime_r=''
+d_localtime_r_needs_tzset=''
localtime_r_proto=''
d_locconv=''
d_lockf=''
@​@​ -14261,7 +14262,59 @​@​
*) localtime_r_proto=0
;;
esac
+​: see if localtime_r calls tzset
+case "$localtime_r_proto" in
+REENTRANT_PROTO*)
+ $cat >try.c <<EOCP
+/* Does our libc's localtime_r call tzset ?
+ * return 0 if so, 1 otherwise.
+ */
+#include <sys/types.h>
+#include <unistd.h>
+#include <time.h>
+#include <string.h>
+#include <malloc.h>
+int main()
+{
+ time_t t = time(0L);
+ char w_tz[]="TZ=GMT+5",
+ e_tz[]="TZ=GMT-5",
+ *tz_e = (char*)malloc(16),
+ *tz_w = (char*)malloc(16);
+ struct tm tm_e, tm_w;
+ memset(&tm_e,'\0',sizeof(struct tm));
+ memset(&tm_w,'\0',sizeof(struct tm));
+ strcpy(tz_e,e_tz);
+ strcpy(tz_w,w_tz);

+ putenv(tz_e);
+ localtime_r(&t, &tm_e);
+
+ putenv(tz_w);
+ localtime_r(&t, &tm_w);
+
+ if( memcmp(&tm_e, &tm_w, sizeof(struct tm)) == 0 )
+ return 1;
+ return 0;
+}
+EOCP
+ set try
+ if eval $compile; then
+ if ./try; then
+ d_localtime_r_needs_tzset=undef;
+ else
+ d_localtime_r_needs_tzset=define;
+ fi;
+ rm -f ./try;
+ else
+ d_localtime_r_needs_tzset=undef;
+ fi;
+ rm -f try.c;
+ ;;
+ *)
+ d_localtime_r_needs_tzset=undef;
+ ;;
+esac
: see if localeconv exists
set localeconv d_locconv
eval $inlibc
@​@​ -21220,6 +21273,7 @​@​
d_libm_lib_version='$d_libm_lib_version'
d_link='$d_link'
d_localtime_r='$d_localtime_r'
+d_localtime_r_needs_tzset='$d_localtime_r_needs_tzset'
d_locconv='$d_locconv'
d_lockf='$d_lockf'
d_longdbl='$d_longdbl'

--
H.Merijn Brand Amsterdam Perl Mongers (http​://amsterdam.pm.org/)
using & porting perl 5.6.2, 5.8.x, 5.9.x on HP-UX 10.20, 11.00, 11.11,
& 11.23, SuSE 10.0 & 10.2, AIX 4.3 & 5.2, and Cygwin. http​://qa.perl.org
http​://mirrors.develooper.com/hpux/ http​://www.test-smoke.org
  http​://www.goldmark.org/jeff/stupid-disclaimers/

@p5pRT
Copy link
Author

p5pRT commented Mar 9, 2007

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Mar 20, 2007

@smpeters - Status changed from 'open' to 'resolved'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant