diff options
author | Micael Karlberg <bmk@erlang.org> | 2019-12-02 10:48:20 +0100 |
---|---|---|
committer | Micael Karlberg <bmk@erlang.org> | 2019-12-02 10:48:20 +0100 |
commit | b0104e3f1aa26559da2e65f85859735b49af0926 (patch) | |
tree | d459e857292fd3cccc0f8586fe0ac6ce2a9c5edf | |
parent | 4d4141195a7d55cab20e8f1bb15732808c15782c (diff) | |
parent | 912d1783122e53b9af312bb2c0e77d6e9ad10d60 (diff) | |
download | erlang-b0104e3f1aa26559da2e65f85859735b49af0926.tar.gz |
Merge branch 'bmk/erts/esock/20191128/timeval_decode_on_openbsd' into maint
-rw-r--r-- | erts/emulator/nifs/common/socket_int.h | 1 | ||||
-rw-r--r-- | erts/emulator/nifs/common/socket_util.c | 28 |
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)) |