summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMicael Karlberg <bmk@erlang.org>2019-12-02 10:48:20 +0100
committerMicael Karlberg <bmk@erlang.org>2019-12-02 10:48:20 +0100
commitb0104e3f1aa26559da2e65f85859735b49af0926 (patch)
treed459e857292fd3cccc0f8586fe0ac6ce2a9c5edf
parent4d4141195a7d55cab20e8f1bb15732808c15782c (diff)
parent912d1783122e53b9af312bb2c0e77d6e9ad10d60 (diff)
downloaderlang-b0104e3f1aa26559da2e65f85859735b49af0926.tar.gz
Merge branch 'bmk/erts/esock/20191128/timeval_decode_on_openbsd' into maint
-rw-r--r--erts/emulator/nifs/common/socket_int.h1
-rw-r--r--erts/emulator/nifs/common/socket_util.c28
2 files changed, 25 insertions, 4 deletions
diff --git a/erts/emulator/nifs/common/socket_int.h b/erts/emulator/nifs/common/socket_int.h
index 21427b0ae3..e4a3d6157d 100644
--- a/erts/emulator/nifs/common/socket_int.h
+++ b/erts/emulator/nifs/common/socket_int.h
@@ -406,6 +406,7 @@ GLOBAL_ERROR_REASON_ATOM_DEFS
enif_get_atom((E), (TE), (BP), (MAX), ERL_NIF_LATIN1)
#define GET_BIN(E, TE, BP) enif_inspect_iolist_as_binary((E), (TE), (BP))
#define GET_INT(E, TE, IP) enif_get_int((E), (TE), (IP))
+#define GET_INT64(E, TE, IP) enif_get_int64((E), (TE), (IP))
#define GET_LIST_ELEM(E, L, HP, TP) enif_get_list_cell((E), (L), (HP), (TP))
#define GET_LIST_LEN(E, L, LP) enif_get_list_length((E), (L), (LP))
#define GET_LONG(E, TE, LP) enif_get_long((E), (TE), (LP))
diff --git a/erts/emulator/nifs/common/socket_util.c b/erts/emulator/nifs/common/socket_util.c
index 9daf7f3e67..6839395e8f 100644
--- a/erts/emulator/nifs/common/socket_util.c
+++ b/erts/emulator/nifs/common/socket_util.c
@@ -1082,10 +1082,30 @@ char* esock_decode_timeval(ErlNifEnv* env,
if (!GET_MAP_VAL(env, eTime, esock_atom_usec, &eUSec))
return ESOCK_STR_EINVAL;
- if (!GET_LONG(env, eSec, &timeP->tv_sec))
- return ESOCK_STR_EINVAL;
-
-#if (SIZEOF_INT == 4)
+ /* On some platforms (e.g. OpenBSD) this is a 'long long' and on others
+ * (e.g. Linux) its a long.
+ * As long as they are both 64 bits, its easy (use our own signed 64-bit int
+ * and then cast). But if they are either not 64 bit, or they are of different size
+ * then we make it easy on ourselves and use long and then cast to whatever
+ * type sec is.
+ */
+#if (SIZEOF_LONG_LONG == SIZEOF_LONG) && (SIZEOF_LONG == 8)
+ {
+ ErlNifSInt64 sec;
+ if (!GET_INT64(env, eSec, &sec))
+ return ESOCK_STR_EINVAL;
+ timeP->tv_sec = (typeof(timeP->tv_sec)) sec;
+ }
+#else
+ {
+ long sec;
+ if (!GET_LONG(env, eSec, &sec))
+ return ESOCK_STR_EINVAL;
+ timeP->tv_sec = (typeof(timeP->tv_sec)) sec;
+ }
+#endif
+
+ #if (SIZEOF_INT == 4)
{
int usec;
if (!GET_INT(env, eUSec, &usec))