aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/nifs/common/socket_util.c
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/nifs/common/socket_util.c')
-rw-r--r--erts/emulator/nifs/common/socket_util.c129
1 files changed, 79 insertions, 50 deletions
diff --git a/erts/emulator/nifs/common/socket_util.c b/erts/emulator/nifs/common/socket_util.c
index 8ad95cb6b7..54c310ecc7 100644
--- a/erts/emulator/nifs/common/socket_util.c
+++ b/erts/emulator/nifs/common/socket_util.c
@@ -35,6 +35,10 @@
#include "socket_util.h"
#include "socket_dbg.h"
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
/* We don't have a "debug flag" to check here, so we
* should use the compile debug flag, whatever that is...
*/
@@ -51,12 +55,10 @@
extern char* erl_errno_id(int error); /* THIS IS JUST TEMPORARY??? */
-#if defined(CLOCK_REALTIME)
-static int realtime(struct timespec* tsP);
-static int timespec2str(char *buf,
- unsigned int len,
- struct timespec *ts);
+#if (defined(HAVE_LOCALTIME_R) && defined(HAVE_STRFTIME))
+#define ESOCK_USE_PRETTY_TIMESTAMP 1
#endif
+
static char* make_sockaddr_in4(ErlNifEnv* env,
ERL_NIF_TERM port,
@@ -739,16 +741,24 @@ char* esock_decode_ip4_address(ErlNifEnv* env,
"\r\n", eAddr) );
if (IS_ATOM(env, eAddr)) {
- /* This is either 'any' or 'loopback' */
+
+ /* This is either 'any' | 'broadcast' | 'loopback' */
if (COMPARE(esock_atom_loopback, eAddr) == 0) {
- UDBG( ("SUTIL", "esock_decode_ip4_address -> address: lookback\r\n") );
+ UDBG( ("SUTIL",
+ "esock_decode_ip4_address -> address: lookback\r\n") );
addr.s_addr = htonl(INADDR_LOOPBACK);
} else if (COMPARE(esock_atom_any, eAddr) == 0) {
- UDBG( ("SUTIL", "esock_decode_ip4_address -> address: any\r\n") );
- addr.s_addr = htonl(INADDR_ANY);
+ UDBG( ("SUTIL",
+ "esock_decode_ip4_address -> address: any\r\n") );
+ addr.s_addr = htonl(INADDR_ANY);
+ } else if (COMPARE(esock_atom_broadcast, eAddr) == 0) {
+ UDBG( ("SUTIL",
+ "esock_decode_ip4_address -> address: broadcast\r\n") );
+ addr.s_addr = htonl(INADDR_BROADCAST);
} else {
- UDBG( ("SUTIL", "esock_decode_ip4_address -> address: unknown\r\n") );
+ UDBG( ("SUTIL",
+ "esock_decode_ip4_address -> address: unknown\r\n") );
return ESOCK_STR_EINVAL;
}
@@ -984,9 +994,27 @@ char* esock_decode_timeval(ErlNifEnv* env,
if (!GET_LONG(env, eSec, &timeP->tv_sec))
return ESOCK_STR_EINVAL;
+#if (SIZEOF_INT == 4)
+ {
+ int usec;
+ if (!GET_INT(env, eUSec, &usec))
+ return ESOCK_STR_EINVAL;
+ timeP->tv_usec = (typeof(timeP->tv_usec)) usec;
+ }
+#elif (SIZEOF_LONG == 4)
+ {
+ long usec;
+ if (!GET_LONG(env, eUSec, &usec))
+ return ESOCK_STR_EINVAL;
+ timeP->tv_usec = (typeof(timeP->tv_usec)) usec;
+ }
+#else
+ /* Ok, we give up... */
if (!GET_LONG(env, eUSec, &timeP->tv_usec))
return ESOCK_STR_EINVAL;
+#endif
+
return NULL;
}
@@ -1510,10 +1538,7 @@ void esock_warning_msg( const char* format, ... )
{
va_list args;
char f[512 + sizeof(format)]; // This has to suffice...
-#if defined(CLOCK_REALTIME)
char stamp[64]; // Just in case...
- struct timespec ts;
-#endif
int res;
/*
@@ -1525,18 +1550,13 @@ void esock_warning_msg( const char* format, ... )
// 2018-06-29 12:13:21.232089
// 29-Jun-2018::13:47:25.097097
-#if defined(CLOCK_REALTIME)
- if (!realtime(&ts) &&
- (timespec2str(stamp, sizeof(stamp), &ts) == 0)) {
+ if (esock_timestamp(stamp, sizeof(stamp))) {
res = enif_snprintf(f, sizeof(f),
"=WARNING MSG==== %s ===\r\n%s",
stamp, format);
} else {
res = enif_snprintf(f, sizeof(f), "=WARNING MSG==== %s", format);
}
-#else
- res = enif_snprintf(f, sizeof(f), "=WARNING MSG==== %s", format);
-#endif
if (res > 0) {
va_start (args, format);
@@ -1549,43 +1569,52 @@ void esock_warning_msg( const char* format, ... )
}
-#if defined(CLOCK_REALTIME)
-static
-int realtime(struct timespec* tsP)
-{
- return clock_gettime(CLOCK_REALTIME, tsP);
-}
-
-
-/*
- * Convert a timespec struct into a readable/printable string.
+/* *** esock_timestamp ***
*
- * "%F::%T" => 2018-06-29 12:13:21[.232089]
- * "%d-%b-%Y::%T" => 29-Jun-2018::13:47:25.097097
+ * Create a timestamp string.
+ * If awailable, we use the localtime_r and strftime function(s)
+ * to produces a nice readable timestamp. But if not (awailable),
+ * it produces a timestamp in the form of an "Epoch" (A real epoch
+ * is the number of seconds since 1/1 1970, but our timestamp is
+ * the number micro seconds since 1/1 1970).
*/
-static
-int timespec2str(char *buf, unsigned int len, struct timespec *ts)
-{
- int ret, buflen;
- struct tm t;
- tzset();
- if (localtime_r(&(ts->tv_sec), &t) == NULL)
- return 1;
+extern
+BOOLEAN_T esock_timestamp(char *buf, unsigned int len)
+{
+ int ret;
+ ErlNifTime monTime = enif_monotonic_time(ERL_NIF_USEC);
+ ErlNifTime offTime = enif_time_offset(ERL_NIF_USEC);
+ ErlNifTime time = monTime + offTime;
+#if defined(ESOCK_USE_PRETTY_TIMESTAMP)
+ time_t sec = time / 1000000; // (if _MSEC) sec = time / 1000;
+ time_t usec = time % 1000000; // (if _MSEC) msec = time % 1000;
+ int buflen;
+ struct tm t;
+
+ if (localtime_r(&sec, &t) == NULL)
+ return FALSE;
- ret = strftime(buf, len, "%d-%B-%Y::%T", &t);
- if (ret == 0)
- return 2;
- len -= ret - 1;
- buflen = strlen(buf);
+ ret = strftime(buf, len, "%d-%B-%Y::%T", &t);
+ if (ret == 0)
+ return FALSE;
+ len -= ret - 1;
+ buflen = strlen(buf);
- ret = snprintf(&buf[buflen], len, ".%06ld", ts->tv_nsec/1000);
- if (ret >= len)
- return 3;
+ ret = enif_snprintf(&buf[buflen], len, ".%06b64d", usec);
+ if (ret >= len)
+ return FALSE;
- return 0;
-}
+ return TRUE;
+#else
+ ret = enif_snprintf(buf, len, "%b64d", time);
+ if (ret == 0)
+ return FALSE;
+ else
+ return TRUE;
#endif
+}
+
/* =================================================================== *
@@ -1653,7 +1682,7 @@ char* make_sockaddr_un(ErlNifEnv* env,
ERL_NIF_TERM* sa)
{
ERL_NIF_TERM keys[] = {esock_atom_family, esock_atom_path};
- ERL_NIF_TERM vals[] = {esock_atom_inet, path};
+ ERL_NIF_TERM vals[] = {esock_atom_local, path};
unsigned int numKeys = sizeof(keys) / sizeof(ERL_NIF_TERM);
unsigned int numVals = sizeof(vals) / sizeof(ERL_NIF_TERM);