From 30d5b7ee32d099f2a23c26e873aeb08be1b1d966 Mon Sep 17 00:00:00 2001
From: Sverker Eriksson
Date: Thu, 15 Mar 2018 17:14:39 +0100
Subject: erts: Add enif_*_name functions
---
erts/doc/src/erl_nif.xml | 40 ++++++++++++++++++++++++++++++++++
erts/emulator/beam/erl_nif.c | 6 +++++
erts/emulator/beam/erl_nif.h | 2 +-
erts/emulator/beam/erl_nif_api_funcs.h | 9 ++++++++
4 files changed, 56 insertions(+), 1 deletion(-)
diff --git a/erts/doc/src/erl_nif.xml b/erts/doc/src/erl_nif.xml
index 9b446615a4..9d92e87baa 100644
--- a/erts/doc/src/erl_nif.xml
+++ b/erts/doc/src/erl_nif.xml
@@ -1103,6 +1103,16 @@ typedef struct {
+
+ char*
+ enif_cond_name(ErlNifCond* cnd)
+
+
+ Same as
+ erl_drv_cond_name.
+
+
+
void
enif_cond_signal(ErlNifCond *cnd)
@@ -2626,6 +2636,16 @@ enif_map_iterator_destroy(env, &iter);
+
+ char*
+ enif_mutex_name(ErlNifMutex* mtx)
+
+
+ Same as
+ erl_drv_mutex_name.
+
+
+
int
enif_mutex_trylock(ErlNifMutex *mtx)
@@ -2870,6 +2890,16 @@ enif_map_iterator_destroy(env, &iter);
+
+ char*
+ enif_rwlock_name(ErlNifRWLock* rwlck)
+
+
+ Same as
+ erl_drv_rwlock_name.
+
+
+
void
enif_rwlock_rlock(ErlNifRWLock *rwlck)
@@ -3211,6 +3241,16 @@ if (retval & ERL_NIF_SELECT_STOP_CALLED) {
+
+ char*
+ enif_thread_name(ErlNifTid tid)
+ Thread name
+
+ Same as
+ erl_drv_thread_name.
+
+
+
ErlNifThreadOpts *
enif_thread_opts_create(char *name)
diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c
index c60cc7fecf..332e692fd6 100644
--- a/erts/emulator/beam/erl_nif.c
+++ b/erts/emulator/beam/erl_nif.c
@@ -1963,6 +1963,12 @@ ErlNifTid enif_thread_self(void) { return erl_drv_thread_self(); }
int enif_equal_tids(ErlNifTid tid1, ErlNifTid tid2) { return erl_drv_equal_tids(tid1,tid2); }
void enif_thread_exit(void *resp) { erl_drv_thread_exit(resp); }
int enif_thread_join(ErlNifTid tid, void **respp) { return erl_drv_thread_join(tid,respp); }
+
+char* enif_mutex_name(ErlNifMutex *mtx) {return erl_drv_mutex_name(mtx); }
+char* enif_cond_name(ErlNifCond *cnd) { return erl_drv_cond_name(cnd); }
+char* enif_rwlock_name(ErlNifRWLock* rwlck) { return erl_drv_rwlock_name(rwlck); }
+char* enif_thread_name(ErlNifTid tid) { return erl_drv_thread_name(tid); }
+
int enif_getenv(const char *key, char *value, size_t *value_size) { return erl_drv_getenv(key, value, value_size); }
ErlNifTime enif_monotonic_time(ErlNifTimeUnit time_unit)
diff --git a/erts/emulator/beam/erl_nif.h b/erts/emulator/beam/erl_nif.h
index a99b4db705..14682add51 100644
--- a/erts/emulator/beam/erl_nif.h
+++ b/erts/emulator/beam/erl_nif.h
@@ -52,7 +52,7 @@
** 2.11: 19.0 enif_snprintf
** 2.12: 20.0 add enif_select, enif_open_resource_type_x
** 2.13: 20.1 add enif_ioq
-** 2.14: 21.0 add enif_ioq_peek_head
+** 2.14: 21.0 add enif_ioq_peek_head, enif_(mutex|cond|rwlock|thread)_name
*/
#define ERL_NIF_MAJOR_VERSION 2
#define ERL_NIF_MINOR_VERSION 14
diff --git a/erts/emulator/beam/erl_nif_api_funcs.h b/erts/emulator/beam/erl_nif_api_funcs.h
index 3750fd9b68..09250bfaf0 100644
--- a/erts/emulator/beam/erl_nif_api_funcs.h
+++ b/erts/emulator/beam/erl_nif_api_funcs.h
@@ -200,6 +200,11 @@ ERL_NIF_API_FUNC_DECL(void,enif_free_iovec,(ErlNifIOVec *iov));
ERL_NIF_API_FUNC_DECL(int,enif_ioq_peek_head,(ErlNifEnv *env, ErlNifIOQueue *q, size_t *size, ERL_NIF_TERM *head));
+ERL_NIF_API_FUNC_DECL(char*,enif_mutex_name,(ErlNifMutex*));
+ERL_NIF_API_FUNC_DECL(char*,enif_cond_name,(ErlNifCond*));
+ERL_NIF_API_FUNC_DECL(char*,enif_rwlock_name,(ErlNifRWLock*));
+ERL_NIF_API_FUNC_DECL(char*,enif_thread_name,(ErlNifTid));
+
/*
** ADD NEW ENTRIES HERE (before this comment) !!!
*/
@@ -375,6 +380,10 @@ ERL_NIF_API_FUNC_DECL(int,enif_ioq_peek_head,(ErlNifEnv *env, ErlNifIOQueue *q,
# define enif_inspect_iovec ERL_NIF_API_FUNC_MACRO(enif_inspect_iovec)
# define enif_free_iovec ERL_NIF_API_FUNC_MACRO(enif_free_iovec)
# define enif_ioq_peek_head ERL_NIF_API_FUNC_MACRO(enif_ioq_peek_head)
+# define enif_mutex_name ERL_NIF_API_FUNC_MACRO(enif_mutex_name)
+# define enif_cond_name ERL_NIF_API_FUNC_MACRO(enif_cond_name)
+# define enif_rwlock_name ERL_NIF_API_FUNC_MACRO(enif_rwlock_name)
+# define enif_thread_name ERL_NIF_API_FUNC_MACRO(enif_thread_name)
/*
** ADD NEW ENTRIES HERE (before this comment)
--
cgit v1.2.3
From e36c103236ac70c29caf910d31651bed6c24dfe8 Mon Sep 17 00:00:00 2001
From: Sverker Eriksson
Date: Thu, 15 Mar 2018 21:02:47 +0100
Subject: erts: Add enif_vfprintf and enif_vsnprintf
---
erts/doc/src/erl_nif.xml | 26 +++++++++++++++++++++++++-
erts/emulator/beam/erl_nif.c | 15 +++++++++++++--
erts/emulator/beam/erl_nif.h | 3 +++
erts/emulator/beam/erl_nif_api_funcs.h | 7 ++++++-
4 files changed, 47 insertions(+), 4 deletions(-)
diff --git a/erts/doc/src/erl_nif.xml b/erts/doc/src/erl_nif.xml
index 9d92e87baa..1daac88d47 100644
--- a/erts/doc/src/erl_nif.xml
+++ b/erts/doc/src/erl_nif.xml
@@ -875,7 +875,7 @@ typedef enum {
-
An enumeration of the properties that can be requested from
- enif_unique_integer.
+ enif_make_unique_integer.
For default properties, use value 0.
ERL_NIF_UNIQUE_POSITIVE
@@ -3367,6 +3367,30 @@ if (retval & ERL_NIF_SELECT_STOP_CALLED) {
+
+ int
+ enif_vfprintf(FILE *stream, const char *format, va_list ap)
+
+ Format strings and Erlang terms.
+
+ Equivalent to enif_fprintf
+ except that its called with a va_list instead of a variable number of
+ arguments.
+
+
+
+
+ int
+ enif_vsnprintf(char *str, size_t size, const char *format, va_list ap)
+
+ Format strings and Erlang terms.
+
+ Equivalent to enif_snprintf
+ except that its called with a va_list instead of a variable number of
+ arguments.
+
+
+
int
enif_whereis_pid(ErlNifEnv *env,
diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c
index 332e692fd6..2c851fd531 100644
--- a/erts/emulator/beam/erl_nif.c
+++ b/erts/emulator/beam/erl_nif.c
@@ -1991,16 +1991,21 @@ enif_convert_time_unit(ErlNifTime val,
(int) to);
}
-int enif_fprintf(void* filep, const char* format, ...)
+int enif_fprintf(FILE* filep, const char* format, ...)
{
int ret;
va_list arglist;
va_start(arglist, format);
- ret = erts_vfprintf((FILE*)filep, format, arglist);
+ ret = erts_vfprintf(filep, format, arglist);
va_end(arglist);
return ret;
}
+int enif_vfprintf(FILE* filep, const char *format, va_list ap)
+{
+ return erts_vfprintf(filep, format, ap);
+}
+
int enif_snprintf(char *buffer, size_t size, const char* format, ...)
{
int ret;
@@ -2011,6 +2016,12 @@ int enif_snprintf(char *buffer, size_t size, const char* format, ...)
return ret;
}
+int enif_vsnprintf(char* buffer, size_t size, const char *format, va_list ap)
+{
+ return erts_vsnprintf(buffer, size, format, ap);
+}
+
+
/***********************************************************
** Memory managed (GC'ed) "resource" objects **
***********************************************************/
diff --git a/erts/emulator/beam/erl_nif.h b/erts/emulator/beam/erl_nif.h
index 14682add51..30eff9fcb9 100644
--- a/erts/emulator/beam/erl_nif.h
+++ b/erts/emulator/beam/erl_nif.h
@@ -53,6 +53,7 @@
** 2.12: 20.0 add enif_select, enif_open_resource_type_x
** 2.13: 20.1 add enif_ioq
** 2.14: 21.0 add enif_ioq_peek_head, enif_(mutex|cond|rwlock|thread)_name
+** enif_vfprintf, enif_vsnprintf
*/
#define ERL_NIF_MAJOR_VERSION 2
#define ERL_NIF_MINOR_VERSION 14
@@ -70,6 +71,8 @@
#define ERL_NIF_MIN_REQUIRED_MAJOR_VERSION_ON_LOAD 2
#include
+#include
+#include
#ifdef __cplusplus
extern "C" {
diff --git a/erts/emulator/beam/erl_nif_api_funcs.h b/erts/emulator/beam/erl_nif_api_funcs.h
index 09250bfaf0..744f7c9f69 100644
--- a/erts/emulator/beam/erl_nif_api_funcs.h
+++ b/erts/emulator/beam/erl_nif_api_funcs.h
@@ -92,7 +92,7 @@ ERL_NIF_API_FUNC_DECL(int,enif_thread_join,(ErlNifTid, void **respp));
ERL_NIF_API_FUNC_DECL(void*,enif_realloc,(void* ptr, size_t size));
ERL_NIF_API_FUNC_DECL(void,enif_system_info,(ErlNifSysInfo *sip, size_t si_size));
-ERL_NIF_API_FUNC_DECL(int,enif_fprintf,(void/* FILE* */ *filep, const char *format, ...));
+ERL_NIF_API_FUNC_DECL(int,enif_fprintf,(FILE* filep, const char *format, ...));
ERL_NIF_API_FUNC_DECL(int,enif_inspect_iolist_as_binary,(ErlNifEnv*, ERL_NIF_TERM term, ErlNifBinary* bin));
ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_sub_binary,(ErlNifEnv*, ERL_NIF_TERM bin_term, size_t pos, size_t size));
ERL_NIF_API_FUNC_DECL(int,enif_get_string,(ErlNifEnv*, ERL_NIF_TERM list, char* buf, unsigned len, ErlNifCharEncoding));
@@ -205,6 +205,9 @@ ERL_NIF_API_FUNC_DECL(char*,enif_cond_name,(ErlNifCond*));
ERL_NIF_API_FUNC_DECL(char*,enif_rwlock_name,(ErlNifRWLock*));
ERL_NIF_API_FUNC_DECL(char*,enif_thread_name,(ErlNifTid));
+ERL_NIF_API_FUNC_DECL(int,enif_vfprintf,(FILE*, const char *fmt, va_list));
+ERL_NIF_API_FUNC_DECL(int,enif_vsnprintf,(char*, size_t, const char *fmt, va_list));
+
/*
** ADD NEW ENTRIES HERE (before this comment) !!!
*/
@@ -384,6 +387,8 @@ ERL_NIF_API_FUNC_DECL(char*,enif_thread_name,(ErlNifTid));
# define enif_cond_name ERL_NIF_API_FUNC_MACRO(enif_cond_name)
# define enif_rwlock_name ERL_NIF_API_FUNC_MACRO(enif_rwlock_name)
# define enif_thread_name ERL_NIF_API_FUNC_MACRO(enif_thread_name)
+# define enif_vfprintf ERL_NIF_API_FUNC_MACRO(enif_vfprintf)
+# define enif_vsnprintf ERL_NIF_API_FUNC_MACRO(enif_vsnprintf)
/*
** ADD NEW ENTRIES HERE (before this comment)
--
cgit v1.2.3
From 97a5f6c89c7b937e0a1192e02a7dc94f64f558cf Mon Sep 17 00:00:00 2001
From: Sverker Eriksson
Date: Fri, 16 Mar 2018 17:11:39 +0100
Subject: erts: Add statement about errno to enif_*printf docs
---
erts/doc/src/erl_nif.xml | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/erts/doc/src/erl_nif.xml b/erts/doc/src/erl_nif.xml
index 1daac88d47..6b9ca971dc 100644
--- a/erts/doc/src/erl_nif.xml
+++ b/erts/doc/src/erl_nif.xml
@@ -1252,7 +1252,8 @@ typedef struct {
Similar to fprintf but this format string also accepts
"%T", which formats Erlang terms.
This function was originally intenden for debugging purpose. It is not
- recommended to print very large terms with %T.
+ recommended to print very large terms with %T. The function may
+ change errno, even if successful.
@@ -3178,7 +3179,8 @@ if (retval & ERL_NIF_SELECT_STOP_CALLED) {
Similar to snprintf but this format string also accepts
"%T", which formats Erlang terms.
This function was originally intenden for debugging purpose. It is not
- recommended to print very large terms with %T.
+ recommended to print very large terms with %T. The function may
+ change errno, even if successful.
--
cgit v1.2.3
From 0c33c7eb6642adf974fcd2b0426198bd666d28e2 Mon Sep 17 00:00:00 2001
From: Sverker Eriksson
Date: Fri, 16 Mar 2018 20:02:21 +0100
Subject: erts: Remove const from ErlNifResourceDown doc
to conform with erl_nif.h
---
erts/doc/src/erl_nif.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/erts/doc/src/erl_nif.xml b/erts/doc/src/erl_nif.xml
index 6b9ca971dc..5c7d91b9c2 100644
--- a/erts/doc/src/erl_nif.xml
+++ b/erts/doc/src/erl_nif.xml
@@ -809,7 +809,7 @@ typedef void ErlNifResourceDtor(ErlNifEnv* env, void* obj);
ErlNifResourceDown
-
-typedef void ErlNifResourceDown(ErlNifEnv* env, void* obj, const ErlNifPid* pid, const ErlNifMonitor* mon);
+typedef void ErlNifResourceDown(ErlNifEnv* env, void* obj, ErlNifPid* pid, ErlNifMonitor* mon);
The function prototype of a resource down function,
called on the behalf of
enif_monitor_process. obj is the resource, pid
--
cgit v1.2.3
From cbc7ef1f665423aabba3836b79017682ca1b0816 Mon Sep 17 00:00:00 2001
From: Sverker Eriksson
Date: Fri, 16 Mar 2018 20:57:41 +0100
Subject: erts: Improve NIF load incompatibility errors
---
erts/emulator/beam/erl_nif.c | 21 ++++++++++++++++-----
erts/emulator/beam/erl_nif.h | 7 ++++++-
2 files changed, 22 insertions(+), 6 deletions(-)
diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c
index 2c851fd531..99079dabf6 100644
--- a/erts/emulator/beam/erl_nif.c
+++ b/erts/emulator/beam/erl_nif.c
@@ -3873,6 +3873,11 @@ static struct erl_module_nif* create_lib(const ErlNifEntry* src)
} else {
dst->sizeof_ErlNifResourceTypeInit = 0;
}
+ if (AT_LEAST_VERSION(src, 2, 14)) {
+ dst->min_erts = src->min_erts;
+ } else {
+ dst->min_erts = "erts-?";
+ }
return lib;
};
@@ -3985,14 +3990,20 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2)
(entry = erts_sys_ddll_call_nif_init(init_func)) == NULL)) {
ret = load_nif_error(BIF_P, bad_lib, "Library init-call unsuccessful");
}
+ else if (entry->major > ERL_NIF_MAJOR_VERSION
+ || (entry->major == ERL_NIF_MAJOR_VERSION
+ && entry->minor > ERL_NIF_MINOR_VERSION)) {
+ char* fmt = "That '%T' NIF library needs %s or newer. Either try to"
+ " recompile the NIF lib or use a newer erts runtime.";
+ ret = load_nif_error(BIF_P, bad_lib, fmt, mod_atom, entry->min_erts);
+ }
else if (entry->major < ERL_NIF_MIN_REQUIRED_MAJOR_VERSION_ON_LOAD
- || (ERL_NIF_MAJOR_VERSION < entry->major
- || (ERL_NIF_MAJOR_VERSION == entry->major
- && ERL_NIF_MINOR_VERSION < entry->minor))
|| (entry->major==2 && entry->minor == 5)) { /* experimental maps */
- ret = load_nif_error(BIF_P, bad_lib, "Library version (%d.%d) not compatible (with %d.%d).",
- entry->major, entry->minor, ERL_NIF_MAJOR_VERSION, ERL_NIF_MINOR_VERSION);
+ char* fmt = "That old NIF library (%d.%d) is not compatible with this "
+ "erts runtime (%d.%d). Try recompile the NIF lib.";
+ ret = load_nif_error(BIF_P, bad_lib, fmt, entry->major, entry->minor,
+ ERL_NIF_MAJOR_VERSION, ERL_NIF_MINOR_VERSION);
}
else if (AT_LEAST_VERSION(entry, 2, 1)
&& sys_strcmp(entry->vm_variant, ERL_NIF_VM_VARIANT) != 0) {
diff --git a/erts/emulator/beam/erl_nif.h b/erts/emulator/beam/erl_nif.h
index 30eff9fcb9..e051ecb26e 100644
--- a/erts/emulator/beam/erl_nif.h
+++ b/erts/emulator/beam/erl_nif.h
@@ -57,6 +57,7 @@
*/
#define ERL_NIF_MAJOR_VERSION 2
#define ERL_NIF_MINOR_VERSION 14
+#define ERL_NIF_MIN_ERTS_VERSION "erts-10.0 (OTP-21)"
/*
* The emulator will refuse to load a nif-lib with a major version
@@ -131,6 +132,9 @@ typedef struct enif_entry_t
/* Added in 2.12 */
size_t sizeof_ErlNifResourceTypeInit;
+
+ /* Added in 2.14 */
+ const char* min_erts;
}ErlNifEntry;
@@ -353,7 +357,8 @@ ERL_NIF_INIT_DECL(NAME) \
LOAD, RELOAD, UPGRADE, UNLOAD, \
ERL_NIF_VM_VARIANT, \
1, \
- sizeof(ErlNifResourceTypeInit) \
+ sizeof(ErlNifResourceTypeInit), \
+ ERL_NIF_MIN_ERTS_VERSION \
}; \
ERL_NIF_INIT_BODY; \
return &entry; \
--
cgit v1.2.3
From 6ee8cc56db53fd7951fb3bacfd6621c72fdf3ced Mon Sep 17 00:00:00 2001
From: Sverker Eriksson
Date: Fri, 16 Mar 2018 21:22:29 +0100
Subject: crypto: Improve load error message
to only suggest missing OpenSSL if dlopen fails (load_failed).
---
lib/crypto/src/crypto.erl | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl
index ec2a1dba0a..46775989ae 100644
--- a/lib/crypto/src/crypto.erl
+++ b/lib/crypto/src/crypto.erl
@@ -847,8 +847,13 @@ on_load() ->
case Status of
ok -> ok;
{error, {E, Str}} ->
- error_logger:error_msg("Unable to load crypto library. Failed with error:~n\"~p, ~s\"~n"
- "OpenSSL might not be installed on this system.~n",[E,Str]),
+ Fmt = "Unable to load crypto library. Failed with error:~n\"~p, ~s\"~n~s",
+ Extra = case E of
+ load_failed ->
+ "OpenSSL might not be installed on this system.\n";
+ _ -> ""
+ end,
+ error_logger:error_msg(Fmt, [E,Str,Extra]),
Status
end.
--
cgit v1.2.3