Hi,
I was hoping that we would be on 14Bxx by now, but since this didn't
happen yet, I would like to get this fix backported:
https://github.com/erlang/otp/commit/7e6fe78278c203c3756ce0d6bf23a6bd6cf7bb5d
Without this fix, MochiWeb (which is used by couple of Erlang applications)
crashes on systems with timezone without DST (like UTC).
--- 13B04 ---
1> calendar:local_time_to_universal_time_dst({{2011, 1, 1}, {0, 0, 0}}).
** exception error: bad argument
in function erlang:universaltime_to_localtime/1
called as erlang:universaltime_to_localtime({{1969,12,31},{23,59,59}})
in call from calendar:local_time_to_universal_time_dst/1
--- 13B04-patched ---
1> calendar:local_time_to_universal_time_dst({{2011, 1, 1}, {0, 0, 0}}).
[{{2011,1,1},{0,0,0}}]
For completness, attached patch includes changes to the test suite,
but since we're not running tests, feel free to ignore it.
Best regards,
Piotr Sikora < [email protected] >
Index: Makefile
===================================================================
RCS file: /cvs/ports/lang/erlang/Makefile,v
retrieving revision 1.42
diff -u -r1.42 Makefile
--- Makefile 25 Jun 2011 07:48:43 -0000 1.42
+++ Makefile 2 Jul 2011 00:21:12 -0000
@@ -5,7 +5,7 @@
V= R13B04
DISTNAME= otp_src_${V}
PKGNAME= erlang-13b.04
-REVISION= 3
+REVISION= 4
CATEGORIES= lang
# Erlang Public License
Index: patches/patch-erts_configure_in
===================================================================
RCS file: patches/patch-erts_configure_in
diff -N patches/patch-erts_configure_in
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-erts_configure_in 2 Jul 2011 00:21:12 -0000
@@ -0,0 +1,13 @@
+$OpenBSD$
+--- erts/configure.in.orig
++++ erts/configure.in
+@@ -1698,6 +1698,9 @@ AC_CHECK_FUNCS([ieee_handler fpsetmask finite isnan
isinf res_gethostbyname dlop
+ gethrtime localtime_r gmtime_r mmap mremap memcpy mallopt \
+ sbrk _sbrk __sbrk brk _brk __brk \
+ flockfile fstat strlcpy strlcat setsid posix2time setlocale
nl_langinfo poll])
++
++AC_CHECK_DECLS([posix2time],,,[#include <time.h>])
++
+ if test "X$host" = "Xwin32"; then
+ ac_cv_func_setvbuf_reversed=yes
+ fi
Index: patches/patch-erts_emulator_beam_erl_time_sup_c
===================================================================
RCS file: patches/patch-erts_emulator_beam_erl_time_sup_c
diff -N patches/patch-erts_emulator_beam_erl_time_sup_c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-erts_emulator_beam_erl_time_sup_c 2 Jul 2011 00:21:12
-0000
@@ -0,0 +1,37 @@
+$OpenBSD$
+--- erts/emulator/beam/erl_time_sup.c.orig
++++ erts/emulator/beam/erl_time_sup.c
+@@ -650,6 +650,22 @@ local_to_univ(Sint *year, Sint *month, Sint *day,
+ t.tm_sec = *second;
+ t.tm_isdst = isdst;
+ the_clock = mktime(&t);
++ if (the_clock == -1) {
++ if (isdst) {
++ /* If this is a timezone without DST and the OS (correctly)
++ refuses to give us a DST time, we simulate the Linux/Solaris
++ behaviour of giving the same data as if is_dst was not set. */
++ t.tm_isdst = 0;
++ the_clock = mktime(&t);
++ if (the_clock == -1) {
++ /* Failed anyway, something else is bad - will be a badarg */
++ return 0;
++ }
++ } else {
++ /* Something else is the matter, badarg. */
++ return 0;
++ }
++ }
+ #ifdef HAVE_GMTIME_R
+ gmtime_r(&the_clock, (tm = &tmbuf));
+ #else
+@@ -663,6 +679,10 @@ local_to_univ(Sint *year, Sint *month, Sint *day,
+ *second = tm->tm_sec;
+ return 1;
+ }
++#if defined(HAVE_POSIX2TIME) && defined(HAVE_DECL_POSIX2TIME) && \
++ !HAVE_DECL_POSIX2TIME
++extern time_t posix2time(time_t);
++#endif
+
+ int
+ univ_to_local(Sint *year, Sint *month, Sint *day,
Index: patches/patch-erts_emulator_test_time_SUITE_erl
===================================================================
RCS file: patches/patch-erts_emulator_test_time_SUITE_erl
diff -N patches/patch-erts_emulator_test_time_SUITE_erl
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-erts_emulator_test_time_SUITE_erl 2 Jul 2011 00:21:12
-0000
@@ -0,0 +1,54 @@
+$OpenBSD$
+--- erts/emulator/test/time_SUITE.erl.orig
++++ erts/emulator/test/time_SUITE.erl
+@@ -34,6 +34,8 @@
+ consistency/1,
+ now/1, now_unique/1, now_update/1, timestamp/1]).
+
++-export([local_to_univ_utc/1]).
++
+ -include("test_server.hrl").
+
+ -export([linear_time/1]).
+@@ -53,7 +55,40 @@
+ -define(dst_timezone, 2).
+
+ all(suite) -> [univ_to_local, local_to_univ,
+- bad_univ_to_local, bad_local_to_univ, consistency, now,
timestamp].
++ local_to_univ_utc,
++ bad_univ_to_local, bad_local_to_univ,
++ consistency, now, timestamp].
++
++local_to_univ_utc(suite) ->
++ [];
++local_to_univ_utc(doc) ->
++ ["Test that DST = true on timezones without DST is ignored"];
++local_to_univ_utc(Config) when is_list(Config) ->
++ case os:type() of
++ {unix,_} ->
++ %% TZ variable has a meaning
++ ?line {ok, Node} =
++ test_server:start_node(local_univ_utc,peer,
++ [{args, "-env TZ UTC"}]),
++ ?line {{2008,8,1},{0,0,0}} =
++ rpc:call(Node,
++ erlang,localtime_to_universaltime,
++ [{{2008, 8, 1}, {0, 0, 0}},
++ false]),
++ ?line {{2008,8,1},{0,0,0}} =
++ rpc:call(Node,
++ erlang,localtime_to_universaltime,
++ [{{2008, 8, 1}, {0, 0, 0}},
++ true]),
++ ?line [{{2008,8,1},{0,0,0}}] =
++ rpc:call(Node,
++ calendar,local_time_to_universal_time_dst,
++ [{{2008, 8, 1}, {0, 0, 0}}]),
++ ?line test_server:stop_node(Node),
++ ok;
++ _ ->
++ {skip,"Only valid on Unix"}
++ end.
+
+
+ %% Tests conversion from univeral to local time.