aboutsummaryrefslogtreecommitdiffstats
path: root/src/editfns.c
diff options
context:
space:
mode:
authorRichard M. Stallman1996-06-05 15:08:18 +0000
committerRichard M. Stallman1996-06-05 15:08:18 +0000
commitaafe5147448734a0ef35deba8f8065f424e88343 (patch)
tree2e47f199cb60ab3762ba8250086a00754c4d33fc /src/editfns.c
parented8a2c3a284a7371cccfd019c418f5ed47bddd46 (diff)
downloademacs-aafe5147448734a0ef35deba8f8065f424e88343.tar.gz
emacs-aafe5147448734a0ef35deba8f8065f424e88343.zip
(set_time_zone_rule):
Work around localtime cache bug in SunOS 4.1.3_U1 and SunOS 4.1.4.
Diffstat (limited to 'src/editfns.c')
-rw-r--r--src/editfns.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/src/editfns.c b/src/editfns.c
index dc5e7988f23..c33a6acae8b 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -939,11 +939,14 @@ set_time_zone_rule (tzstring)
939 int envptrs; 939 int envptrs;
940 char **from, **to, **newenv; 940 char **from, **to, **newenv;
941 941
942 /* Make the ENVIRON vector longer with room for TZSTRING. */
942 for (from = environ; *from; from++) 943 for (from = environ; *from; from++)
943 continue; 944 continue;
944 envptrs = from - environ + 2; 945 envptrs = from - environ + 2;
945 newenv = to = (char **) xmalloc (envptrs * sizeof (char *) 946 newenv = to = (char **) xmalloc (envptrs * sizeof (char *)
946 + (tzstring ? strlen (tzstring) + 4 : 0)); 947 + (tzstring ? strlen (tzstring) + 4 : 0));
948
949 /* Add TZSTRING to the end of environ, as a value for TZ. */
947 if (tzstring) 950 if (tzstring)
948 { 951 {
949 char *t = (char *) (to + envptrs); 952 char *t = (char *) (to + envptrs);
@@ -952,6 +955,9 @@ set_time_zone_rule (tzstring)
952 *to++ = t; 955 *to++ = t;
953 } 956 }
954 957
958 /* Copy the old environ vector elements into NEWENV,
959 but don't copy the TZ variable.
960 So we have only one definition of TZ, which came from TZSTRING. */
955 for (from = environ; *from; from++) 961 for (from = environ; *from; from++)
956 if (strncmp (*from, "TZ=", 3) != 0) 962 if (strncmp (*from, "TZ=", 3) != 0)
957 *to++ = *from; 963 *to++ = *from;
@@ -959,7 +965,49 @@ set_time_zone_rule (tzstring)
959 965
960 environ = newenv; 966 environ = newenv;
961 967
968 /* If we do have a TZSTRING, NEWENV points to the vector slot where
969 the TZ variable is stored. If we do not have a TZSTRING,
970 TO points to the vector slot which has the terminating null. */
971
962#ifdef LOCALTIME_CACHE 972#ifdef LOCALTIME_CACHE
973 {
974 /* In SunOS 4.1.3_U1 and 4.1.4, if TZ has a value like
975 "US/Pacific" that loads a tz file, then changes to a value like
976 "XXX0" that does not load a tz file, and then changes back to
977 its original value, the last change is (incorrectly) ignored.
978 Also, if TZ changes twice in succession to values that do
979 not load a tz file, tzset can dump core (see Sun bug#1225179).
980 The following code works around these bugs. */
981
982 /* These two values are known to load tz files in buggy implementations.
983 Their values shouldn't matter in non-buggy implementations. */
984 char *tz1 = "TZ=GMT0";
985 char *tz2 = "TZ=GMT1";
986
987 if (tzstring)
988 {
989 /* Temporarily set TZ to a value that loads a tz file
990 and that differs from tzstring. */
991 char *tz = *newenv;
992 *newenv = strcmp (tzstring, tz1 + 3) == 0 ? tz2 : tz1;
993 tzset ();
994 *newenv = tz;
995 }
996 else
997 {
998 /* The implied tzstring is unknown, so temporarily set TZ to
999 two different values that each load a tz file. */
1000 *to = tz1;
1001 to[1] = 0;
1002 tzset ();
1003 *to = tz2;
1004 tzset ();
1005 *to = 0;
1006 }
1007
1008 /* Now TZ has the desired value, and tzset can be invoked safely. */
1009 }
1010
963 tzset (); 1011 tzset ();
964#endif 1012#endif
965} 1013}