From 200fbe924466720bd2a8c5eb05b05d67b0a2414c Mon Sep 17 00:00:00 2001
From: Lukas Larsson
Date: Thu, 14 Mar 2013 15:42:19 +0100
Subject: Added support for ENEA OSE
This port has support for both non-smp and smp.
It contains a new way to do io checking in which erts_poll_wait
receives the payload of the polled entity. This has implications
for all linked-in drivers.
---
lib/asn1/Makefile | 2 +-
lib/asn1/c_src/Makefile | 7 +++++++
lib/asn1/c_src/asn1_erl_nif.c | 1 +
lib/crypto/c_src/Makefile.in | 7 +++++++
lib/erl_interface/aclocal.m4 | 41 ++++++++++++++++++++++++++++++++-----
lib/hipe/cerl/erl_bif_types.erl | 3 ++-
lib/megaco/aclocal.m4 | 41 ++++++++++++++++++++++++++++++++-----
lib/odbc/aclocal.m4 | 41 ++++++++++++++++++++++++++++++++-----
lib/runtime_tools/c_src/Makefile.in | 7 +++++++
lib/stdlib/src/filename.erl | 6 ++++--
lib/tools/c_src/Makefile.in | 8 ++++++++
lib/wx/aclocal.m4 | 41 ++++++++++++++++++++++++++++++++-----
12 files changed, 181 insertions(+), 24 deletions(-)
(limited to 'lib')
diff --git a/lib/asn1/Makefile b/lib/asn1/Makefile
index 1bc303b73c..18e95a2471 100644
--- a/lib/asn1/Makefile
+++ b/lib/asn1/Makefile
@@ -25,6 +25,7 @@ include $(ERL_TOP)/make/$(TARGET)/otp.mk
#
SUB_DIRECTORIES = src doc/src c_src
+
static_lib: SUB_DIRECTORIES = c_src
@@ -62,7 +63,6 @@ info:
version:
@echo "$(VSN)"
-
# ----------------------------------------------------
# Application (source) release targets
# ----------------------------------------------------
diff --git a/lib/asn1/c_src/Makefile b/lib/asn1/c_src/Makefile
index ded4b73d1b..a7cd03f516 100644
--- a/lib/asn1/c_src/Makefile
+++ b/lib/asn1/c_src/Makefile
@@ -96,7 +96,12 @@ endif
_create_dirs := $(shell mkdir -p $(OBJDIR) $(LIBDIR))
+ifneq ($(findstring ose,$(TARGET)),ose)
opt: $(NIF_SHARED_OBJ_FILE)
+else
+# Do not build dynamic files on OSE
+opt:
+endif
debug: opt
@@ -134,7 +139,9 @@ include $(ERL_TOP)/make/otp_release_targets.mk
release_spec: opt
$(INSTALL_DIR) "$(RELSYSDIR)/priv/lib"
+ifneq ($(findstring ose,$(TARGET)),ose)
$(INSTALL_PROGRAM) $(NIF_SHARED_OBJ_FILE) "$(RELSYSDIR)/priv/lib"
+endif
$(INSTALL_DIR) "$(RELSYSDIR)/c_src"
$(INSTALL_DATA) *.c "$(RELSYSDIR)/c_src"
diff --git a/lib/asn1/c_src/asn1_erl_nif.c b/lib/asn1/c_src/asn1_erl_nif.c
index 0930010fda..8a0e4b1cf0 100644
--- a/lib/asn1/c_src/asn1_erl_nif.c
+++ b/lib/asn1/c_src/asn1_erl_nif.c
@@ -1320,6 +1320,7 @@ static void unload(ErlNifEnv* env, void* priv_data) {
}
+
static ErlNifFunc nif_funcs[] = {
{ "encode_per_complete", 1, encode_per_complete },
{ "decode_ber_tlv_raw", 1, decode_ber_tlv_raw },
diff --git a/lib/crypto/c_src/Makefile.in b/lib/crypto/c_src/Makefile.in
index 124d088056..8c92b5ba1b 100644
--- a/lib/crypto/c_src/Makefile.in
+++ b/lib/crypto/c_src/Makefile.in
@@ -126,7 +126,12 @@ ALL_STATIC_CFLAGS = $(DED_STATIC_CFLAGS) $(INCLUDES)
_create_dirs := $(shell mkdir -p $(OBJDIR) $(LIBDIR))
+ifneq ($(findstring ose,$(TARGET)),ose)
debug opt valgrind: $(NIF_LIB) $(CALLBACK_LIB)
+else
+# Do not build dynamic files on OSE
+debug opt valgrind:
+endif
static_lib: $(NIF_ARCHIVE)
@@ -197,12 +202,14 @@ release_spec: opt
$(INSTALL_DIR) "$(RELSYSDIR)/priv/obj"
$(INSTALL_DIR) "$(RELSYSDIR)/priv/lib"
$(INSTALL_DATA) $(NIF_MAKEFILE) "$(RELSYSDIR)/priv/obj"
+ifneq ($(findstring ose,$(TARGET)),ose)
$(INSTALL_PROGRAM) $(CRYPTO_OBJS) "$(RELSYSDIR)/priv/obj"
$(INSTALL_PROGRAM) $(NIF_LIB) "$(RELSYSDIR)/priv/lib"
ifeq ($(DYNAMIC_CRYPTO_LIB),yes)
$(INSTALL_PROGRAM) $(CALLBACK_OBJS) "$(RELSYSDIR)/priv/obj"
$(INSTALL_PROGRAM) $(CALLBACK_LIB) "$(RELSYSDIR)/priv/lib"
endif
+endif
release_docs_spec:
diff --git a/lib/erl_interface/aclocal.m4 b/lib/erl_interface/aclocal.m4
index 46b30a16b3..4a3407e0eb 100644
--- a/lib/erl_interface/aclocal.m4
+++ b/lib/erl_interface/aclocal.m4
@@ -74,6 +74,17 @@ AC_ARG_VAR(erl_xcomp_clock_gettime_cpu_time, [clock_gettime() can be used for re
AC_ARG_VAR(erl_xcomp_after_morecore_hook, [__after_morecore_hook can track malloc()s core memory usage: yes|no (only used when cross compiling)])
AC_ARG_VAR(erl_xcomp_dlsym_brk_wrappers, [dlsym(RTLD_NEXT, _) brk wrappers can track malloc()s core memory usage: yes|no (only used when cross compiling)])
+dnl Cross compilation variables for OSE
+AC_ARG_VAR(erl_xcomp_ose_ldflags_pass1, [Linker flags for the OSE module (pass 1) (only used when cross compiling for OSE)])
+AC_ARG_VAR(erl_xcomp_ose_ldflags_pass2, [Linker flags for the OSE module (pass 2) (only used when cross compiling for OSE)])
+AC_ARG_VAR(erl_xcomp_ose_OSEROOT, [OSE installation root directory (only used when cross compiling for OSE)])
+AC_ARG_VAR(erl_xcomp_ose_STRIP, [Strip utility shipped with the OSE distribution(only used when cross compiling for OSE)])
+AC_ARG_VAR(erl_xcomp_ose_LM_POST_LINK, [OSE postlink tool (only used when cross compiling for OSE)])
+AC_ARG_VAR(erl_xcomp_ose_LM_SET_CONF, [Sets the configuration for an OSE load module (only used when cross compiling for OSE)])
+AC_ARG_VAR(erl_xcomp_ose_LM_ELF_SIZE, [Prints the section size information for an OSE load module (only used when cross compiling for OSE)])
+AC_ARG_VAR(erl_xcomp_ose_LM_LCF, [OSE load module linker configuration file (only used when cross compiling for OSE)])
+AC_ARG_VAR(erl_xcomp_ose_LM_CONF, [OSE load module default configuration file (only used when cross compiling for OSE)])
+
])
AC_DEFUN(ERL_XCOMP_SYSROOT_INIT,
@@ -488,6 +499,8 @@ AC_CACHE_VAL(ac_cv_sys_ipv6_support,
#ifdef __WIN32__
#include
#include
+#elif __OSE__
+#error "no ipv6"
#else
#include
#endif],
@@ -500,6 +513,8 @@ else
#ifdef __WIN32__
#include
#include
+#elif __OSE__
+#error "no ipv6"
#else
#include
#endif],
@@ -728,6 +743,12 @@ if test "X$host_os" = "Xwin32"; then
THR_LIBS=
THR_LIB_NAME=win32_threads
THR_LIB_TYPE=win32_threads
+elif test "X$host_os" = "Xose"; then
+ AC_MSG_RESULT(yes)
+ THR_DEFS="-DOSE_THREADS"
+ THR_LIBS=
+ THR_LIB_NAME=ose_threads
+ THR_LIB_TYPE=ose_threads
else
AC_MSG_RESULT(no)
THR_DEFS=
@@ -1078,9 +1099,17 @@ case "$THR_LIB_NAME" in
test "$ethr_have_native_atomics" = "yes" && ethr_have_native_spinlock=yes
;;
- pthread)
- ETHR_THR_LIB_BASE_DIR=pthread
- AC_DEFINE(ETHR_PTHREADS, 1, [Define if you have pthreads])
+ pthread|ose_threads)
+ case "$THR_LIB_NAME" in
+ pthread)
+ ETHR_THR_LIB_BASE_DIR=pthread
+ AC_DEFINE(ETHR_PTHREADS, 1, [Define if you have pthreads])
+ ;;
+ ose_threads)
+ AC_DEFINE(ETHR_OSE_THREADS, 1, [Define if you have OSE style threads]) ETHR_THR_LIB_BASE_DIR=ose
+ ;;
+ esac
+ if test "x$THR_LIB_NAME" == "xpthread"; then
case $host_os in
openbsd*)
# The default stack size is insufficient for our needs
@@ -1139,6 +1168,7 @@ case "$THR_LIB_NAME" in
*) ;;
esac
+ fi
dnl We sometimes need ETHR_DEFS in order to find certain headers
dnl (at least for pthread.h on osf1).
saved_cppflags="$CPPFLAGS"
@@ -1151,7 +1181,6 @@ case "$THR_LIB_NAME" in
dnl
dnl Check for headers
dnl
-
AC_CHECK_HEADER(pthread.h, \
AC_DEFINE(ETHR_HAVE_PTHREAD_H, 1, \
[Define if you have the header file.]))
@@ -1184,7 +1213,7 @@ case "$THR_LIB_NAME" in
dnl
dnl Check for functions
dnl
-
+ if test "x$THR_LIB_NAME" == "xpthread"; then
AC_CHECK_FUNC(pthread_spin_lock, \
[ethr_have_native_spinlock=yes \
AC_DEFINE(ETHR_HAVE_PTHREAD_SPIN_LOCK, 1, \
@@ -1311,6 +1340,8 @@ case "$THR_LIB_NAME" in
AC_MSG_RESULT([$linux_futex])
test $linux_futex = yes && AC_DEFINE(ETHR_HAVE_LINUX_FUTEX, 1, [Define if you have a linux futex implementation.])
+ fi
+
AC_CHECK_SIZEOF(int)
AC_CHECK_SIZEOF(long)
AC_CHECK_SIZEOF(long long)
diff --git a/lib/hipe/cerl/erl_bif_types.erl b/lib/hipe/cerl/erl_bif_types.erl
index 8b610ac893..0512d4bc3c 100644
--- a/lib/hipe/cerl/erl_bif_types.erl
+++ b/lib/hipe/cerl/erl_bif_types.erl
@@ -912,7 +912,8 @@ type(erlang, system_info, 1, Xs, Opaques) ->
t_list(t_pid());
['os_type'] ->
t_tuple([t_sup([t_atom('unix'),
- t_atom('win32')]),
+ t_atom('win32'),
+ t_atom('ose')]),
t_atom()]);
['os_version'] ->
t_sup(t_tuple([t_non_neg_fixnum(),
diff --git a/lib/megaco/aclocal.m4 b/lib/megaco/aclocal.m4
index 46b30a16b3..4a3407e0eb 100644
--- a/lib/megaco/aclocal.m4
+++ b/lib/megaco/aclocal.m4
@@ -74,6 +74,17 @@ AC_ARG_VAR(erl_xcomp_clock_gettime_cpu_time, [clock_gettime() can be used for re
AC_ARG_VAR(erl_xcomp_after_morecore_hook, [__after_morecore_hook can track malloc()s core memory usage: yes|no (only used when cross compiling)])
AC_ARG_VAR(erl_xcomp_dlsym_brk_wrappers, [dlsym(RTLD_NEXT, _) brk wrappers can track malloc()s core memory usage: yes|no (only used when cross compiling)])
+dnl Cross compilation variables for OSE
+AC_ARG_VAR(erl_xcomp_ose_ldflags_pass1, [Linker flags for the OSE module (pass 1) (only used when cross compiling for OSE)])
+AC_ARG_VAR(erl_xcomp_ose_ldflags_pass2, [Linker flags for the OSE module (pass 2) (only used when cross compiling for OSE)])
+AC_ARG_VAR(erl_xcomp_ose_OSEROOT, [OSE installation root directory (only used when cross compiling for OSE)])
+AC_ARG_VAR(erl_xcomp_ose_STRIP, [Strip utility shipped with the OSE distribution(only used when cross compiling for OSE)])
+AC_ARG_VAR(erl_xcomp_ose_LM_POST_LINK, [OSE postlink tool (only used when cross compiling for OSE)])
+AC_ARG_VAR(erl_xcomp_ose_LM_SET_CONF, [Sets the configuration for an OSE load module (only used when cross compiling for OSE)])
+AC_ARG_VAR(erl_xcomp_ose_LM_ELF_SIZE, [Prints the section size information for an OSE load module (only used when cross compiling for OSE)])
+AC_ARG_VAR(erl_xcomp_ose_LM_LCF, [OSE load module linker configuration file (only used when cross compiling for OSE)])
+AC_ARG_VAR(erl_xcomp_ose_LM_CONF, [OSE load module default configuration file (only used when cross compiling for OSE)])
+
])
AC_DEFUN(ERL_XCOMP_SYSROOT_INIT,
@@ -488,6 +499,8 @@ AC_CACHE_VAL(ac_cv_sys_ipv6_support,
#ifdef __WIN32__
#include
#include
+#elif __OSE__
+#error "no ipv6"
#else
#include
#endif],
@@ -500,6 +513,8 @@ else
#ifdef __WIN32__
#include
#include
+#elif __OSE__
+#error "no ipv6"
#else
#include
#endif],
@@ -728,6 +743,12 @@ if test "X$host_os" = "Xwin32"; then
THR_LIBS=
THR_LIB_NAME=win32_threads
THR_LIB_TYPE=win32_threads
+elif test "X$host_os" = "Xose"; then
+ AC_MSG_RESULT(yes)
+ THR_DEFS="-DOSE_THREADS"
+ THR_LIBS=
+ THR_LIB_NAME=ose_threads
+ THR_LIB_TYPE=ose_threads
else
AC_MSG_RESULT(no)
THR_DEFS=
@@ -1078,9 +1099,17 @@ case "$THR_LIB_NAME" in
test "$ethr_have_native_atomics" = "yes" && ethr_have_native_spinlock=yes
;;
- pthread)
- ETHR_THR_LIB_BASE_DIR=pthread
- AC_DEFINE(ETHR_PTHREADS, 1, [Define if you have pthreads])
+ pthread|ose_threads)
+ case "$THR_LIB_NAME" in
+ pthread)
+ ETHR_THR_LIB_BASE_DIR=pthread
+ AC_DEFINE(ETHR_PTHREADS, 1, [Define if you have pthreads])
+ ;;
+ ose_threads)
+ AC_DEFINE(ETHR_OSE_THREADS, 1, [Define if you have OSE style threads]) ETHR_THR_LIB_BASE_DIR=ose
+ ;;
+ esac
+ if test "x$THR_LIB_NAME" == "xpthread"; then
case $host_os in
openbsd*)
# The default stack size is insufficient for our needs
@@ -1139,6 +1168,7 @@ case "$THR_LIB_NAME" in
*) ;;
esac
+ fi
dnl We sometimes need ETHR_DEFS in order to find certain headers
dnl (at least for pthread.h on osf1).
saved_cppflags="$CPPFLAGS"
@@ -1151,7 +1181,6 @@ case "$THR_LIB_NAME" in
dnl
dnl Check for headers
dnl
-
AC_CHECK_HEADER(pthread.h, \
AC_DEFINE(ETHR_HAVE_PTHREAD_H, 1, \
[Define if you have the header file.]))
@@ -1184,7 +1213,7 @@ case "$THR_LIB_NAME" in
dnl
dnl Check for functions
dnl
-
+ if test "x$THR_LIB_NAME" == "xpthread"; then
AC_CHECK_FUNC(pthread_spin_lock, \
[ethr_have_native_spinlock=yes \
AC_DEFINE(ETHR_HAVE_PTHREAD_SPIN_LOCK, 1, \
@@ -1311,6 +1340,8 @@ case "$THR_LIB_NAME" in
AC_MSG_RESULT([$linux_futex])
test $linux_futex = yes && AC_DEFINE(ETHR_HAVE_LINUX_FUTEX, 1, [Define if you have a linux futex implementation.])
+ fi
+
AC_CHECK_SIZEOF(int)
AC_CHECK_SIZEOF(long)
AC_CHECK_SIZEOF(long long)
diff --git a/lib/odbc/aclocal.m4 b/lib/odbc/aclocal.m4
index 46b30a16b3..4a3407e0eb 100644
--- a/lib/odbc/aclocal.m4
+++ b/lib/odbc/aclocal.m4
@@ -74,6 +74,17 @@ AC_ARG_VAR(erl_xcomp_clock_gettime_cpu_time, [clock_gettime() can be used for re
AC_ARG_VAR(erl_xcomp_after_morecore_hook, [__after_morecore_hook can track malloc()s core memory usage: yes|no (only used when cross compiling)])
AC_ARG_VAR(erl_xcomp_dlsym_brk_wrappers, [dlsym(RTLD_NEXT, _) brk wrappers can track malloc()s core memory usage: yes|no (only used when cross compiling)])
+dnl Cross compilation variables for OSE
+AC_ARG_VAR(erl_xcomp_ose_ldflags_pass1, [Linker flags for the OSE module (pass 1) (only used when cross compiling for OSE)])
+AC_ARG_VAR(erl_xcomp_ose_ldflags_pass2, [Linker flags for the OSE module (pass 2) (only used when cross compiling for OSE)])
+AC_ARG_VAR(erl_xcomp_ose_OSEROOT, [OSE installation root directory (only used when cross compiling for OSE)])
+AC_ARG_VAR(erl_xcomp_ose_STRIP, [Strip utility shipped with the OSE distribution(only used when cross compiling for OSE)])
+AC_ARG_VAR(erl_xcomp_ose_LM_POST_LINK, [OSE postlink tool (only used when cross compiling for OSE)])
+AC_ARG_VAR(erl_xcomp_ose_LM_SET_CONF, [Sets the configuration for an OSE load module (only used when cross compiling for OSE)])
+AC_ARG_VAR(erl_xcomp_ose_LM_ELF_SIZE, [Prints the section size information for an OSE load module (only used when cross compiling for OSE)])
+AC_ARG_VAR(erl_xcomp_ose_LM_LCF, [OSE load module linker configuration file (only used when cross compiling for OSE)])
+AC_ARG_VAR(erl_xcomp_ose_LM_CONF, [OSE load module default configuration file (only used when cross compiling for OSE)])
+
])
AC_DEFUN(ERL_XCOMP_SYSROOT_INIT,
@@ -488,6 +499,8 @@ AC_CACHE_VAL(ac_cv_sys_ipv6_support,
#ifdef __WIN32__
#include
#include
+#elif __OSE__
+#error "no ipv6"
#else
#include
#endif],
@@ -500,6 +513,8 @@ else
#ifdef __WIN32__
#include
#include
+#elif __OSE__
+#error "no ipv6"
#else
#include
#endif],
@@ -728,6 +743,12 @@ if test "X$host_os" = "Xwin32"; then
THR_LIBS=
THR_LIB_NAME=win32_threads
THR_LIB_TYPE=win32_threads
+elif test "X$host_os" = "Xose"; then
+ AC_MSG_RESULT(yes)
+ THR_DEFS="-DOSE_THREADS"
+ THR_LIBS=
+ THR_LIB_NAME=ose_threads
+ THR_LIB_TYPE=ose_threads
else
AC_MSG_RESULT(no)
THR_DEFS=
@@ -1078,9 +1099,17 @@ case "$THR_LIB_NAME" in
test "$ethr_have_native_atomics" = "yes" && ethr_have_native_spinlock=yes
;;
- pthread)
- ETHR_THR_LIB_BASE_DIR=pthread
- AC_DEFINE(ETHR_PTHREADS, 1, [Define if you have pthreads])
+ pthread|ose_threads)
+ case "$THR_LIB_NAME" in
+ pthread)
+ ETHR_THR_LIB_BASE_DIR=pthread
+ AC_DEFINE(ETHR_PTHREADS, 1, [Define if you have pthreads])
+ ;;
+ ose_threads)
+ AC_DEFINE(ETHR_OSE_THREADS, 1, [Define if you have OSE style threads]) ETHR_THR_LIB_BASE_DIR=ose
+ ;;
+ esac
+ if test "x$THR_LIB_NAME" == "xpthread"; then
case $host_os in
openbsd*)
# The default stack size is insufficient for our needs
@@ -1139,6 +1168,7 @@ case "$THR_LIB_NAME" in
*) ;;
esac
+ fi
dnl We sometimes need ETHR_DEFS in order to find certain headers
dnl (at least for pthread.h on osf1).
saved_cppflags="$CPPFLAGS"
@@ -1151,7 +1181,6 @@ case "$THR_LIB_NAME" in
dnl
dnl Check for headers
dnl
-
AC_CHECK_HEADER(pthread.h, \
AC_DEFINE(ETHR_HAVE_PTHREAD_H, 1, \
[Define if you have the header file.]))
@@ -1184,7 +1213,7 @@ case "$THR_LIB_NAME" in
dnl
dnl Check for functions
dnl
-
+ if test "x$THR_LIB_NAME" == "xpthread"; then
AC_CHECK_FUNC(pthread_spin_lock, \
[ethr_have_native_spinlock=yes \
AC_DEFINE(ETHR_HAVE_PTHREAD_SPIN_LOCK, 1, \
@@ -1311,6 +1340,8 @@ case "$THR_LIB_NAME" in
AC_MSG_RESULT([$linux_futex])
test $linux_futex = yes && AC_DEFINE(ETHR_HAVE_LINUX_FUTEX, 1, [Define if you have a linux futex implementation.])
+ fi
+
AC_CHECK_SIZEOF(int)
AC_CHECK_SIZEOF(long)
AC_CHECK_SIZEOF(long long)
diff --git a/lib/runtime_tools/c_src/Makefile.in b/lib/runtime_tools/c_src/Makefile.in
index 2bcb93b4dd..d46b4997f7 100644
--- a/lib/runtime_tools/c_src/Makefile.in
+++ b/lib/runtime_tools/c_src/Makefile.in
@@ -101,7 +101,12 @@ endif
_create_dirs := $(shell mkdir -p $(OBJDIR) $(LIBDIR))
+ifneq ($(findstring ose,$(TARGET)),ose)
debug opt valgrind: $(SOLIBS) $(OBJDIR) $(LIBDIR) $(NIF_LIB)
+else
+# We do not build this on OSE
+debug opt valgrind:
+endif
DYNTRACE_OBJS = $(before_DTrace_OBJS)
@@ -153,8 +158,10 @@ include $(ERL_TOP)/make/otp_release_targets.mk
release_spec: opt
$(INSTALL_DIR) "$(RELSYSDIR)/priv/obj"
$(INSTALL_DIR) "$(RELSYSDIR)/priv/lib"
+ifneq ($(findstring ose,$(TARGET)),ose)
$(INSTALL_PROGRAM) $(DYNTRACE_OBJS) "$(RELSYSDIR)/priv/obj"
$(INSTALL_PROGRAM) $(NIF_LIB) $(SOLIBS) "$(RELSYSDIR)/priv/lib"
+endif
release_docs_spec:
diff --git a/lib/stdlib/src/filename.erl b/lib/stdlib/src/filename.erl
index 66e54ef221..e6bde5673c 100644
--- a/lib/stdlib/src/filename.erl
+++ b/lib/stdlib/src/filename.erl
@@ -516,8 +516,10 @@ pathtype(Atom) when is_atom(Atom) ->
pathtype(atom_to_list(Atom));
pathtype(Name) when is_list(Name) or is_binary(Name) ->
case os:type() of
- {unix, _} -> unix_pathtype(Name);
- {win32, _} -> win32_pathtype(Name)
+ {win32, _} ->
+ win32_pathtype(Name);
+ {_, _} ->
+ unix_pathtype(Name)
end.
unix_pathtype(<<$/,_/binary>>) ->
diff --git a/lib/tools/c_src/Makefile.in b/lib/tools/c_src/Makefile.in
index aea5686ae9..b1eb69f9dc 100644
--- a/lib/tools/c_src/Makefile.in
+++ b/lib/tools/c_src/Makefile.in
@@ -96,8 +96,11 @@ DRIVERS=
ifneq ($(strip $(ETHR_LIB_NAME)),)
# Need ethread package for emem
+ifneq ($(findstring ose,$(TARGET)),ose)
+# Do not build on OSE
PROGS += $(BIN_DIR)/emem$(TYPEMARKER)@EXEEXT@
endif
+endif
EMEM_OBJ_DIR=$(OBJ_DIR)/emem
CREATE_DIRS += $(EMEM_OBJ_DIR)
@@ -148,7 +151,12 @@ ERTS_LIB = $(ERL_TOP/erts/lib_src/obj/$(TARGET)/$(TYPE)/MADE
_create_dirs := $(shell mkdir -p $(CREATE_DIRS))
+ifneq ($(findstring ose,$(TARGET)),ose)
all: $(PROGS) $(DRIVERS)
+else
+# Do not build dynamic files on OSE
+all:
+endif
$(ERTS_LIB):
$(make_verbose)cd $(ERL_TOP)/erts/lib_src && $(MAKE) $(TYPE)
diff --git a/lib/wx/aclocal.m4 b/lib/wx/aclocal.m4
index 46b30a16b3..4a3407e0eb 100644
--- a/lib/wx/aclocal.m4
+++ b/lib/wx/aclocal.m4
@@ -74,6 +74,17 @@ AC_ARG_VAR(erl_xcomp_clock_gettime_cpu_time, [clock_gettime() can be used for re
AC_ARG_VAR(erl_xcomp_after_morecore_hook, [__after_morecore_hook can track malloc()s core memory usage: yes|no (only used when cross compiling)])
AC_ARG_VAR(erl_xcomp_dlsym_brk_wrappers, [dlsym(RTLD_NEXT, _) brk wrappers can track malloc()s core memory usage: yes|no (only used when cross compiling)])
+dnl Cross compilation variables for OSE
+AC_ARG_VAR(erl_xcomp_ose_ldflags_pass1, [Linker flags for the OSE module (pass 1) (only used when cross compiling for OSE)])
+AC_ARG_VAR(erl_xcomp_ose_ldflags_pass2, [Linker flags for the OSE module (pass 2) (only used when cross compiling for OSE)])
+AC_ARG_VAR(erl_xcomp_ose_OSEROOT, [OSE installation root directory (only used when cross compiling for OSE)])
+AC_ARG_VAR(erl_xcomp_ose_STRIP, [Strip utility shipped with the OSE distribution(only used when cross compiling for OSE)])
+AC_ARG_VAR(erl_xcomp_ose_LM_POST_LINK, [OSE postlink tool (only used when cross compiling for OSE)])
+AC_ARG_VAR(erl_xcomp_ose_LM_SET_CONF, [Sets the configuration for an OSE load module (only used when cross compiling for OSE)])
+AC_ARG_VAR(erl_xcomp_ose_LM_ELF_SIZE, [Prints the section size information for an OSE load module (only used when cross compiling for OSE)])
+AC_ARG_VAR(erl_xcomp_ose_LM_LCF, [OSE load module linker configuration file (only used when cross compiling for OSE)])
+AC_ARG_VAR(erl_xcomp_ose_LM_CONF, [OSE load module default configuration file (only used when cross compiling for OSE)])
+
])
AC_DEFUN(ERL_XCOMP_SYSROOT_INIT,
@@ -488,6 +499,8 @@ AC_CACHE_VAL(ac_cv_sys_ipv6_support,
#ifdef __WIN32__
#include
#include
+#elif __OSE__
+#error "no ipv6"
#else
#include
#endif],
@@ -500,6 +513,8 @@ else
#ifdef __WIN32__
#include
#include
+#elif __OSE__
+#error "no ipv6"
#else
#include
#endif],
@@ -728,6 +743,12 @@ if test "X$host_os" = "Xwin32"; then
THR_LIBS=
THR_LIB_NAME=win32_threads
THR_LIB_TYPE=win32_threads
+elif test "X$host_os" = "Xose"; then
+ AC_MSG_RESULT(yes)
+ THR_DEFS="-DOSE_THREADS"
+ THR_LIBS=
+ THR_LIB_NAME=ose_threads
+ THR_LIB_TYPE=ose_threads
else
AC_MSG_RESULT(no)
THR_DEFS=
@@ -1078,9 +1099,17 @@ case "$THR_LIB_NAME" in
test "$ethr_have_native_atomics" = "yes" && ethr_have_native_spinlock=yes
;;
- pthread)
- ETHR_THR_LIB_BASE_DIR=pthread
- AC_DEFINE(ETHR_PTHREADS, 1, [Define if you have pthreads])
+ pthread|ose_threads)
+ case "$THR_LIB_NAME" in
+ pthread)
+ ETHR_THR_LIB_BASE_DIR=pthread
+ AC_DEFINE(ETHR_PTHREADS, 1, [Define if you have pthreads])
+ ;;
+ ose_threads)
+ AC_DEFINE(ETHR_OSE_THREADS, 1, [Define if you have OSE style threads]) ETHR_THR_LIB_BASE_DIR=ose
+ ;;
+ esac
+ if test "x$THR_LIB_NAME" == "xpthread"; then
case $host_os in
openbsd*)
# The default stack size is insufficient for our needs
@@ -1139,6 +1168,7 @@ case "$THR_LIB_NAME" in
*) ;;
esac
+ fi
dnl We sometimes need ETHR_DEFS in order to find certain headers
dnl (at least for pthread.h on osf1).
saved_cppflags="$CPPFLAGS"
@@ -1151,7 +1181,6 @@ case "$THR_LIB_NAME" in
dnl
dnl Check for headers
dnl
-
AC_CHECK_HEADER(pthread.h, \
AC_DEFINE(ETHR_HAVE_PTHREAD_H, 1, \
[Define if you have the header file.]))
@@ -1184,7 +1213,7 @@ case "$THR_LIB_NAME" in
dnl
dnl Check for functions
dnl
-
+ if test "x$THR_LIB_NAME" == "xpthread"; then
AC_CHECK_FUNC(pthread_spin_lock, \
[ethr_have_native_spinlock=yes \
AC_DEFINE(ETHR_HAVE_PTHREAD_SPIN_LOCK, 1, \
@@ -1311,6 +1340,8 @@ case "$THR_LIB_NAME" in
AC_MSG_RESULT([$linux_futex])
test $linux_futex = yes && AC_DEFINE(ETHR_HAVE_LINUX_FUTEX, 1, [Define if you have a linux futex implementation.])
+ fi
+
AC_CHECK_SIZEOF(int)
AC_CHECK_SIZEOF(long)
AC_CHECK_SIZEOF(long long)
--
cgit v1.2.3
From 06928bcd1ff6ede831bb36395ab94761c85d780b Mon Sep 17 00:00:00 2001
From: Rasmuss Graaf
Date: Wed, 28 Aug 2013 17:51:59 +0200
Subject: ose: Adapt suite for OSE
---
lib/kernel/test/prim_file_SUITE.erl | 52 ++++++++++++++++++-------------------
1 file changed, 26 insertions(+), 26 deletions(-)
(limited to 'lib')
diff --git a/lib/kernel/test/prim_file_SUITE.erl b/lib/kernel/test/prim_file_SUITE.erl
index 199e597e78..ccf325a493 100644
--- a/lib/kernel/test/prim_file_SUITE.erl
+++ b/lib/kernel/test/prim_file_SUITE.erl
@@ -78,7 +78,7 @@
_ -> apply(?PRIM_FILE, F, [H | A])
end).
-suite() -> [{ct_hooks,[ts_install_cth]}].
+suite() -> [].
all() ->
[read_write_file, {group, dirs}, {group, files},
@@ -407,11 +407,11 @@ cur_dir_1(Config, Handle) ->
?line Dog = test_server:timetrap(test_server:seconds(5)),
?line case os:type() of
- {unix, _} ->
- ?line {error, enotsup} =
- ?PRIM_FILE_call(get_cwd, Handle, ["d:"]);
{win32, _} ->
- win_cur_dir_1(Config, Handle)
+ win_cur_dir_1(Config, Handle);
+ _ ->
+ ?line {error, enotsup} =
+ ?PRIM_FILE_call(get_cwd, Handle, ["d:"])
end,
?line test_server:timetrap_cancel(Dog),
ok.
@@ -843,7 +843,7 @@ file_info_basic_directory(Config, Handle) ->
?line test_directory("/", read_write, Handle),
?line test_directory("c:/", read_write, Handle),
?line test_directory("c:\\", read_write, Handle);
- {unix, _} ->
+ _ ->
?line test_directory("/", read, Handle)
end,
?line test_server:timetrap_cancel(Dog).
@@ -1568,15 +1568,15 @@ e_delete(Config) when is_list(Config) ->
%% No permission.
?line case os:type() of
- {unix, _} ->
+ {win32, _} ->
+ %% Remove a character device.
+ ?line {error, eacces} = ?PRIM_FILE:delete("nul");
+ _ ->
?line ?PRIM_FILE:write_file_info(
Base, #file_info {mode=0}),
?line {error, eacces} = ?PRIM_FILE:delete(Afile),
?line ?PRIM_FILE:write_file_info(
- Base, #file_info {mode=8#600});
- {win32, _} ->
- %% Remove a character device.
- ?line {error, eacces} = ?PRIM_FILE:delete("nul")
+ Base, #file_info {mode=8#600})
end,
?line test_server:timetrap_cancel(Dog),
@@ -1656,7 +1656,12 @@ e_rename(Config) when is_list(Config) ->
%% XXX - Gross hack!
?line Comment =
case os:type() of
- {unix, _} ->
+ {win32, _} ->
+ %% At least Windows NT can
+ %% successfully move a file to
+ %% another drive.
+ ok;
+ _ ->
OtherFs = "/tmp",
?line NameOnOtherFs =
filename:join(OtherFs,
@@ -1680,12 +1685,7 @@ e_rename(Config) when is_list(Config) ->
Else ->
Else
end,
- Com;
- {win32, _} ->
- %% At least Windows NT can
- %% successfully move a file to
- %% another drive.
- ok
+ Com
end,
?line test_server:timetrap_cancel(Dog),
Comment.
@@ -1714,14 +1714,14 @@ e_make_dir(Config) when is_list(Config) ->
%% No permission (on Unix only).
case os:type() of
- {unix, _} ->
+ {win32, _} ->
+ ok;
+ _ ->
?line ?PRIM_FILE:write_file_info(Base, #file_info {mode=0}),
?line {error, eacces} =
?PRIM_FILE:make_dir(filename:join(Base, "xxxx")),
?line
- ?PRIM_FILE:write_file_info(Base, #file_info {mode=8#600});
- {win32, _} ->
- ok
+ ?PRIM_FILE:write_file_info(Base, #file_info {mode=8#600})
end,
?line test_server:timetrap_cancel(Dog),
ok.
@@ -1767,15 +1767,15 @@ e_del_dir(Config) when is_list(Config) ->
%% No permission.
case os:type() of
- {unix, _} ->
+ {win32, _} ->
+ ok;
+ _ ->
?line ADirectory = filename:join(Base, "no_perm"),
?line ok = ?PRIM_FILE:make_dir(ADirectory),
?line ?PRIM_FILE:write_file_info(Base, #file_info {mode=0}),
?line {error, eacces} = ?PRIM_FILE:del_dir(ADirectory),
?line ?PRIM_FILE:write_file_info(
- Base, #file_info {mode=8#600});
- {win32, _} ->
- ok
+ Base, #file_info {mode=8#600})
end,
?line test_server:timetrap_cancel(Dog),
ok.
--
cgit v1.2.3
From f8cfcf356cf2f8c573713fc89883bb99003f242c Mon Sep 17 00:00:00 2001
From: Lukas Larsson
Date: Wed, 9 Oct 2013 11:55:26 +0200
Subject: ose: Fix stdlib testcases
---
lib/stdlib/test/filename_SUITE.erl | 53 ++++++++++++++++++++++++--------------
1 file changed, 34 insertions(+), 19 deletions(-)
(limited to 'lib')
diff --git a/lib/stdlib/test/filename_SUITE.erl b/lib/stdlib/test/filename_SUITE.erl
index 232df6a13f..ecd9cff9f9 100644
--- a/lib/stdlib/test/filename_SUITE.erl
+++ b/lib/stdlib/test/filename_SUITE.erl
@@ -96,11 +96,19 @@ absname(Config) when is_list(Config) ->
?line file:set_cwd(Cwd),
ok;
- {unix, _} ->
- ?line ok = file:set_cwd("/usr"),
- ?line "/usr/foo" = filename:absname(foo),
- ?line "/usr/foo" = filename:absname("foo"),
- ?line "/usr/../ebin" = filename:absname("../ebin"),
+ Type ->
+ case Type of
+ {unix, _} ->
+ ?line ok = file:set_cwd("/usr"),
+ ?line "/usr/foo" = filename:absname(foo),
+ ?line "/usr/foo" = filename:absname("foo"),
+ ?line "/usr/../ebin" = filename:absname("../ebin");
+ {ose, _} ->
+ ?line ok = file:set_cwd("/romfs"),
+ ?line "/romfs/foo" = filename:absname(foo),
+ ?line "/romfs/foo" = filename:absname("foo"),
+ ?line "/romfs/../ebin" = filename:absname("../ebin")
+ end,
?line file:set_cwd("/"),
?line "/foo" = filename:absname(foo),
@@ -155,7 +163,7 @@ absname_2(Config) when is_list(Config) ->
?line "a:/erlang" = filename:absname("a:erlang", [Drive|":/"]),
ok;
- {unix, _} ->
+ _ ->
?line "/usr/foo" = filename:absname(foo, "/usr"),
?line "/usr/foo" = filename:absname("foo", "/usr"),
?line "/usr/../ebin" = filename:absname("../ebin", "/usr"),
@@ -189,7 +197,7 @@ basename_1(Config) when is_list(Config) ->
?line "foo" = filename:basename(["usr\\foo\\"]),
?line "foo" = filename:basename("A:\\usr\\foo"),
?line "foo" = filename:basename("A:foo");
- {unix, _} ->
+ _ ->
?line "strange\\but\\true" =
filename:basename("strange\\but\\true")
end,
@@ -219,7 +227,7 @@ basename_2(Config) when is_list(Config) ->
?line "foo.erl" = filename:basename("c:\\usr.hrl\\foo.erl",
".hrl"),
?line "foo" = filename:basename("A:\\usr\\foo", ".hrl");
- {unix, _} ->
+ _ ->
?line "strange\\but\\true" =
filename:basename("strange\\but\\true.erl", ".erl"),
?line "strange\\but\\true" =
@@ -317,7 +325,7 @@ join(Config) when is_list(Config) ->
filename:join(["A:","C:usr","foo.erl"]),
?line "d:/foo" = filename:join([$D, $:, $/, []], "foo"),
ok;
- {unix, _} ->
+ _ ->
ok
end.
@@ -332,7 +340,7 @@ pathtype(Config) when is_list(Config) ->
?line volumerelative = filename:pathtype("/usr/local/bin"),
?line volumerelative = filename:pathtype("A:usr/local/bin"),
ok;
- {unix, _} ->
+ _ ->
?line absolute = filename:pathtype("/"),
?line absolute = filename:pathtype("/usr/local/bin"),
ok
@@ -450,10 +458,17 @@ absname_bin(Config) when is_list(Config) ->
?line file:set_cwd(Cwd),
ok;
- {unix, _} ->
- ?line ok = file:set_cwd(<<"/usr">>),
- ?line <<"/usr/foo">> = filename:absname(<<"foo">>),
- ?line <<"/usr/../ebin">> = filename:absname(<<"../ebin">>),
+ Type ->
+ case Type of
+ {unix,_} ->
+ ?line ok = file:set_cwd(<<"/usr">>),
+ ?line <<"/usr/foo">> = filename:absname(<<"foo">>),
+ ?line <<"/usr/../ebin">> = filename:absname(<<"../ebin">>);
+ {ose,_} ->
+ ?line ok = file:set_cwd(<<"/romfs">>),
+ ?line <<"/romfs/foo">> = filename:absname(<<"foo">>),
+ ?line <<"/romfs/../ebin">> = filename:absname(<<"../ebin">>)
+ end,
?line file:set_cwd(<<"/">>),
?line <<"/foo">> = filename:absname(<<"foo">>),
@@ -503,7 +518,7 @@ absname_bin_2(Config) when is_list(Config) ->
?line <<"a:/erlang">> = filename:absname(<<"a:erlang">>, <>),
ok;
- {unix, _} ->
+ _ ->
?line <<"/usr/foo">> = filename:absname(<<"foo">>, <<"/usr">>),
?line <<"/usr/../ebin">> = filename:absname(<<"../ebin">>, <<"/usr">>),
@@ -527,7 +542,7 @@ basename_bin_1(Config) when is_list(Config) ->
{win32, _} ->
?line <<"foo">> = filename:basename(<<"A:\\usr\\foo">>),
?line <<"foo">> = filename:basename(<<"A:foo">>);
- {unix, _} ->
+ _ ->
?line <<"strange\\but\\true">> =
filename:basename(<<"strange\\but\\true">>)
end,
@@ -551,7 +566,7 @@ basename_bin_2(Config) when is_list(Config) ->
?line <<"foo.erl">> = filename:basename(<<"c:\\usr.hrl\\foo.erl">>,
<<".hrl">>),
?line <<"foo">> = filename:basename(<<"A:\\usr\\foo">>, <<".hrl">>);
- {unix, _} ->
+ _ ->
?line <<"strange\\but\\true">> =
filename:basename(<<"strange\\but\\true.erl">>, <<".erl">>),
?line <<"strange\\but\\true">> =
@@ -639,7 +654,7 @@ join_bin(Config) when is_list(Config) ->
filename:join([<<"A:">>,<<"C:usr">>,<<"foo.erl">>]),
?line <<"d:/foo">> = filename:join([$D, $:, $/, []], <<"foo">>),
ok;
- {unix, _} ->
+ _ ->
ok
end.
@@ -653,7 +668,7 @@ pathtype_bin(Config) when is_list(Config) ->
volumerelative = filename:pathtype(<<"/usr/local/bin">>),
volumerelative = filename:pathtype(<<"A:usr/local/bin">>),
ok;
- {unix, _} ->
+ _ ->
absolute = filename:pathtype(<<"/">>),
absolute = filename:pathtype(<<"/usr/local/bin">>),
ok
--
cgit v1.2.3
From fa3dd14716b2a7ad0c223ebacd2ffc6ecf6437e6 Mon Sep 17 00:00:00 2001
From: Lukas Larsson
Date: Mon, 30 Sep 2013 15:07:49 +0200
Subject: ose: Add module that allows interaction with any OSE process
The interface of this module is made to be as generic as possible
in order for other IPC mechanisms to mimic it and allow porting of
code between different os:es.
---
lib/kernel/doc/src/Makefile | 27 +-
lib/kernel/doc/src/ref_man.xml | 68 ----
lib/kernel/doc/src/ref_man.xml.src | 67 ++++
lib/kernel/src/Makefile | 4 +
lib/kernel/src/ose.erl | 452 ++++++++++++++++++++++
lib/kernel/test/Makefile | 4 +
lib/kernel/test/ose_SUITE.erl | 765 +++++++++++++++++++++++++++++++++++++
7 files changed, 1316 insertions(+), 71 deletions(-)
delete mode 100644 lib/kernel/doc/src/ref_man.xml
create mode 100644 lib/kernel/doc/src/ref_man.xml.src
create mode 100644 lib/kernel/src/ose.erl
create mode 100644 lib/kernel/test/ose_SUITE.erl
(limited to 'lib')
diff --git a/lib/kernel/doc/src/Makefile b/lib/kernel/doc/src/Makefile
index de3ca1e176..7f8023aba4 100644
--- a/lib/kernel/doc/src/Makefile
+++ b/lib/kernel/doc/src/Makefile
@@ -31,6 +31,12 @@ APPLICATION=kernel
# ----------------------------------------------------
RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN)
+# ----------------------------------------------------
+# Help application directory specification
+# ----------------------------------------------------
+EDOC_DIR = $(ERL_TOP)/lib/edoc
+SYNTAX_TOOLS_DIR = $(ERL_TOP)/lib/syntax_tools
+
# ----------------------------------------------------
# Target Specs
# ----------------------------------------------------
@@ -65,6 +71,12 @@ XML_REF3_FILES = application.xml \
user.xml \
zlib_stub.xml
+ifeq ($(findstring ose,$(TARGET)),ose)
+XML_EDOC_FILES = ose.xml
+else
+XML_EDOC_FILES =
+endif
+
XML_REF4_FILES = app.xml config.xml
XML_REF6_FILES = kernel_app.xml
@@ -76,8 +88,8 @@ BOOK_FILES = book.xml
XML_FILES = \
$(BOOK_FILES) $(XML_CHAPTER_FILES) \
- $(XML_PART_FILES) $(XML_REF3_FILES) $(XML_REF4_FILES) \
- $(XML_REF6_FILES) $(XML_APPLICATION_FILES)
+ $(XML_PART_FILES) $(XML_REF3_FILES) $(XML_EDOC_FILES)\
+ $(XML_REF4_FILES) $(XML_REF6_FILES) $(XML_APPLICATION_FILES)
# ----------------------------------------------------
@@ -103,7 +115,7 @@ TOP_SPECS_FILE = specs.xml
# ----------------------------------------------------
XML_FLAGS +=
-SPECS_ESRC = ../../src
+SRC_DIR = ../../src
SPECS_FLAGS = -I../../include
@@ -148,6 +160,15 @@ $(SPECDIR)/specs_zlib_stub.xml:
escript $(SPECS_EXTRACTOR) $(SPECS_FLAGS) \
-o$(dir $@) -module zlib_stub
+ose.xml: $(SRC_DIR)/ose.erl
+ escript $(DOCGEN)/priv/bin/xml_from_edoc.escript $(SRC_DIR)/$(@:%.xml=%.erl)
+ref_man.xml: ref_man.xml.src
+ifeq ($(findstring ose,$(TARGET)),ose)
+ sed -e 's:\(os.xml"/>\):\1\n:' $< > $@
+else
+ cp $< $@
+endif
+
# ----------------------------------------------------
# Release Target
# ----------------------------------------------------
diff --git a/lib/kernel/doc/src/ref_man.xml b/lib/kernel/doc/src/ref_man.xml
deleted file mode 100644
index c1b9eac9d7..0000000000
--- a/lib/kernel/doc/src/ref_man.xml
+++ /dev/null
@@ -1,68 +0,0 @@
-
-
-
-
-
-
- 19962013
- Ericsson AB. All Rights Reserved.
-
-
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
-
-
-
- Kernel Reference Manual
-
-
-
-
-
-
- The Kernel application has all the code necessary to run
- the Erlang runtime system itself: file servers and code servers
- and so on.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/lib/kernel/doc/src/ref_man.xml.src b/lib/kernel/doc/src/ref_man.xml.src
new file mode 100644
index 0000000000..bd25d1e78d
--- /dev/null
+++ b/lib/kernel/doc/src/ref_man.xml.src
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+ 19962013
+ Ericsson AB. All Rights Reserved.
+
+
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+
+
+ Kernel Reference Manual
+
+
+
+
+
+
+ The Kernel application has all the code necessary to run
+ the Erlang runtime system itself: file servers and code servers
+ and so on.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/kernel/src/Makefile b/lib/kernel/src/Makefile
index cb3c0a49f4..5379006784 100644
--- a/lib/kernel/src/Makefile
+++ b/lib/kernel/src/Makefile
@@ -117,6 +117,10 @@ MODULES = \
user_sup \
wrap_log_reader
+ifeq ($(findstring ose,$(TARGET)),ose)
+MODULES+=ose
+endif
+
HRL_FILES= ../include/file.hrl ../include/inet.hrl ../include/inet_sctp.hrl \
../include/dist.hrl ../include/dist_util.hrl \
../include/net_address.hrl
diff --git a/lib/kernel/src/ose.erl b/lib/kernel/src/ose.erl
new file mode 100644
index 0000000000..ff7147233f
--- /dev/null
+++ b/lib/kernel/src/ose.erl
@@ -0,0 +1,452 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2013. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%% @doc Interface module for OSE messaging and process monitoring from Erlang
+%%
+%% For each mailbox created through {@link open/1} a OSE phantom process with
+%% that name is started. Since phantom processes are used the memory footprint
+%% of each mailbox is quite small.
+%%
+%% To receive messages you first have to subscribe to the specific message
+%% numbers that you are interested in with {@link listen/2}. The messages
+%% will be sent to the Erlang process that created the mailbox.
+%%
+%% @end
+%%
+-module(ose).
+
+%%==============================================================================
+%% Exported API
+%%==============================================================================
+-export([open/1,
+ close/1,
+ get_id/1,
+ get_name/2,
+ hunt/2,
+ dehunt/2,
+ attach/2,
+ detach/2,
+ send/4,
+ send/5,
+ listen/2
+ ]).
+
+%%==============================================================================
+%% Types
+%%==============================================================================
+-opaque mailbox() :: port().
+%% Mailbox handle. Implemented as an erlang port.
+
+-opaque mailbox_id() :: integer().
+%% Mailbox ID, this is the same as the process id of an OSE process.
+%% An integer.
+
+-type message_number() :: 0..4294967295.
+%% OSE Signal number
+
+-opaque hunt_ref() :: {mailbox(),integer()}.
+%% Reference from a hunt request. This term will be included
+%% in a successful hunt response.
+
+-opaque attach_ref() :: {mailbox(),integer()}.
+%% Reference from an attach request. This term will be included
+%% in the term returned when the attached mailbox disappears.
+
+-export_type([mailbox_id/0,
+ message_number/0,
+ mailbox/0,
+ hunt_ref/0,
+ attach_ref/0]).
+
+%%==============================================================================
+%% Defines
+%%==============================================================================
+-define(DRIVER_NAME, "ose_signal_drv").
+-define(GET_SPID, 1).
+-define(GET_NAME, 2).
+-define(HUNT, 100).
+-define(DEHUNT, 101).
+-define(ATTACH, 102).
+-define(DETACH, 103).
+-define(SEND, 104).
+-define(SEND_W_S, 105).
+-define(LISTEN, 106).
+-define(OPEN, 200).
+
+-define(INT_32BIT(Int),(is_integer(Int) andalso (Int >= 0) andalso (Int < (1 bsl 32)))).
+
+%%==============================================================================
+%% API functions
+%%==============================================================================
+
+%%------------------------------------------------------------------------------
+%% @doc Create a mailbox with the given name and return a port that handles
+%% the mailbox.
+%%
+%% An OSE phantom process with the given name will be created that will send any
+%% messages sent through this mailbox. Any messages sent to the new OSE process
+%% will automatically be converted to an Erlang message and sent to the Erlang
+%% process that calls this function. See {@link listen/2} for details about the
+%% format of the message sent.
+%%
+%% The caller gets linked to the created mailbox.
+%%
+%% raises: `badarg' | `system_limit'
+%%
+%% @see liten/2
+%% @end
+%%------------------------------------------------------------------------------
+-spec open(Name) -> Port when
+ Name :: iodata(),
+ Port :: mailbox().
+open(Name) ->
+ try open_port({spawn_driver,?DRIVER_NAME}, [binary]) of
+ Port ->
+ try port_command(Port,[?OPEN,Name]) of
+ true ->
+ receive
+ {ose_drv_reply,Port,{error,Error}} ->
+ close(Port),
+ erlang:error(Error,[Name]);
+ {ose_drv_reply,Port,ok} ->
+ Port
+ end
+ catch
+ error:badarg -> close(Port),erlang:error(badarg,[Name])
+ end
+ catch
+ error:badarg -> erlang:error(badarg,[Name])
+ end.
+
+%%------------------------------------------------------------------------------
+%% @doc Close a mailbox
+%%
+%% This kills the OSE phantom process associated with this mailbox.
+%%
+%% Will also consume any ``{'EXIT',Port,_}'' message from the port that comes
+%% due to the port closing when the calling process traps exits.
+%%
+%% raises: `badarg'
+%% @end
+%%------------------------------------------------------------------------------
+-spec close(Port) -> ok when
+ Port :: mailbox().
+close(Port) when is_port(Port) ->
+ %% Copied from prim_inet
+ case erlang:process_info(self(), trap_exit) of
+ {trap_exit,true} ->
+ link(Port),
+ catch erlang:port_close(Port),
+ receive {'EXIT',Port,_} -> ok end;
+ {trap_exit,false} ->
+ catch erlang:port_close(Port),
+ ok
+ end;
+close(NotPort) ->
+ erlang:error(badarg,[NotPort]).
+
+%%------------------------------------------------------------------------------
+%% @doc Get the mailbox id for the given port.
+%%
+%% The mailbox id is the same as the OSE process id of the OSE phantom process
+%% that this mailbox represents.
+%%
+%% raises: `badarg'
+%% @end
+%%------------------------------------------------------------------------------
+-spec get_id(Port) -> Pid when
+ Port :: mailbox(),
+ Pid :: mailbox_id().
+get_id(Port) ->
+ try port_control(Port, ?GET_SPID, <<>>) of
+ <> -> Spid
+ catch error:_Error ->
+ erlang:error(badarg,[Port])
+ end.
+
+%%------------------------------------------------------------------------------
+%% @doc Get the mailbox name for the given mailbox id.
+%%
+%% The mailbox name is the name of the OSE process with process id Pid.
+%%
+%% This call will fail with badarg if the underlying system does not support
+%% getting the name from a process id.
+%%
+%% raises: `badarg'
+%% @end
+%%------------------------------------------------------------------------------
+-spec get_name(Port, Pid) -> Name | undefined when
+ Port :: mailbox(),
+ Pid :: mailbox_id(),
+ Name :: binary().
+get_name(Port, Pid) when ?INT_32BIT(Pid) ->
+ try port_control(Port, ?GET_NAME, <>) of
+ [] -> undefined;
+ Res -> Res
+ catch error:_Error ->
+ erlang:error(badarg,[Port,Pid])
+ end;
+get_name(Port, Pid) ->
+ erlang:error(badarg,[Port,Pid]).
+
+
+%%------------------------------------------------------------------------------
+%% @doc Hunt for OSE process by name.
+%%
+%% Will send `{mailbox_up, Port, Ref, MboxId}'
+%% to the calling process when the OSE process becomes available.
+%%
+%% Returns a reference term that can be used to cancel the hunt
+%% using {@link dehunt/2}.
+%%
+%% raises: `badarg'
+%%
+%% @end
+%%------------------------------------------------------------------------------
+-spec hunt(Port, HuntPath) -> Ref when
+ Port :: mailbox(),
+ HuntPath :: iodata(),
+ Ref :: hunt_ref().
+hunt(Port, HuntPath) ->
+ try port_command(Port, [?HUNT,HuntPath]) of
+ true ->
+ receive
+ {ose_drv_reply,Port,{error,Error}} ->
+ erlang:error(Error,[Port,HuntPath]);
+ {ose_drv_reply,Port,Ref} ->
+ Ref
+ end
+ catch error:_Error ->
+ erlang:error(badarg,[Port,HuntPath])
+ end.
+
+%%------------------------------------------------------------------------------
+%% @doc Stop hunting for OSE process.
+%%
+%% If a message for this hunt has been sent but not received
+%% by the calling process, it is removed from the message queue.
+%% Note that this only works if the same process that did
+%% the hunt does the dehunt.
+%%
+%% raises: `badarg'
+%%
+%% @see hunt/2
+%% @end
+%%------------------------------------------------------------------------------
+-spec dehunt(Port, Ref) -> ok when
+ Port :: mailbox(),
+ Ref :: hunt_ref().
+dehunt(Port, {Port,Ref}) when ?INT_32BIT(Ref) ->
+ try port_command(Port, <>) of
+ true ->
+ receive
+ {ose_drv_reply,Port,{error,enoent}} ->
+ %% enoent could mean that it is in the message queue
+ receive
+ {mailbox_up, Port, {Port,Ref}, _} ->
+ ok
+ after 0 ->
+ ok
+ end;
+ {ose_drv_reply,Port,ok} ->
+ ok
+ end
+ catch error:_Error ->
+ erlang:error(badarg,[Port,{Port,Ref}])
+ end;
+dehunt(Port,Ref) ->
+ erlang:error(badarg,[Port,Ref]).
+
+%%------------------------------------------------------------------------------
+%% @doc Attach to an OSE process.
+%%
+%% Will send `{mailbox_down, Port, Ref, MboxId}'
+%% to the calling process if the OSE process exits.
+%%
+%% Returns a reference that can be used to cancel the attachment
+%% using {@link detach/2}.
+%%
+%% raises: `badarg' | `enomem'
+%%
+%% @end
+%%------------------------------------------------------------------------------
+-spec attach(Port,Pid) -> Ref when
+ Port :: mailbox(),
+ Pid :: mailbox_id(),
+ Ref :: attach_ref().
+attach(Port, Spid) when ?INT_32BIT(Spid) ->
+ try port_command(Port, <>) of
+ true ->
+ receive
+ {ose_drv_reply,Port,{error,Error}} ->
+ erlang:error(Error,[Port,Spid]);
+ {ose_drv_reply,Port,Ref} ->
+ Ref
+ end
+ catch error:_Error ->
+ erlang:error(badarg,[Port,Spid])
+ end;
+attach(Port,Spid) ->
+ erlang:error(badarg,[Port,Spid]).
+
+
+%%------------------------------------------------------------------------------
+%% @doc Remove attachment to an OSE process.
+%%
+%% If a message for this monitor has been sent but not received
+%% by the calling process, it is removed from the message queue.
+%% Note that this only works of the same process
+%% that did the attach does the detach.
+%%
+%% raises: `badarg'
+%%
+%% @see attach/2
+%% @end
+%%------------------------------------------------------------------------------
+-spec detach(Port,Ref) -> ok when
+ Port :: mailbox(),
+ Ref :: attach_ref().
+detach(Port, {Port,Ref} ) when ?INT_32BIT(Ref) ->
+ try port_command(Port, <>) of
+ true ->
+ receive
+ {ose_drv_reply,Port,{error,enoent}} ->
+ %% enoent could mean that it is in the message queue
+ receive
+ {mailbox_down,Port,{Port,Ref},_} ->
+ ok
+ after 0 ->
+ ok
+ end;
+ {ose_drv_reply,Port,ok} ->
+ ok
+ end
+ catch error:_Error ->
+ erlang:error(badarg,[Port,{Port,Ref}])
+ end;
+detach(Port,Ref) ->
+ erlang:error(badarg,[Port,Ref]).
+
+%%------------------------------------------------------------------------------
+%% @doc Send an OSE message.
+%%
+%% The message is sent from the OSE process' own ID that is: `get_id(Port)'.
+%%
+%% raises: `badarg'
+%%
+%% @see send/5
+%% @end
+%%------------------------------------------------------------------------------
+-spec send(Port,Pid,SigNo,SigData) -> ok when
+ Port :: mailbox(),
+ Pid :: mailbox_id(),
+ SigNo :: message_number(),
+ SigData :: iodata().
+send(Port, Spid, SigNo, SigData) when ?INT_32BIT(Spid), ?INT_32BIT(SigNo) ->
+ try erlang:port_command(Port, [<>, SigData]) of
+ true -> ok
+ catch error:_Error ->
+ erlang:error(badarg,[Port,Spid,SigNo,SigData])
+ end;
+send(Port,Spid,SigNo,SigData) ->
+ erlang:error(badarg,[Port,Spid,SigNo,SigData]).
+
+
+%%------------------------------------------------------------------------------
+%% @doc Send an OSE message with different sender.
+%%
+%% As {@link send/4} but the sender will be `SenderPid'.
+%%
+%% raises: `badarg'
+%%
+%% @see send/4
+%% @end
+%%------------------------------------------------------------------------------
+-spec send(Port,Pid,SenderPid,SigNo,SigData) -> ok when
+ Port :: mailbox(),
+ Pid :: mailbox_id(),
+ SenderPid :: mailbox_id(),
+ SigNo :: message_number(),
+ SigData :: iodata().
+send(Port, Spid, SenderPid, SigNo, SigData)
+ when ?INT_32BIT(Spid), ?INT_32BIT(SenderPid), ?INT_32BIT(SigNo) ->
+ try erlang:port_command(Port, [<>, SigData]) of
+ true -> ok
+ catch error:_Error ->
+ erlang:error(badarg,[Port,Spid,SenderPid,SigNo,SigData])
+ end;
+send(Port,Spid,SenderPid,SigNo,SigData) ->
+ erlang:error(badarg,[Port,Spid,SenderPid,SigNo,SigData]).
+
+%%------------------------------------------------------------------------------
+%% @doc Start listening for specified OSE signal numbers.
+%%
+%% The mailbox will send `{message,Port,{FromMboxId,ToMboxId,MsgNo,MsgData}}'
+%% to the process that created the mailbox when an OSE message with any
+%% of the specified `SigNos' arrives.
+%%
+%% Repeated calls to listen will replace the current set of signal numbers to
+%% listen to. i.e
+%%
+%% ```1>ose:listen(MsgB,[1234,12345]).
+%% ok
+%% 2> ose:listen(MsgB,[1234,123456]).
+%% ok.'''
+%%
+%% The above will first listen for signals with numbers 1234 and 12345, and then
+%% replace that with only listening to 1234 and 123456.
+%%
+%% With the current implementation it is not possible to listen to all signal
+%% numbers.
+%%
+%% raises: `badarg' | `enomem'
+%%
+%% @end
+%%------------------------------------------------------------------------------
+-spec listen(Port, SigNos) -> ok when
+ Port :: mailbox(),
+ SigNos :: list(message_number()).
+listen(Port, SigNos) when is_list(SigNos) ->
+ USSigNos = lists:usort(SigNos),
+ BinSigNos = try
+ << <> ||
+ SigNo <- USSigNos,
+ ?INT_32BIT(SigNo) orelse erlang:error(badarg)
+ >>
+ catch _:_ ->
+ erlang:error(badarg,[Port,SigNos])
+ end,
+ try port_command(Port, [?LISTEN, BinSigNos]) of
+ true ->
+ receive
+ {ose_drv_reply,Port,{error,Error}} ->
+ erlang:error(Error,[Port,SigNos]);
+ {ose_drv_reply,Port,Else} ->
+ Else
+ end
+ catch error:_Error ->
+ erlang:error(badarg,[Port,SigNos])
+ end;
+listen(Port, SigNos) ->
+ erlang:error(badarg,[Port,SigNos]).
+
+
+%%%=============================================================================
+%%% Internal functions
+%%%=============================================================================
diff --git a/lib/kernel/test/Makefile b/lib/kernel/test/Makefile
index f1b8a105ed..ac28d1aae9 100644
--- a/lib/kernel/test/Makefile
+++ b/lib/kernel/test/Makefile
@@ -79,6 +79,10 @@ MODULES= \
loose_node \
sendfile_SUITE
+ifeq ($(findstring ose,$(TARGET)),ose)
+MODULES+=ose_SUITE
+endif
+
APP_FILES = \
appinc.app \
appinc1.app \
diff --git a/lib/kernel/test/ose_SUITE.erl b/lib/kernel/test/ose_SUITE.erl
new file mode 100644
index 0000000000..7e81b19894
--- /dev/null
+++ b/lib/kernel/test/ose_SUITE.erl
@@ -0,0 +1,765 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1998-2013. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+-module(ose_SUITE).
+
+%-compile(export_all).
+
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,init_per_testcase/2,
+ end_per_testcase/2]).
+-export([
+ basic/1,stress/1,multi_msg_numbers/1,multi_mailboxes/1,
+ hunt/1,multi_hunt/1,dehunt/1,multi_dehunt/1,
+ attach/1,multi_attach/1,detach/1,multi_detach/1,
+ open_errors/1,close_errors/1,get_id_errors/1,get_name_errors/1,
+ hunt_errors/1,dehunt_errors/1,attach_errors/1,detach_errors/1,
+ send_errors/1,send_w_s_errors/1,listen_errors/1
+ ]).
+
+-define(INTERFACE,ose).
+
+
+init_per_testcase(_Func, Config) ->
+ Config.
+end_per_testcase(_Func, _Config) ->
+ ok.
+
+suite() -> [{timeout,{30,seconds}}].
+
+all() ->
+ [
+ basic,stress,multi_msg_numbers,multi_mailboxes,
+ hunt,multi_hunt,dehunt,multi_dehunt,
+ attach,multi_attach,detach,multi_detach,
+
+ open_errors,close_errors,get_id_errors,get_name_errors,
+ hunt_errors,dehunt_errors,attach_errors,detach_errors,
+ send_errors,send_w_s_errors,listen_errors
+ ].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ case os:type() of
+ {ose,_} ->
+ Config;
+ _Else ->
+ {skip,"Only run on OSE"}
+ end.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+basic(_Config) ->
+
+ [P1,P2] = multi_open(2,[42]),
+ P1Id = ?INTERFACE:get_id(P1),
+ P2Id = ?INTERFACE:get_id(P2),
+
+ ok = ?INTERFACE:send(P2,P1Id,42,<<"ping">>),
+ receive
+ {message,P1,V1} ->
+ {P2Id,P1Id,42,<<"ping">>} = V1,
+ ?INTERFACE:send(P1,P2Id,42,<<"pong">>);
+ Else1 ->
+ ct:fail({got_wrong_message,Else1})
+ end,
+
+ receive
+ {message,P2,V2} ->
+ {P1Id,P2Id,42,<<"pong">>} = V2;
+ Else2 ->
+ ct:fail({got_wrong_message,Else2})
+ end,
+
+ ?INTERFACE:close(P1),
+ ?INTERFACE:close(P2).
+
+%% Send 1000 messages and see if we can cope and that msg order is preserved
+stress(_Config) ->
+
+ Iterations = 1000,
+
+ [P1,P2] = multi_open(2,[42]),
+ P1Id = ?INTERFACE:get_id(P1),
+ P2Id = ?INTERFACE:get_id(P2),
+
+ spawn(fun() ->
+ n(fun(N) ->
+ Msg = [<<"ping">>|integer_to_list(N)],
+ ?INTERFACE:send(P2,P1Id,42,Msg)
+ end,Iterations)
+ end),
+ timer:sleep(100),
+ n(fun(N) ->
+ receive
+ {message,P1,Value} ->
+ Int = integer_to_binary(N),
+ {P2Id,P1Id,42,<<"ping",Int/binary>>} = Value,
+ ok;
+ Else ->
+ ct:fail({got_wrong_message,Else})
+ end
+ end,Iterations),
+
+ ?INTERFACE:close(P1),
+ ?INTERFACE:close(P2).
+
+%% Listen to 1000 different message numbers and send some random messages
+multi_msg_numbers(_Config) ->
+
+ Iterations = 100,
+
+ [P1,P2] = multi_open(2,lists:seq(2000,3000)),
+ P1Id = ?INTERFACE:get_id(P1),
+
+ n(fun(_) ->
+ Num = random:uniform(1000)+2000,
+ ?INTERFACE:send(P2,P1Id,Num,<<"ping",(integer_to_binary(Num))/binary>>)
+ end,Iterations),
+
+ n(fun(_) ->
+ receive
+ {message,P1,{_,_,Id,<<"ping",Num/binary>>}} when Id > 2000;
+ Id =< 3000 ->
+ Id = binary_to_integer(Num),
+ ok;
+ Else ->
+ ct:fail({got_wrong_message,Else})
+ end
+ end,Iterations),
+
+ ?INTERFACE:close(P1),
+ ?INTERFACE:close(P2).
+
+
+%% Create 100 mailboxes and send messages to them
+multi_mailboxes(_Config) ->
+
+ Mailboxes = 100,
+
+ [P1|MBs] = multi_open(Mailboxes,[42]),
+
+ [?INTERFACE:send(P1,?INTERFACE:get_id(P),42,[<<"ping">>,?INTERFACE:get_name(P,?INTERFACE:get_id(P))]) || P <- MBs],
+
+ [receive
+ {message,P,Value} ->
+ Name = ?INTERFACE:get_name(P,?INTERFACE:get_id(P)),
+ {_,_,42,<<"ping",Name/binary>>} = Value,
+ ok
+ end || P <- MBs],
+
+ [?INTERFACE:close(P) || P <- [P1|MBs]],
+ ok.
+
+hunt(_Config) ->
+ [P1,P2] = multi_open(2,[]),
+
+ Ref = ?INTERFACE:hunt(P1,"p2"),
+ receive
+ {mailbox_up,P1,Ref,Pid} ->
+ Pid = ?INTERFACE:get_id(P2),
+ ?INTERFACE:close(P1),
+ ?INTERFACE:close(P2);
+ Else ->
+ ct:fail({got_wrong_message,Else,Ref})
+ end.
+
+multi_hunt(_Config) ->
+
+ Iterations = 100,
+
+ P = ?INTERFACE:open("p"),
+
+ Refs = [?INTERFACE:hunt(P,"p"++integer_to_list(N))|| N <- lists:seq(1,Iterations)],
+
+ Pids = [begin
+ Prt = ?INTERFACE:open("p"++integer_to_list(N)),
+ Pid = ?INTERFACE:get_id(Prt),
+ ?INTERFACE:close(Prt),
+ Pid
+ end || N <- lists:seq(1,Iterations)],
+
+ [receive
+ {mailbox_up,P,Ref,Pid} ->
+ ok
+ after 10 ->
+ ct:fail({did_not_get,Pid,Ref})
+ end || {Pid,Ref} <- lists:zip(Pids,Refs)],
+ ?INTERFACE:close(P).
+
+
+dehunt(_Config) ->
+ [P1] = multi_open(1,[]),
+ Ref = ?INTERFACE:hunt(P1,"p2"),
+ receive
+ _Else -> ct:fail({got,_Else})
+ after 1000 ->
+ ok
+ end,
+ P2 = ?INTERFACE:open("p2"),
+
+ % Make sure any messages are sent
+ receive after 10 -> ok end,
+
+ ok = ?INTERFACE:dehunt(P1,Ref),
+
+ % Make sure no messages are received
+ receive
+ _Else2 -> ct:fail({got,_Else2})
+ after 1000 ->
+ ?INTERFACE:close(P1),
+ ?INTERFACE:close(P2)
+ end.
+
+%%%
+%%% This testcase basically:
+%%% spawn 10 processes that in parallel
+%%% adds some hunts for different OSE processes
+%%% maybe create hunted OSE process
+%%% dehunt half of the hunts
+%%% create more hunts
+%%% if not created create hunted OSE process
+%%% veryify that all expected hunt messages are received
+%%% verify that all processes exited correctly
+%%%
+%%% This complex test is done to make sure that the internal handling
+%%% of dehunt works as expected.
+%%%
+multi_dehunt(_Config) ->
+ [P1] = multi_open(1,[]),
+
+ Scenario =
+ fun(Iterations) ->
+
+ Hunted = "p"++integer_to_list(Iterations),
+ %% Start a couple of hunts
+ Refs = [?INTERFACE:hunt(P1,Hunted) || _ <- lists:seq(1,Iterations)],
+
+ %% We alternate if the process is opened before or after the dehunt
+ P2O = if Iterations rem 2 == 0 ->
+ ?INTERFACE:open(Hunted);
+ true ->
+ undefined
+ end,
+
+ %% Remove half of them
+ {RemRefs,_} = lists:mapfoldl(fun(Ref,Acc) when Acc rem 2 == 0 ->
+ ok = ?INTERFACE:dehunt(P1,Ref),
+ {[],Acc+1};
+ (Ref,Acc) ->
+ {Ref,Acc+1}
+ end,0,Refs),
+
+ %% Add some new ones
+ NewRefs = [?INTERFACE:hunt(P1,Hunted)
+ || _ <- lists:seq(1,Iterations div 4)]
+ ++ lists:flatten(RemRefs),
+
+ P2 = if P2O == undefined ->
+ ?INTERFACE:open(Hunted);
+ true ->
+ P2O
+ end,
+ P2Id = ?INTERFACE:get_id(P2),
+
+ %% Receive all the expected ones
+ lists:foreach(fun(Ref) ->
+ receive
+ {mailbox_up,P1,Ref,P2Id} ->
+ ok
+ after 1000 ->
+ io:format("Flush: ~p~n",[flush()]),
+ io:format("~p~n",[{Iterations,{did_not_get, Ref}}]),
+ ok = Ref
+ end
+ end,NewRefs),
+
+ %% Check that no other have arrived
+ receive
+ _Else ->
+ io:format("Flush: ~p~n",[flush()]),
+ io:format("~p~n",[{Iterations,{got, _Else}}]),
+ ok = _Else
+ after 100 ->
+ ok
+ end,
+ ?INTERFACE:close(P2)
+ end,
+
+ Self = self(),
+
+ n(fun(N) ->
+ spawn(fun() -> Self !
+ Scenario(N*25)
+ end),
+ ok
+ end,10),
+
+ n(fun(_N) ->
+ receive ok -> ok
+ after 60000 -> ct:fail(failed)
+ end
+ end,10),
+ ?INTERFACE:close(P1).
+
+attach(_Config) ->
+ [P1,P2] = multi_open(2,[]),
+
+ P2Id = ?INTERFACE:get_id(P2),
+ Ref = ?INTERFACE:attach(P1,P2Id),
+ ?INTERFACE:close(P2),
+ receive
+ {mailbox_down,P1,Ref,P2Id} ->
+ ?INTERFACE:close(P1);
+ _Else ->
+ ct:fail({got,_Else, {P1,Ref,P2Id}})
+ after 1000 ->
+ ct:fail({did_not_get,P1,Ref,P2Id})
+ end.
+
+multi_attach(_Config) ->
+
+ Iterations = 100,
+
+ [P1|Pids] = multi_open(Iterations,[]),
+
+ Refs = [{?INTERFACE:get_id(Pid),?INTERFACE:attach(P1,?INTERFACE:get_id(Pid))} || Pid <- Pids],
+
+ [?INTERFACE:close(Pid) || Pid <- Pids],
+
+ [receive
+ {mailbox_down,P1,Ref,Pid} ->
+ ok
+ after 10000 ->
+ ct:fail({did_not_get,Pid,Ref})
+ end || {Pid,Ref} <- Refs],
+ ?INTERFACE:close(P1).
+
+detach(_Config) ->
+ [P1,P2] = multi_open(2,[]),
+ P2Id = ?INTERFACE:get_id(P2),
+ Ref = ?INTERFACE:attach(P1,P2Id),
+ receive
+ _Else -> ct:fail({got,_Else})
+ after 100 ->
+ ok
+ end,
+
+ ?INTERFACE:close(P2),
+
+ % Make sure any messages are sent
+ receive after 10 -> ok end,
+
+ ?INTERFACE:detach(P1,Ref),
+
+ % Make sure no messages are received
+ receive
+ _Else2 -> ct:fail({got,_Else2})
+ after 1000 ->
+ ?INTERFACE:close(P1)
+ end.
+
+%%%
+%%% This testcase basically:
+%%% spawn 10 processes that in parallel
+%%% adds some attach for different OSE processes
+%%% maybe close OSE process
+%%% dehunt half of the hunts
+%%% create more hunts
+%%% if not closed close attached OSE process
+%%% veryify that all expected attach messages are received
+%%% verify that all processes exited correctly
+%%%
+%%% This complex test is done to make sure that the internal handling
+%%% of dehunt works as expected.
+%%%
+multi_detach(_Config) ->
+ [P1] = multi_open(1,[]),
+
+ Scenario =
+ fun(Iterations) ->
+
+ Attached = ?INTERFACE:open("p"++integer_to_list(Iterations)),
+ AttachedId = ?INTERFACE:get_id(Attached),
+ %% Start a couple of attachs
+ Refs = [?INTERFACE:attach(P1,AttachedId) || _ <- lists:seq(1,Iterations)],
+
+ %% We alternate if the process is closed before or after the detach
+ P2O = if Iterations rem 2 == 0 ->
+ ?INTERFACE:close(Attached);
+ true ->
+ undefined
+ end,
+
+ %% Remove half of them
+ {RemRefs,_} = lists:mapfoldl(fun(Ref,Acc) when Acc rem 2 == 0 ->
+ ok = ?INTERFACE:detach(P1,Ref),
+ {[],Acc+1};
+ (Ref,Acc) ->
+ {Ref,Acc+1}
+ end,0,Refs),
+
+ %% Add some new ones
+ NewRefs = [?INTERFACE:attach(P1,AttachedId)
+ || _ <- lists:seq(1,Iterations div 4)]
+ ++ lists:flatten(RemRefs),
+
+ if P2O == undefined ->
+ ?INTERFACE:close(Attached);
+ true ->
+ P2O
+ end,
+
+ %% Receive all the expected ones
+ lists:foreach(fun(Ref) ->
+ receive
+ {mailbox_down,P1,Ref,AttachedId} ->
+ ok
+ after 1000 ->
+ io:format("Flush: ~p~n",[flush()]),
+ io:format("~p~n",[{Iterations,{did_not_get, Ref}}]),
+ ok = Ref
+ end
+ end,NewRefs),
+
+ %% Check that no other have arrived
+ receive
+ _Else ->
+ io:format("Flush: ~p~n",[flush()]),
+ io:format("~p~n",[{Iterations,{got, _Else}}]),
+ ok = _Else
+ after 100 ->
+ ok
+ end
+ end,
+
+ Self = self(),
+
+ n(fun(N) ->
+ spawn(fun() -> Self !
+ Scenario(N*5)
+ end),
+ ok
+ end,10),
+
+ n(fun(_N) ->
+ receive ok -> ok
+ after 60000 -> ct:fail(failed)
+ end
+ end,10),
+ ?INTERFACE:close(P1).
+
+
+open_errors(_Config) ->
+ {'EXIT',{badarg,[{?INTERFACE,open,[inval],_}|_]}} =
+ (catch ?INTERFACE:open(inval)),
+ {'EXIT',{badarg,[{?INTERFACE,open,[["p"|1]],_}|_]}} =
+ (catch ?INTERFACE:open(["p"|1])),
+ {'EXIT',{badarg,[{?INTERFACE,open,[["p",1234]],_}|_]}} =
+ (catch ?INTERFACE:open(["p",1234])),
+
+ ok.
+
+close_errors(_Config) ->
+ {'EXIT',{badarg,[{?INTERFACE,close,[inval],_}|_]}} =
+ (catch ?INTERFACE:close(inval)),
+
+ P1 = ?INTERFACE:open("p1"),
+ ok = ?INTERFACE:close(P1),
+ ok = ?INTERFACE:close(P1).
+
+
+get_id_errors(_Config) ->
+ {'EXIT',{badarg,[{?INTERFACE,get_id,[inval],_}|_]}} =
+ (catch ?INTERFACE:get_id(inval)),
+
+ P1 = ?INTERFACE:open("p1"),
+ ok = ?INTERFACE:close(P1),
+ {'EXIT',{badarg,[{?INTERFACE,get_id,[P1],_}|_]}} =
+ (catch ?INTERFACE:get_id(P1)),
+
+ ok.
+
+get_name_errors(_Config) ->
+ P1 = ?INTERFACE:open("p1"),
+ {'EXIT',{badarg,[{?INTERFACE,get_name,[P1,inval],_}|_]}} =
+ (catch ?INTERFACE:get_name(P1,inval)),
+
+ undefined = ?INTERFACE:get_name(P1,1234),
+
+ P2 = ?INTERFACE:open("p2"),
+ P2Id = ?INTERFACE:get_id(P2),
+ ok = ?INTERFACE:close(P1),
+ {'EXIT',{badarg,[{?INTERFACE,get_name,[P1,P2Id],_}|_]}} =
+ (catch ?INTERFACE:get_name(P1,P2Id)),
+ ?INTERFACE:close(P2),
+
+ P3 = ?INTERFACE:open([255]),
+ <<255>> = ?INTERFACE:get_name(P3, ?INTERFACE:get_id(P3)),
+ ?INTERFACE:close(P3),
+
+ ok.
+
+hunt_errors(_Config) ->
+
+ {'EXIT',{badarg,[{?INTERFACE,hunt,[inval,"hello"],_}|_]}} =
+ (catch ?INTERFACE:hunt(inval,"hello")),
+
+ P1 = ?INTERFACE:open("p1"),
+ {'EXIT',{badarg,[{?INTERFACE,hunt,[P1,["hello",12345]],_}|_]}} =
+ (catch ?INTERFACE:hunt(P1,["hello",12345])),
+
+ P2 = ?INTERFACE:open(<<255>>),
+ P2Pid = ?INTERFACE:get_id(P2),
+ Ref = ?INTERFACE:hunt(P1,[255]),
+ receive
+ {mailbox_up,P1,Ref,P2Pid} ->
+ ok;
+ Else ->
+ ct:fail({got,Else,{mailbox_up,P1,Ref,P2Pid}})
+ after 150 ->
+ ct:fail({did_not_get,{mailbox_up,P1,Ref,P2Pid}})
+ end,
+
+ ok = ?INTERFACE:close(P1),
+ ok = ?INTERFACE:close(P2),
+ {'EXIT',{badarg,[{?INTERFACE,hunt,[P1,["hello"]],_}|_]}} =
+ (catch ?INTERFACE:hunt(P1,["hello"])),
+
+ ok.
+
+dehunt_errors(_Config) ->
+ P1 = ?INTERFACE:open("p1"),
+ Ref = ?INTERFACE:hunt(P1,"p2"),
+
+ {'EXIT',{badarg,[{?INTERFACE,dehunt,[inval,Ref],_}|_]}} =
+ (catch ?INTERFACE:dehunt(inval,Ref)),
+
+ {'EXIT',{badarg,[{?INTERFACE,dehunt,[P1,inval],_}|_]}} =
+ (catch ?INTERFACE:dehunt(P1,inval)),
+
+ ok = ?INTERFACE:dehunt(P1,Ref),
+ ok = ?INTERFACE:dehunt(P1,Ref),
+
+ ok = ?INTERFACE:close(P1),
+
+ {'EXIT',{badarg,[{?INTERFACE,dehunt,[P1,Ref],_}|_]}} =
+ (catch ?INTERFACE:dehunt(P1,Ref)),
+
+ case ?INTERFACE of
+ ose -> ok;
+ _ ->
+ P2 = ?INTERFACE:open("p2"),
+ ok = ?INTERFACE:close(P2)
+ end,
+
+ receive
+ Else -> ct:fail({got,Else})
+ after 100 ->
+ ok
+ end.
+
+attach_errors(_Config) ->
+ P1 = ?INTERFACE:open("p1"),
+ P2 = ?INTERFACE:open("p2"),
+ P2Id = ?INTERFACE:get_id(P2),
+
+ {'EXIT',{badarg,[{?INTERFACE,attach,[inval,P2Id],_}|_]}} =
+ (catch ?INTERFACE:attach(inval,P2Id)),
+
+ {'EXIT',{badarg,[{?INTERFACE,attach,[P1,[12345]],_}|_]}} =
+ (catch ?INTERFACE:attach(P1,[12345])),
+
+ ok = ?INTERFACE:close(P1),
+ ok = ?INTERFACE:close(P2),
+ {'EXIT',{badarg,[{?INTERFACE,attach,[P1,P2Id],_}|_]}} =
+ (catch ?INTERFACE:attach(P1,P2Id)),
+
+ ok.
+
+detach_errors(_Config) ->
+ P1 = ?INTERFACE:open("p1"),
+ P2 = ?INTERFACE:open("p2"),
+ P2Id = ?INTERFACE:get_id(P2),
+
+ Ref = ?INTERFACE:attach(P1,P2Id),
+
+ {'EXIT',{badarg,[{?INTERFACE,detach,[inval,Ref],_}|_]}} =
+ (catch ?INTERFACE:detach(inval,Ref)),
+
+ {'EXIT',{badarg,[{?INTERFACE,detach,[P1,inval],_}|_]}} =
+ (catch ?INTERFACE:detach(P1,inval)),
+
+ ok = ?INTERFACE:detach(P1,Ref),
+ ok = ?INTERFACE:detach(P1,Ref),
+
+ case ?INTERFACE of
+ ose -> ok;
+ _ ->
+ ok = ?INTERFACE:close(P1)
+ end,
+
+ ok = ?INTERFACE:close(P2),
+ ok = ?INTERFACE:close(P1),
+
+ {'EXIT',{badarg,[{?INTERFACE,detach,[P1,Ref],_}|_]}} =
+ (catch ?INTERFACE:detach(P1,Ref)),
+
+ receive
+ Else -> ct:fail({got,Else})
+ after 100 ->
+ ok
+ end.
+
+send_errors(_Config) ->
+ P1 = ?INTERFACE:open("p1"),
+ P2 = ?INTERFACE:open("p2"),
+ P2Id = ?INTERFACE:get_id(P2),
+
+ {'EXIT',{badarg,[{?INTERFACE,send,[inval,P2Id,42,"hello"],_}|_]}} =
+ (catch ?INTERFACE:send(inval,P2Id,42,"hello")),
+ {'EXIT',{badarg,[{?INTERFACE,send,[P1,inval,42,"hello"],_}|_]}} =
+ (catch ?INTERFACE:send(P1,inval,42,"hello")),
+ {'EXIT',{badarg,[{?INTERFACE,send,[P1,P2Id,inval,"hello"],_}|_]}} =
+ (catch ?INTERFACE:send(P1,P2Id,inval,"hello")),
+ {'EXIT',{badarg,[{?INTERFACE,send,[P1,P2Id,42,inval],_}|_]}} =
+ (catch ?INTERFACE:send(P1,P2Id,42,inval)),
+
+ ok = ?INTERFACE:close(P2),
+ ok = ?INTERFACE:send(P1,P2Id,42,"hello"),
+ ok = ?INTERFACE:close(P1),
+
+ {'EXIT',{badarg,[{?INTERFACE,send,[P1,P2Id,42,"hello"],_}|_]}} =
+ (catch ?INTERFACE:send(P1,P2Id,42,"hello")),
+
+ receive
+ Else -> ct:fail({got,Else})
+ after 100 ->
+ ok
+ end.
+
+send_w_s_errors(_Config) ->
+ P1 = ?INTERFACE:open("p1"),
+ P1Id = ?INTERFACE:get_id(P1),
+ P2 = ?INTERFACE:open("p2"),
+ P2Id = ?INTERFACE:get_id(P2),
+ P3 = ?INTERFACE:open("p3"),
+ P3Id = ?INTERFACE:get_id(P3),
+
+ {'EXIT',{badarg,[{?INTERFACE,send,[inval,P2Id,P1Id,42,"hello"],_}|_]}} =
+ (catch ?INTERFACE:send(inval,P2Id,P1Id,42,"hello")),
+ {'EXIT',{badarg,[{?INTERFACE,send,[P2,-1,P1Id,42,"hello"],_}|_]}} =
+ (catch ?INTERFACE:send(P2,-1,P1Id,42,"hello")),
+ {'EXIT',{badarg,[{?INTERFACE,send,[P2,P2Id,1 bsl 32,42,"hello"],_}|_]}} =
+ (catch ?INTERFACE:send(P2,P2Id,1 bsl 32,42,"hello")),
+ {'EXIT',{badarg,[{?INTERFACE,send,[P2,P2Id,P1Id,inval,"hello"],_}|_]}} =
+ (catch ?INTERFACE:send(P2,P2Id,P1Id,inval,"hello")),
+ {'EXIT',{badarg,[{?INTERFACE,send,[P2,P2Id,P1Id,42,inval],_}|_]}} =
+ (catch ?INTERFACE:send(P2,P2Id,P1Id,42,inval)),
+
+ ok = ?INTERFACE:close(P3),
+ ok = ?INTERFACE:send(P2,P3Id,P1Id,42,"hello"),
+
+ ok = ?INTERFACE:close(P1),
+ ok = ?INTERFACE:send(P2,P2Id,P1Id,42,"hello"),
+ ok = ?INTERFACE:close(P2),
+
+ {'EXIT',{badarg,[{?INTERFACE,send,[P1,P2Id,P1Id,42,"hello"],_}|_]}} =
+ (catch ?INTERFACE:send(P1,P2Id,P1Id,42,"hello")),
+
+ receive
+ Else -> ct:fail({got,Else})
+ after 100 ->
+ ok
+ end.
+
+listen_errors(_Config) ->
+
+ P1 = ?INTERFACE:open("p1"),
+ P1Id = ?INTERFACE:get_id(P1),
+
+ {'EXIT',{badarg,[{?INTERFACE,listen,[inval,[42]],_}|_]}} =
+ (catch ?INTERFACE:listen(inval,[42])),
+ {'EXIT',{badarg,[{?INTERFACE,listen,[P1,inval],_}|_]}} =
+ (catch ?INTERFACE:listen(P1,inval)),
+ {'EXIT',{badarg,[{?INTERFACE,listen,[P1,[1 bsl 33]],_}|_]}} =
+ (catch ?INTERFACE:listen(P1,[1 bsl 33])),
+
+ ok = ?INTERFACE:listen(P1,[42,42,42,42,42,42,42,42,42,42,42,42,42]),
+
+ case ?INTERFACE of
+ ose -> ok;
+ _ ->
+ ?INTERFACE:send(P1,P1Id,42,"hello"),
+ timer:sleep(50),
+ ?INTERFACE:listen(P1,[]),
+ ?INTERFACE:send(P1,P1Id,42,"hello2"),
+
+ receive
+ {message,P1,42,"hello"} -> ok
+ end,
+
+ receive
+ Else -> ct:fail({got,Else})
+ after 100 ->
+ ok
+ end
+ end,
+
+ ok = ?INTERFACE:close(P1),
+ {'EXIT',{badarg,[{?INTERFACE,listen,[P1,[42]],_}|_]}} =
+ (catch ?INTERFACE:listen(P1,[42])),
+
+ ok.
+
+%%
+%% Internal functions
+%%
+multi_open(N,ListenNums) ->
+ multi_open(N,ListenNums,[]).
+
+multi_open(0,_,Acc) ->
+ Acc;
+multi_open(N,ListenNums,Acc) ->
+ P = ?INTERFACE:open("p"++integer_to_list(N)),
+ ok = ?INTERFACE:listen(P,ListenNums),
+ multi_open(N-1,ListenNums,[P|Acc]).
+
+n(_F,0) ->
+ ok;
+n(F,N) ->
+ ok = F(N),
+ n(F,N-1).
+
+
+flush() ->
+ receive
+ Msg ->
+ [Msg|flush()]
+ after 0 ->
+ []
+ end.
--
cgit v1.2.3
From a6788ea337a2319a2d1a42ee4618553a1c7765bf Mon Sep 17 00:00:00 2001
From: Lukas Larsson
Date: Wed, 30 Oct 2013 17:56:37 +0100
Subject: ose: Fix various build environment issues
---
lib/erl_interface/aclocal.m4 | 9 ++++++++-
lib/megaco/aclocal.m4 | 9 ++++++++-
lib/odbc/aclocal.m4 | 9 ++++++++-
lib/wx/aclocal.m4 | 9 ++++++++-
4 files changed, 32 insertions(+), 4 deletions(-)
(limited to 'lib')
diff --git a/lib/erl_interface/aclocal.m4 b/lib/erl_interface/aclocal.m4
index 4a3407e0eb..09d0f0194c 100644
--- a/lib/erl_interface/aclocal.m4
+++ b/lib/erl_interface/aclocal.m4
@@ -84,6 +84,8 @@ AC_ARG_VAR(erl_xcomp_ose_LM_SET_CONF, [Sets the configuration for an OSE load mo
AC_ARG_VAR(erl_xcomp_ose_LM_ELF_SIZE, [Prints the section size information for an OSE load module (only used when cross compiling for OSE)])
AC_ARG_VAR(erl_xcomp_ose_LM_LCF, [OSE load module linker configuration file (only used when cross compiling for OSE)])
AC_ARG_VAR(erl_xcomp_ose_LM_CONF, [OSE load module default configuration file (only used when cross compiling for OSE)])
+AC_ARG_VAR(erl_xcomp_ose_CONFD, [OSE OSE confd source file])
+AC_ARG_VAR(erl_xcomp_ose_CRT0_LM, [OSE crt0 lm source file])
])
@@ -1106,7 +1108,12 @@ case "$THR_LIB_NAME" in
AC_DEFINE(ETHR_PTHREADS, 1, [Define if you have pthreads])
;;
ose_threads)
- AC_DEFINE(ETHR_OSE_THREADS, 1, [Define if you have OSE style threads]) ETHR_THR_LIB_BASE_DIR=ose
+ AC_DEFINE(ETHR_OSE_THREADS, 1,
+ [Define if you have OSE style threads])
+ ETHR_THR_LIB_BASE_DIR=ose
+ AC_CHECK_HEADER(ose_spi/ose_spi.h,
+ AC_DEFINE(HAVE_OSE_SPI, 1,
+ [Define if you have the "ose_spi/ose_spi.h" header file.]))
;;
esac
if test "x$THR_LIB_NAME" == "xpthread"; then
diff --git a/lib/megaco/aclocal.m4 b/lib/megaco/aclocal.m4
index 4a3407e0eb..09d0f0194c 100644
--- a/lib/megaco/aclocal.m4
+++ b/lib/megaco/aclocal.m4
@@ -84,6 +84,8 @@ AC_ARG_VAR(erl_xcomp_ose_LM_SET_CONF, [Sets the configuration for an OSE load mo
AC_ARG_VAR(erl_xcomp_ose_LM_ELF_SIZE, [Prints the section size information for an OSE load module (only used when cross compiling for OSE)])
AC_ARG_VAR(erl_xcomp_ose_LM_LCF, [OSE load module linker configuration file (only used when cross compiling for OSE)])
AC_ARG_VAR(erl_xcomp_ose_LM_CONF, [OSE load module default configuration file (only used when cross compiling for OSE)])
+AC_ARG_VAR(erl_xcomp_ose_CONFD, [OSE OSE confd source file])
+AC_ARG_VAR(erl_xcomp_ose_CRT0_LM, [OSE crt0 lm source file])
])
@@ -1106,7 +1108,12 @@ case "$THR_LIB_NAME" in
AC_DEFINE(ETHR_PTHREADS, 1, [Define if you have pthreads])
;;
ose_threads)
- AC_DEFINE(ETHR_OSE_THREADS, 1, [Define if you have OSE style threads]) ETHR_THR_LIB_BASE_DIR=ose
+ AC_DEFINE(ETHR_OSE_THREADS, 1,
+ [Define if you have OSE style threads])
+ ETHR_THR_LIB_BASE_DIR=ose
+ AC_CHECK_HEADER(ose_spi/ose_spi.h,
+ AC_DEFINE(HAVE_OSE_SPI, 1,
+ [Define if you have the "ose_spi/ose_spi.h" header file.]))
;;
esac
if test "x$THR_LIB_NAME" == "xpthread"; then
diff --git a/lib/odbc/aclocal.m4 b/lib/odbc/aclocal.m4
index 4a3407e0eb..09d0f0194c 100644
--- a/lib/odbc/aclocal.m4
+++ b/lib/odbc/aclocal.m4
@@ -84,6 +84,8 @@ AC_ARG_VAR(erl_xcomp_ose_LM_SET_CONF, [Sets the configuration for an OSE load mo
AC_ARG_VAR(erl_xcomp_ose_LM_ELF_SIZE, [Prints the section size information for an OSE load module (only used when cross compiling for OSE)])
AC_ARG_VAR(erl_xcomp_ose_LM_LCF, [OSE load module linker configuration file (only used when cross compiling for OSE)])
AC_ARG_VAR(erl_xcomp_ose_LM_CONF, [OSE load module default configuration file (only used when cross compiling for OSE)])
+AC_ARG_VAR(erl_xcomp_ose_CONFD, [OSE OSE confd source file])
+AC_ARG_VAR(erl_xcomp_ose_CRT0_LM, [OSE crt0 lm source file])
])
@@ -1106,7 +1108,12 @@ case "$THR_LIB_NAME" in
AC_DEFINE(ETHR_PTHREADS, 1, [Define if you have pthreads])
;;
ose_threads)
- AC_DEFINE(ETHR_OSE_THREADS, 1, [Define if you have OSE style threads]) ETHR_THR_LIB_BASE_DIR=ose
+ AC_DEFINE(ETHR_OSE_THREADS, 1,
+ [Define if you have OSE style threads])
+ ETHR_THR_LIB_BASE_DIR=ose
+ AC_CHECK_HEADER(ose_spi/ose_spi.h,
+ AC_DEFINE(HAVE_OSE_SPI, 1,
+ [Define if you have the "ose_spi/ose_spi.h" header file.]))
;;
esac
if test "x$THR_LIB_NAME" == "xpthread"; then
diff --git a/lib/wx/aclocal.m4 b/lib/wx/aclocal.m4
index 4a3407e0eb..09d0f0194c 100644
--- a/lib/wx/aclocal.m4
+++ b/lib/wx/aclocal.m4
@@ -84,6 +84,8 @@ AC_ARG_VAR(erl_xcomp_ose_LM_SET_CONF, [Sets the configuration for an OSE load mo
AC_ARG_VAR(erl_xcomp_ose_LM_ELF_SIZE, [Prints the section size information for an OSE load module (only used when cross compiling for OSE)])
AC_ARG_VAR(erl_xcomp_ose_LM_LCF, [OSE load module linker configuration file (only used when cross compiling for OSE)])
AC_ARG_VAR(erl_xcomp_ose_LM_CONF, [OSE load module default configuration file (only used when cross compiling for OSE)])
+AC_ARG_VAR(erl_xcomp_ose_CONFD, [OSE OSE confd source file])
+AC_ARG_VAR(erl_xcomp_ose_CRT0_LM, [OSE crt0 lm source file])
])
@@ -1106,7 +1108,12 @@ case "$THR_LIB_NAME" in
AC_DEFINE(ETHR_PTHREADS, 1, [Define if you have pthreads])
;;
ose_threads)
- AC_DEFINE(ETHR_OSE_THREADS, 1, [Define if you have OSE style threads]) ETHR_THR_LIB_BASE_DIR=ose
+ AC_DEFINE(ETHR_OSE_THREADS, 1,
+ [Define if you have OSE style threads])
+ ETHR_THR_LIB_BASE_DIR=ose
+ AC_CHECK_HEADER(ose_spi/ose_spi.h,
+ AC_DEFINE(HAVE_OSE_SPI, 1,
+ [Define if you have the "ose_spi/ose_spi.h" header file.]))
;;
esac
if test "x$THR_LIB_NAME" == "xpthread"; then
--
cgit v1.2.3
From a0766a4efeefe0ac035d2be04816274aee5751f3 Mon Sep 17 00:00:00 2001
From: Jonas Karlsson
Date: Fri, 8 Nov 2013 14:00:36 +0100
Subject: ose: Bugfixes to filesystem related issues.
---
lib/kernel/test/file_SUITE.erl | 39 +++++++++++++++++++++++++------------
lib/kernel/test/prim_file_SUITE.erl | 5 ++++-
2 files changed, 31 insertions(+), 13 deletions(-)
(limited to 'lib')
diff --git a/lib/kernel/test/file_SUITE.erl b/lib/kernel/test/file_SUITE.erl
index c75639ae7e..15b7016f7d 100644
--- a/lib/kernel/test/file_SUITE.erl
+++ b/lib/kernel/test/file_SUITE.erl
@@ -161,7 +161,13 @@ init_per_suite(Config) when is_list(Config) ->
ok ->
[{sasl,started}]
end,
- ok = application:start(os_mon),
+ ok = case os:type() of
+ {ose,_} ->
+ ok;
+ _ ->
+ application:start(os_mon)
+ end,
+
case os:type() of
{win32, _} ->
Priv = ?config(priv_dir, Config),
@@ -185,7 +191,13 @@ end_per_suite(Config) when is_list(Config) ->
_ ->
ok
end,
- application:stop(os_mon),
+
+ case os:type() of
+ {ose,_} ->
+ ok;
+ _ ->
+ application:stop(os_mon)
+ end,
case proplists:get_value(sasl, Config) of
started ->
application:stop(sasl);
@@ -525,11 +537,11 @@ cur_dir_1(Config) when is_list(Config) ->
?line Dog = test_server:timetrap(test_server:seconds(5)),
?line case os:type() of
- {unix, _} ->
- ?line {error, enotsup} = ?FILE_MODULE:get_cwd("d:");
- {win32, _} ->
- win_cur_dir_1(Config)
- end,
+ {win32, _} ->
+ win_cur_dir_1(Config);
+ _ ->
+ ?line {error, enotsup} = ?FILE_MODULE:get_cwd("d:")
+ end,
?line [] = flush(),
?line test_server:timetrap_cancel(Dog),
ok.
@@ -712,7 +724,10 @@ open1(Config) when is_list(Config) ->
?line io:format(Fd1,Str,[]),
?line {ok,0} = ?FILE_MODULE:position(Fd1,bof),
?line Str = io:get_line(Fd1,''),
- ?line Str = io:get_line(Fd2,''),
+ ?line case io:get_line(Fd2,'') of
+ Str -> Str;
+ eof -> Str
+ end,
?line ok = ?FILE_MODULE:close(Fd2),
?line {ok,0} = ?FILE_MODULE:position(Fd1,bof),
?line ok = ?FILE_MODULE:truncate(Fd1),
@@ -2171,13 +2186,13 @@ e_make_dir(Config) when is_list(Config) ->
%% No permission (on Unix only).
case os:type() of
- {unix, _} ->
+ {win32, _} ->
+ ok;
+ _ ->
?FILE_MODULE:write_file_info(Base, #file_info {mode=0}),
{error, eacces} = ?FILE_MODULE:make_dir(filename:join(Base, "xxxx")),
?FILE_MODULE:write_file_info(
- Base, #file_info {mode=8#600});
- {win32, _} ->
- ok
+ Base, #file_info {mode=8#600})
end,
test_server:timetrap_cancel(Dog),
ok.
diff --git a/lib/kernel/test/prim_file_SUITE.erl b/lib/kernel/test/prim_file_SUITE.erl
index ccf325a493..84618a881e 100644
--- a/lib/kernel/test/prim_file_SUITE.erl
+++ b/lib/kernel/test/prim_file_SUITE.erl
@@ -453,7 +453,10 @@ open1(Config) when is_list(Config) ->
?line ?PRIM_FILE:write(Fd1,Str),
?line {ok,0} = ?PRIM_FILE:position(Fd1,bof),
?line {ok, Str} = ?PRIM_FILE:read(Fd1,Length),
- ?line {ok, Str} = ?PRIM_FILE:read(Fd2,Length),
+ ?line case ?PRIM_FILE:read(Fd2,Length) of
+ Str -> Str;
+ eof -> Str
+ end,
?line ok = ?PRIM_FILE:close(Fd2),
?line {ok,0} = ?PRIM_FILE:position(Fd1,bof),
?line ok = ?PRIM_FILE:truncate(Fd1),
--
cgit v1.2.3
From 3d24208d607501207af371098c1466758844e667 Mon Sep 17 00:00:00 2001
From: Jonas Karlsson
Date: Fri, 22 Nov 2013 09:45:05 +0100
Subject: ose: efile driver updates.
---
lib/kernel/test/file_SUITE.erl | 23 +++++++++++++----------
lib/kernel/test/prim_file_SUITE.erl | 9 ++++++---
2 files changed, 19 insertions(+), 13 deletions(-)
(limited to 'lib')
diff --git a/lib/kernel/test/file_SUITE.erl b/lib/kernel/test/file_SUITE.erl
index 15b7016f7d..6b52493f46 100644
--- a/lib/kernel/test/file_SUITE.erl
+++ b/lib/kernel/test/file_SUITE.erl
@@ -1261,7 +1261,7 @@ file_info_basic_directory(Config) when is_list(Config) ->
?line test_directory("/", read_write),
?line test_directory("c:/", read_write),
?line test_directory("c:\\", read_write);
- {unix, _} ->
+ _ ->
?line test_directory("/", read)
end,
test_server:timetrap_cancel(Dog).
@@ -2045,15 +2045,15 @@ e_delete(Config) when is_list(Config) ->
%% No permission.
?line case os:type() of
- {unix, _} ->
+ {win32, _} ->
+ %% Remove a character device.
+ ?line {error, eacces} = ?FILE_MODULE:delete("nul");
+ _ ->
?line ?FILE_MODULE:write_file_info(
Base, #file_info {mode=0}),
?line {error, eacces} = ?FILE_MODULE:delete(Afile),
?line ?FILE_MODULE:write_file_info(
- Base, #file_info {mode=8#600});
- {win32, _} ->
- %% Remove a character device.
- ?line {error, eacces} = ?FILE_MODULE:delete("nul")
+ Base, #file_info {mode=8#600})
end,
?line [] = flush(),
@@ -2155,6 +2155,9 @@ e_rename(Config) when is_list(Config) ->
%% At least Windows NT can
%% successfully move a file to
%% another drive.
+ ok;
+ {ose, _} ->
+ %% disabled for now
ok
end,
[] = flush(),
@@ -2235,14 +2238,14 @@ e_del_dir(Config) when is_list(Config) ->
%% No permission.
case os:type() of
- {unix, _} ->
+ {win32, _} ->
+ ok;
+ _ ->
ADirectory = filename:join(Base, "no_perm"),
ok = ?FILE_MODULE:make_dir(ADirectory),
?FILE_MODULE:write_file_info( Base, #file_info {mode=0}),
{error, eacces} = ?FILE_MODULE:del_dir(ADirectory),
- ?FILE_MODULE:write_file_info( Base, #file_info {mode=8#600});
- {win32, _} ->
- ok
+ ?FILE_MODULE:write_file_info( Base, #file_info {mode=8#600})
end,
[] = flush(),
test_server:timetrap_cancel(Dog),
diff --git a/lib/kernel/test/prim_file_SUITE.erl b/lib/kernel/test/prim_file_SUITE.erl
index 84618a881e..3e6a85eadd 100644
--- a/lib/kernel/test/prim_file_SUITE.erl
+++ b/lib/kernel/test/prim_file_SUITE.erl
@@ -454,7 +454,7 @@ open1(Config) when is_list(Config) ->
?line {ok,0} = ?PRIM_FILE:position(Fd1,bof),
?line {ok, Str} = ?PRIM_FILE:read(Fd1,Length),
?line case ?PRIM_FILE:read(Fd2,Length) of
- Str -> Str;
+ {ok,Str} -> Str;
eof -> Str
end,
?line ok = ?PRIM_FILE:close(Fd2),
@@ -1664,7 +1664,7 @@ e_rename(Config) when is_list(Config) ->
%% successfully move a file to
%% another drive.
ok;
- _ ->
+ {unix, _ } ->
OtherFs = "/tmp",
?line NameOnOtherFs =
filename:join(OtherFs,
@@ -1688,7 +1688,10 @@ e_rename(Config) when is_list(Config) ->
Else ->
Else
end,
- Com
+ Com;
+ {ose, _} ->
+ %% disabled for now
+ ok
end,
?line test_server:timetrap_cancel(Dog),
Comment.
--
cgit v1.2.3
From b309ad9b4a3e4ff2d6d3a6e6270d37355a798bb1 Mon Sep 17 00:00:00 2001
From: Lukas Larsson
Date: Fri, 10 Jan 2014 17:16:15 +0100
Subject: ose: Fix check for HAVE_OSE_SPI_H
---
lib/erl_interface/aclocal.m4 | 2 +-
lib/megaco/aclocal.m4 | 2 +-
lib/odbc/aclocal.m4 | 2 +-
lib/wx/aclocal.m4 | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
(limited to 'lib')
diff --git a/lib/erl_interface/aclocal.m4 b/lib/erl_interface/aclocal.m4
index 09d0f0194c..c51c26794a 100644
--- a/lib/erl_interface/aclocal.m4
+++ b/lib/erl_interface/aclocal.m4
@@ -1112,7 +1112,7 @@ case "$THR_LIB_NAME" in
[Define if you have OSE style threads])
ETHR_THR_LIB_BASE_DIR=ose
AC_CHECK_HEADER(ose_spi/ose_spi.h,
- AC_DEFINE(HAVE_OSE_SPI, 1,
+ AC_DEFINE(HAVE_OSE_SPI_H, 1,
[Define if you have the "ose_spi/ose_spi.h" header file.]))
;;
esac
diff --git a/lib/megaco/aclocal.m4 b/lib/megaco/aclocal.m4
index 09d0f0194c..c51c26794a 100644
--- a/lib/megaco/aclocal.m4
+++ b/lib/megaco/aclocal.m4
@@ -1112,7 +1112,7 @@ case "$THR_LIB_NAME" in
[Define if you have OSE style threads])
ETHR_THR_LIB_BASE_DIR=ose
AC_CHECK_HEADER(ose_spi/ose_spi.h,
- AC_DEFINE(HAVE_OSE_SPI, 1,
+ AC_DEFINE(HAVE_OSE_SPI_H, 1,
[Define if you have the "ose_spi/ose_spi.h" header file.]))
;;
esac
diff --git a/lib/odbc/aclocal.m4 b/lib/odbc/aclocal.m4
index 09d0f0194c..c51c26794a 100644
--- a/lib/odbc/aclocal.m4
+++ b/lib/odbc/aclocal.m4
@@ -1112,7 +1112,7 @@ case "$THR_LIB_NAME" in
[Define if you have OSE style threads])
ETHR_THR_LIB_BASE_DIR=ose
AC_CHECK_HEADER(ose_spi/ose_spi.h,
- AC_DEFINE(HAVE_OSE_SPI, 1,
+ AC_DEFINE(HAVE_OSE_SPI_H, 1,
[Define if you have the "ose_spi/ose_spi.h" header file.]))
;;
esac
diff --git a/lib/wx/aclocal.m4 b/lib/wx/aclocal.m4
index 09d0f0194c..c51c26794a 100644
--- a/lib/wx/aclocal.m4
+++ b/lib/wx/aclocal.m4
@@ -1112,7 +1112,7 @@ case "$THR_LIB_NAME" in
[Define if you have OSE style threads])
ETHR_THR_LIB_BASE_DIR=ose
AC_CHECK_HEADER(ose_spi/ose_spi.h,
- AC_DEFINE(HAVE_OSE_SPI, 1,
+ AC_DEFINE(HAVE_OSE_SPI_H, 1,
[Define if you have the "ose_spi/ose_spi.h" header file.]))
;;
esac
--
cgit v1.2.3
From cd69c2a54201b4e0c4ba86d4248937120e1957e7 Mon Sep 17 00:00:00 2001
From: Lukas Larsson
Date: Wed, 8 Jan 2014 18:54:15 +0100
Subject: ose: Create OSE application
Create an specific OSE application that mainly contains documentation
around the OSE specific part of Erlang/OTP.
---
lib/Makefile | 2 +-
lib/kernel/doc/src/Makefile | 27 +-
lib/kernel/doc/src/ref_man.xml | 67 +++
lib/kernel/src/Makefile | 4 -
lib/kernel/src/ose.erl | 452 -------------------
lib/kernel/test/Makefile | 4 -
lib/kernel/test/ose_SUITE.erl | 765 --------------------------------
lib/ose/Makefile | 36 ++
lib/ose/doc/html/.gitignore | 0
lib/ose/doc/man3/.gitignore | 0
lib/ose/doc/man6/.gitignore | 0
lib/ose/doc/pdf/.gitignore | 0
lib/ose/doc/src/.gitignore | 1 +
lib/ose/doc/src/Makefile | 132 ++++++
lib/ose/doc/src/book.xml | 48 ++
lib/ose/doc/src/notes.xml | 33 ++
lib/ose/doc/src/ose_app.xml | 37 ++
lib/ose/doc/src/ose_erl_driver.xml | 109 +++++
lib/ose/doc/src/ose_intro.xml | 48 ++
lib/ose/doc/src/ose_signals_chapter.xml | 197 ++++++++
lib/ose/doc/src/part.xml | 38 ++
lib/ose/doc/src/ref_man.xml | 39 ++
lib/ose/ebin/.gitignore | 0
lib/ose/include/.gitignore | 0
lib/ose/info | 2 +
lib/ose/src/Makefile | 106 +++++
lib/ose/src/ose.app.src | 26 ++
lib/ose/src/ose.appup.src | 22 +
lib/ose/src/ose.erl | 452 +++++++++++++++++++
lib/ose/test/Makefile | 67 +++
lib/ose/test/ose.cover | 2 +
lib/ose/test/ose.spec | 1 +
lib/ose/test/ose_SUITE.erl | 765 ++++++++++++++++++++++++++++++++
lib/ose/vsn.mk | 1 +
34 files changed, 2233 insertions(+), 1250 deletions(-)
create mode 100644 lib/kernel/doc/src/ref_man.xml
delete mode 100644 lib/kernel/src/ose.erl
delete mode 100644 lib/kernel/test/ose_SUITE.erl
create mode 100644 lib/ose/Makefile
create mode 100644 lib/ose/doc/html/.gitignore
create mode 100644 lib/ose/doc/man3/.gitignore
create mode 100644 lib/ose/doc/man6/.gitignore
create mode 100644 lib/ose/doc/pdf/.gitignore
create mode 100644 lib/ose/doc/src/.gitignore
create mode 100644 lib/ose/doc/src/Makefile
create mode 100644 lib/ose/doc/src/book.xml
create mode 100644 lib/ose/doc/src/notes.xml
create mode 100644 lib/ose/doc/src/ose_app.xml
create mode 100644 lib/ose/doc/src/ose_erl_driver.xml
create mode 100644 lib/ose/doc/src/ose_intro.xml
create mode 100644 lib/ose/doc/src/ose_signals_chapter.xml
create mode 100644 lib/ose/doc/src/part.xml
create mode 100644 lib/ose/doc/src/ref_man.xml
create mode 100644 lib/ose/ebin/.gitignore
create mode 100644 lib/ose/include/.gitignore
create mode 100644 lib/ose/info
create mode 100644 lib/ose/src/Makefile
create mode 100644 lib/ose/src/ose.app.src
create mode 100644 lib/ose/src/ose.appup.src
create mode 100644 lib/ose/src/ose.erl
create mode 100644 lib/ose/test/Makefile
create mode 100644 lib/ose/test/ose.cover
create mode 100644 lib/ose/test/ose.spec
create mode 100644 lib/ose/test/ose_SUITE.erl
create mode 100644 lib/ose/vsn.mk
(limited to 'lib')
diff --git a/lib/Makefile b/lib/Makefile
index 5128241563..9257d8c7a9 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -34,7 +34,7 @@ ALL_ERLANG_APPLICATIONS = snmp otp_mibs erl_interface asn1 jinterface \
public_key ssl observer odbc diameter \
cosTransactions cosEvent cosTime cosNotification \
cosProperty cosFileTransfer cosEventDomain et megaco webtool \
- eunit ssh typer percept eldap dialyzer hipe
+ eunit ssh typer percept eldap dialyzer hipe ose
ifdef BUILD_ALL
ERLANG_APPLICATIONS += $(ALL_ERLANG_APPLICATIONS)
diff --git a/lib/kernel/doc/src/Makefile b/lib/kernel/doc/src/Makefile
index 7f8023aba4..ec5d1f09e4 100644
--- a/lib/kernel/doc/src/Makefile
+++ b/lib/kernel/doc/src/Makefile
@@ -31,12 +31,6 @@ APPLICATION=kernel
# ----------------------------------------------------
RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN)
-# ----------------------------------------------------
-# Help application directory specification
-# ----------------------------------------------------
-EDOC_DIR = $(ERL_TOP)/lib/edoc
-SYNTAX_TOOLS_DIR = $(ERL_TOP)/lib/syntax_tools
-
# ----------------------------------------------------
# Target Specs
# ----------------------------------------------------
@@ -71,12 +65,6 @@ XML_REF3_FILES = application.xml \
user.xml \
zlib_stub.xml
-ifeq ($(findstring ose,$(TARGET)),ose)
-XML_EDOC_FILES = ose.xml
-else
-XML_EDOC_FILES =
-endif
-
XML_REF4_FILES = app.xml config.xml
XML_REF6_FILES = kernel_app.xml
@@ -88,8 +76,8 @@ BOOK_FILES = book.xml
XML_FILES = \
$(BOOK_FILES) $(XML_CHAPTER_FILES) \
- $(XML_PART_FILES) $(XML_REF3_FILES) $(XML_EDOC_FILES)\
- $(XML_REF4_FILES) $(XML_REF6_FILES) $(XML_APPLICATION_FILES)
+ $(XML_PART_FILES) $(XML_REF3_FILES) $(XML_REF4_FILES)\
+ $(XML_REF6_FILES) $(XML_APPLICATION_FILES)
# ----------------------------------------------------
@@ -115,7 +103,7 @@ TOP_SPECS_FILE = specs.xml
# ----------------------------------------------------
XML_FLAGS +=
-SRC_DIR = ../../src
+SPECS_ESRC = ../../src
SPECS_FLAGS = -I../../include
@@ -160,15 +148,6 @@ $(SPECDIR)/specs_zlib_stub.xml:
escript $(SPECS_EXTRACTOR) $(SPECS_FLAGS) \
-o$(dir $@) -module zlib_stub
-ose.xml: $(SRC_DIR)/ose.erl
- escript $(DOCGEN)/priv/bin/xml_from_edoc.escript $(SRC_DIR)/$(@:%.xml=%.erl)
-ref_man.xml: ref_man.xml.src
-ifeq ($(findstring ose,$(TARGET)),ose)
- sed -e 's:\(os.xml"/>\):\1\n:' $< > $@
-else
- cp $< $@
-endif
-
# ----------------------------------------------------
# Release Target
# ----------------------------------------------------
diff --git a/lib/kernel/doc/src/ref_man.xml b/lib/kernel/doc/src/ref_man.xml
new file mode 100644
index 0000000000..bd25d1e78d
--- /dev/null
+++ b/lib/kernel/doc/src/ref_man.xml
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+ 19962013
+ Ericsson AB. All Rights Reserved.
+
+
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+
+
+ Kernel Reference Manual
+
+
+
+
+
+
+ The Kernel application has all the code necessary to run
+ the Erlang runtime system itself: file servers and code servers
+ and so on.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/kernel/src/Makefile b/lib/kernel/src/Makefile
index 5379006784..cb3c0a49f4 100644
--- a/lib/kernel/src/Makefile
+++ b/lib/kernel/src/Makefile
@@ -117,10 +117,6 @@ MODULES = \
user_sup \
wrap_log_reader
-ifeq ($(findstring ose,$(TARGET)),ose)
-MODULES+=ose
-endif
-
HRL_FILES= ../include/file.hrl ../include/inet.hrl ../include/inet_sctp.hrl \
../include/dist.hrl ../include/dist_util.hrl \
../include/net_address.hrl
diff --git a/lib/kernel/src/ose.erl b/lib/kernel/src/ose.erl
deleted file mode 100644
index ff7147233f..0000000000
--- a/lib/kernel/src/ose.erl
+++ /dev/null
@@ -1,452 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2013. All Rights Reserved.
-%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
-%%
-%% %CopyrightEnd%
-%%
-%% @doc Interface module for OSE messaging and process monitoring from Erlang
-%%
-%% For each mailbox created through {@link open/1} a OSE phantom process with
-%% that name is started. Since phantom processes are used the memory footprint
-%% of each mailbox is quite small.
-%%
-%% To receive messages you first have to subscribe to the specific message
-%% numbers that you are interested in with {@link listen/2}. The messages
-%% will be sent to the Erlang process that created the mailbox.
-%%
-%% @end
-%%
--module(ose).
-
-%%==============================================================================
-%% Exported API
-%%==============================================================================
--export([open/1,
- close/1,
- get_id/1,
- get_name/2,
- hunt/2,
- dehunt/2,
- attach/2,
- detach/2,
- send/4,
- send/5,
- listen/2
- ]).
-
-%%==============================================================================
-%% Types
-%%==============================================================================
--opaque mailbox() :: port().
-%% Mailbox handle. Implemented as an erlang port.
-
--opaque mailbox_id() :: integer().
-%% Mailbox ID, this is the same as the process id of an OSE process.
-%% An integer.
-
--type message_number() :: 0..4294967295.
-%% OSE Signal number
-
--opaque hunt_ref() :: {mailbox(),integer()}.
-%% Reference from a hunt request. This term will be included
-%% in a successful hunt response.
-
--opaque attach_ref() :: {mailbox(),integer()}.
-%% Reference from an attach request. This term will be included
-%% in the term returned when the attached mailbox disappears.
-
--export_type([mailbox_id/0,
- message_number/0,
- mailbox/0,
- hunt_ref/0,
- attach_ref/0]).
-
-%%==============================================================================
-%% Defines
-%%==============================================================================
--define(DRIVER_NAME, "ose_signal_drv").
--define(GET_SPID, 1).
--define(GET_NAME, 2).
--define(HUNT, 100).
--define(DEHUNT, 101).
--define(ATTACH, 102).
--define(DETACH, 103).
--define(SEND, 104).
--define(SEND_W_S, 105).
--define(LISTEN, 106).
--define(OPEN, 200).
-
--define(INT_32BIT(Int),(is_integer(Int) andalso (Int >= 0) andalso (Int < (1 bsl 32)))).
-
-%%==============================================================================
-%% API functions
-%%==============================================================================
-
-%%------------------------------------------------------------------------------
-%% @doc Create a mailbox with the given name and return a port that handles
-%% the mailbox.
-%%
-%% An OSE phantom process with the given name will be created that will send any
-%% messages sent through this mailbox. Any messages sent to the new OSE process
-%% will automatically be converted to an Erlang message and sent to the Erlang
-%% process that calls this function. See {@link listen/2} for details about the
-%% format of the message sent.
-%%
-%% The caller gets linked to the created mailbox.
-%%
-%% raises: `badarg' | `system_limit'
-%%
-%% @see liten/2
-%% @end
-%%------------------------------------------------------------------------------
--spec open(Name) -> Port when
- Name :: iodata(),
- Port :: mailbox().
-open(Name) ->
- try open_port({spawn_driver,?DRIVER_NAME}, [binary]) of
- Port ->
- try port_command(Port,[?OPEN,Name]) of
- true ->
- receive
- {ose_drv_reply,Port,{error,Error}} ->
- close(Port),
- erlang:error(Error,[Name]);
- {ose_drv_reply,Port,ok} ->
- Port
- end
- catch
- error:badarg -> close(Port),erlang:error(badarg,[Name])
- end
- catch
- error:badarg -> erlang:error(badarg,[Name])
- end.
-
-%%------------------------------------------------------------------------------
-%% @doc Close a mailbox
-%%
-%% This kills the OSE phantom process associated with this mailbox.
-%%
-%% Will also consume any ``{'EXIT',Port,_}'' message from the port that comes
-%% due to the port closing when the calling process traps exits.
-%%
-%% raises: `badarg'
-%% @end
-%%------------------------------------------------------------------------------
--spec close(Port) -> ok when
- Port :: mailbox().
-close(Port) when is_port(Port) ->
- %% Copied from prim_inet
- case erlang:process_info(self(), trap_exit) of
- {trap_exit,true} ->
- link(Port),
- catch erlang:port_close(Port),
- receive {'EXIT',Port,_} -> ok end;
- {trap_exit,false} ->
- catch erlang:port_close(Port),
- ok
- end;
-close(NotPort) ->
- erlang:error(badarg,[NotPort]).
-
-%%------------------------------------------------------------------------------
-%% @doc Get the mailbox id for the given port.
-%%
-%% The mailbox id is the same as the OSE process id of the OSE phantom process
-%% that this mailbox represents.
-%%
-%% raises: `badarg'
-%% @end
-%%------------------------------------------------------------------------------
--spec get_id(Port) -> Pid when
- Port :: mailbox(),
- Pid :: mailbox_id().
-get_id(Port) ->
- try port_control(Port, ?GET_SPID, <<>>) of
- <> -> Spid
- catch error:_Error ->
- erlang:error(badarg,[Port])
- end.
-
-%%------------------------------------------------------------------------------
-%% @doc Get the mailbox name for the given mailbox id.
-%%
-%% The mailbox name is the name of the OSE process with process id Pid.
-%%
-%% This call will fail with badarg if the underlying system does not support
-%% getting the name from a process id.
-%%
-%% raises: `badarg'
-%% @end
-%%------------------------------------------------------------------------------
--spec get_name(Port, Pid) -> Name | undefined when
- Port :: mailbox(),
- Pid :: mailbox_id(),
- Name :: binary().
-get_name(Port, Pid) when ?INT_32BIT(Pid) ->
- try port_control(Port, ?GET_NAME, <>) of
- [] -> undefined;
- Res -> Res
- catch error:_Error ->
- erlang:error(badarg,[Port,Pid])
- end;
-get_name(Port, Pid) ->
- erlang:error(badarg,[Port,Pid]).
-
-
-%%------------------------------------------------------------------------------
-%% @doc Hunt for OSE process by name.
-%%
-%% Will send `{mailbox_up, Port, Ref, MboxId}'
-%% to the calling process when the OSE process becomes available.
-%%
-%% Returns a reference term that can be used to cancel the hunt
-%% using {@link dehunt/2}.
-%%
-%% raises: `badarg'
-%%
-%% @end
-%%------------------------------------------------------------------------------
--spec hunt(Port, HuntPath) -> Ref when
- Port :: mailbox(),
- HuntPath :: iodata(),
- Ref :: hunt_ref().
-hunt(Port, HuntPath) ->
- try port_command(Port, [?HUNT,HuntPath]) of
- true ->
- receive
- {ose_drv_reply,Port,{error,Error}} ->
- erlang:error(Error,[Port,HuntPath]);
- {ose_drv_reply,Port,Ref} ->
- Ref
- end
- catch error:_Error ->
- erlang:error(badarg,[Port,HuntPath])
- end.
-
-%%------------------------------------------------------------------------------
-%% @doc Stop hunting for OSE process.
-%%
-%% If a message for this hunt has been sent but not received
-%% by the calling process, it is removed from the message queue.
-%% Note that this only works if the same process that did
-%% the hunt does the dehunt.
-%%
-%% raises: `badarg'
-%%
-%% @see hunt/2
-%% @end
-%%------------------------------------------------------------------------------
--spec dehunt(Port, Ref) -> ok when
- Port :: mailbox(),
- Ref :: hunt_ref().
-dehunt(Port, {Port,Ref}) when ?INT_32BIT(Ref) ->
- try port_command(Port, <>) of
- true ->
- receive
- {ose_drv_reply,Port,{error,enoent}} ->
- %% enoent could mean that it is in the message queue
- receive
- {mailbox_up, Port, {Port,Ref}, _} ->
- ok
- after 0 ->
- ok
- end;
- {ose_drv_reply,Port,ok} ->
- ok
- end
- catch error:_Error ->
- erlang:error(badarg,[Port,{Port,Ref}])
- end;
-dehunt(Port,Ref) ->
- erlang:error(badarg,[Port,Ref]).
-
-%%------------------------------------------------------------------------------
-%% @doc Attach to an OSE process.
-%%
-%% Will send `{mailbox_down, Port, Ref, MboxId}'
-%% to the calling process if the OSE process exits.
-%%
-%% Returns a reference that can be used to cancel the attachment
-%% using {@link detach/2}.
-%%
-%% raises: `badarg' | `enomem'
-%%
-%% @end
-%%------------------------------------------------------------------------------
--spec attach(Port,Pid) -> Ref when
- Port :: mailbox(),
- Pid :: mailbox_id(),
- Ref :: attach_ref().
-attach(Port, Spid) when ?INT_32BIT(Spid) ->
- try port_command(Port, <>) of
- true ->
- receive
- {ose_drv_reply,Port,{error,Error}} ->
- erlang:error(Error,[Port,Spid]);
- {ose_drv_reply,Port,Ref} ->
- Ref
- end
- catch error:_Error ->
- erlang:error(badarg,[Port,Spid])
- end;
-attach(Port,Spid) ->
- erlang:error(badarg,[Port,Spid]).
-
-
-%%------------------------------------------------------------------------------
-%% @doc Remove attachment to an OSE process.
-%%
-%% If a message for this monitor has been sent but not received
-%% by the calling process, it is removed from the message queue.
-%% Note that this only works of the same process
-%% that did the attach does the detach.
-%%
-%% raises: `badarg'
-%%
-%% @see attach/2
-%% @end
-%%------------------------------------------------------------------------------
--spec detach(Port,Ref) -> ok when
- Port :: mailbox(),
- Ref :: attach_ref().
-detach(Port, {Port,Ref} ) when ?INT_32BIT(Ref) ->
- try port_command(Port, <>) of
- true ->
- receive
- {ose_drv_reply,Port,{error,enoent}} ->
- %% enoent could mean that it is in the message queue
- receive
- {mailbox_down,Port,{Port,Ref},_} ->
- ok
- after 0 ->
- ok
- end;
- {ose_drv_reply,Port,ok} ->
- ok
- end
- catch error:_Error ->
- erlang:error(badarg,[Port,{Port,Ref}])
- end;
-detach(Port,Ref) ->
- erlang:error(badarg,[Port,Ref]).
-
-%%------------------------------------------------------------------------------
-%% @doc Send an OSE message.
-%%
-%% The message is sent from the OSE process' own ID that is: `get_id(Port)'.
-%%
-%% raises: `badarg'
-%%
-%% @see send/5
-%% @end
-%%------------------------------------------------------------------------------
--spec send(Port,Pid,SigNo,SigData) -> ok when
- Port :: mailbox(),
- Pid :: mailbox_id(),
- SigNo :: message_number(),
- SigData :: iodata().
-send(Port, Spid, SigNo, SigData) when ?INT_32BIT(Spid), ?INT_32BIT(SigNo) ->
- try erlang:port_command(Port, [<>, SigData]) of
- true -> ok
- catch error:_Error ->
- erlang:error(badarg,[Port,Spid,SigNo,SigData])
- end;
-send(Port,Spid,SigNo,SigData) ->
- erlang:error(badarg,[Port,Spid,SigNo,SigData]).
-
-
-%%------------------------------------------------------------------------------
-%% @doc Send an OSE message with different sender.
-%%
-%% As {@link send/4} but the sender will be `SenderPid'.
-%%
-%% raises: `badarg'
-%%
-%% @see send/4
-%% @end
-%%------------------------------------------------------------------------------
--spec send(Port,Pid,SenderPid,SigNo,SigData) -> ok when
- Port :: mailbox(),
- Pid :: mailbox_id(),
- SenderPid :: mailbox_id(),
- SigNo :: message_number(),
- SigData :: iodata().
-send(Port, Spid, SenderPid, SigNo, SigData)
- when ?INT_32BIT(Spid), ?INT_32BIT(SenderPid), ?INT_32BIT(SigNo) ->
- try erlang:port_command(Port, [<>, SigData]) of
- true -> ok
- catch error:_Error ->
- erlang:error(badarg,[Port,Spid,SenderPid,SigNo,SigData])
- end;
-send(Port,Spid,SenderPid,SigNo,SigData) ->
- erlang:error(badarg,[Port,Spid,SenderPid,SigNo,SigData]).
-
-%%------------------------------------------------------------------------------
-%% @doc Start listening for specified OSE signal numbers.
-%%
-%% The mailbox will send `{message,Port,{FromMboxId,ToMboxId,MsgNo,MsgData}}'
-%% to the process that created the mailbox when an OSE message with any
-%% of the specified `SigNos' arrives.
-%%
-%% Repeated calls to listen will replace the current set of signal numbers to
-%% listen to. i.e
-%%
-%% ```1>ose:listen(MsgB,[1234,12345]).
-%% ok
-%% 2> ose:listen(MsgB,[1234,123456]).
-%% ok.'''
-%%
-%% The above will first listen for signals with numbers 1234 and 12345, and then
-%% replace that with only listening to 1234 and 123456.
-%%
-%% With the current implementation it is not possible to listen to all signal
-%% numbers.
-%%
-%% raises: `badarg' | `enomem'
-%%
-%% @end
-%%------------------------------------------------------------------------------
--spec listen(Port, SigNos) -> ok when
- Port :: mailbox(),
- SigNos :: list(message_number()).
-listen(Port, SigNos) when is_list(SigNos) ->
- USSigNos = lists:usort(SigNos),
- BinSigNos = try
- << <> ||
- SigNo <- USSigNos,
- ?INT_32BIT(SigNo) orelse erlang:error(badarg)
- >>
- catch _:_ ->
- erlang:error(badarg,[Port,SigNos])
- end,
- try port_command(Port, [?LISTEN, BinSigNos]) of
- true ->
- receive
- {ose_drv_reply,Port,{error,Error}} ->
- erlang:error(Error,[Port,SigNos]);
- {ose_drv_reply,Port,Else} ->
- Else
- end
- catch error:_Error ->
- erlang:error(badarg,[Port,SigNos])
- end;
-listen(Port, SigNos) ->
- erlang:error(badarg,[Port,SigNos]).
-
-
-%%%=============================================================================
-%%% Internal functions
-%%%=============================================================================
diff --git a/lib/kernel/test/Makefile b/lib/kernel/test/Makefile
index ac28d1aae9..f1b8a105ed 100644
--- a/lib/kernel/test/Makefile
+++ b/lib/kernel/test/Makefile
@@ -79,10 +79,6 @@ MODULES= \
loose_node \
sendfile_SUITE
-ifeq ($(findstring ose,$(TARGET)),ose)
-MODULES+=ose_SUITE
-endif
-
APP_FILES = \
appinc.app \
appinc1.app \
diff --git a/lib/kernel/test/ose_SUITE.erl b/lib/kernel/test/ose_SUITE.erl
deleted file mode 100644
index 7e81b19894..0000000000
--- a/lib/kernel/test/ose_SUITE.erl
+++ /dev/null
@@ -1,765 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1998-2013. All Rights Reserved.
-%%
-%% The contents of this file are subject to the Erlang Public License,
-%% Version 1.1, (the "License"); you may not use this file except in
-%% compliance with the License. You should have received a copy of the
-%% Erlang Public License along with this software. If not, it can be
-%% retrieved online at http://www.erlang.org/.
-%%
-%% Software distributed under the License is distributed on an "AS IS"
-%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-%% the License for the specific language governing rights and limitations
-%% under the License.
-%%
-%% %CopyrightEnd%
-%%
--module(ose_SUITE).
-
-%-compile(export_all).
-
--export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
- init_per_group/2,end_per_group/2,init_per_testcase/2,
- end_per_testcase/2]).
--export([
- basic/1,stress/1,multi_msg_numbers/1,multi_mailboxes/1,
- hunt/1,multi_hunt/1,dehunt/1,multi_dehunt/1,
- attach/1,multi_attach/1,detach/1,multi_detach/1,
- open_errors/1,close_errors/1,get_id_errors/1,get_name_errors/1,
- hunt_errors/1,dehunt_errors/1,attach_errors/1,detach_errors/1,
- send_errors/1,send_w_s_errors/1,listen_errors/1
- ]).
-
--define(INTERFACE,ose).
-
-
-init_per_testcase(_Func, Config) ->
- Config.
-end_per_testcase(_Func, _Config) ->
- ok.
-
-suite() -> [{timeout,{30,seconds}}].
-
-all() ->
- [
- basic,stress,multi_msg_numbers,multi_mailboxes,
- hunt,multi_hunt,dehunt,multi_dehunt,
- attach,multi_attach,detach,multi_detach,
-
- open_errors,close_errors,get_id_errors,get_name_errors,
- hunt_errors,dehunt_errors,attach_errors,detach_errors,
- send_errors,send_w_s_errors,listen_errors
- ].
-
-groups() ->
- [].
-
-init_per_suite(Config) ->
- case os:type() of
- {ose,_} ->
- Config;
- _Else ->
- {skip,"Only run on OSE"}
- end.
-
-end_per_suite(_Config) ->
- ok.
-
-init_per_group(_GroupName, Config) ->
- Config.
-
-end_per_group(_GroupName, Config) ->
- Config.
-
-basic(_Config) ->
-
- [P1,P2] = multi_open(2,[42]),
- P1Id = ?INTERFACE:get_id(P1),
- P2Id = ?INTERFACE:get_id(P2),
-
- ok = ?INTERFACE:send(P2,P1Id,42,<<"ping">>),
- receive
- {message,P1,V1} ->
- {P2Id,P1Id,42,<<"ping">>} = V1,
- ?INTERFACE:send(P1,P2Id,42,<<"pong">>);
- Else1 ->
- ct:fail({got_wrong_message,Else1})
- end,
-
- receive
- {message,P2,V2} ->
- {P1Id,P2Id,42,<<"pong">>} = V2;
- Else2 ->
- ct:fail({got_wrong_message,Else2})
- end,
-
- ?INTERFACE:close(P1),
- ?INTERFACE:close(P2).
-
-%% Send 1000 messages and see if we can cope and that msg order is preserved
-stress(_Config) ->
-
- Iterations = 1000,
-
- [P1,P2] = multi_open(2,[42]),
- P1Id = ?INTERFACE:get_id(P1),
- P2Id = ?INTERFACE:get_id(P2),
-
- spawn(fun() ->
- n(fun(N) ->
- Msg = [<<"ping">>|integer_to_list(N)],
- ?INTERFACE:send(P2,P1Id,42,Msg)
- end,Iterations)
- end),
- timer:sleep(100),
- n(fun(N) ->
- receive
- {message,P1,Value} ->
- Int = integer_to_binary(N),
- {P2Id,P1Id,42,<<"ping",Int/binary>>} = Value,
- ok;
- Else ->
- ct:fail({got_wrong_message,Else})
- end
- end,Iterations),
-
- ?INTERFACE:close(P1),
- ?INTERFACE:close(P2).
-
-%% Listen to 1000 different message numbers and send some random messages
-multi_msg_numbers(_Config) ->
-
- Iterations = 100,
-
- [P1,P2] = multi_open(2,lists:seq(2000,3000)),
- P1Id = ?INTERFACE:get_id(P1),
-
- n(fun(_) ->
- Num = random:uniform(1000)+2000,
- ?INTERFACE:send(P2,P1Id,Num,<<"ping",(integer_to_binary(Num))/binary>>)
- end,Iterations),
-
- n(fun(_) ->
- receive
- {message,P1,{_,_,Id,<<"ping",Num/binary>>}} when Id > 2000;
- Id =< 3000 ->
- Id = binary_to_integer(Num),
- ok;
- Else ->
- ct:fail({got_wrong_message,Else})
- end
- end,Iterations),
-
- ?INTERFACE:close(P1),
- ?INTERFACE:close(P2).
-
-
-%% Create 100 mailboxes and send messages to them
-multi_mailboxes(_Config) ->
-
- Mailboxes = 100,
-
- [P1|MBs] = multi_open(Mailboxes,[42]),
-
- [?INTERFACE:send(P1,?INTERFACE:get_id(P),42,[<<"ping">>,?INTERFACE:get_name(P,?INTERFACE:get_id(P))]) || P <- MBs],
-
- [receive
- {message,P,Value} ->
- Name = ?INTERFACE:get_name(P,?INTERFACE:get_id(P)),
- {_,_,42,<<"ping",Name/binary>>} = Value,
- ok
- end || P <- MBs],
-
- [?INTERFACE:close(P) || P <- [P1|MBs]],
- ok.
-
-hunt(_Config) ->
- [P1,P2] = multi_open(2,[]),
-
- Ref = ?INTERFACE:hunt(P1,"p2"),
- receive
- {mailbox_up,P1,Ref,Pid} ->
- Pid = ?INTERFACE:get_id(P2),
- ?INTERFACE:close(P1),
- ?INTERFACE:close(P2);
- Else ->
- ct:fail({got_wrong_message,Else,Ref})
- end.
-
-multi_hunt(_Config) ->
-
- Iterations = 100,
-
- P = ?INTERFACE:open("p"),
-
- Refs = [?INTERFACE:hunt(P,"p"++integer_to_list(N))|| N <- lists:seq(1,Iterations)],
-
- Pids = [begin
- Prt = ?INTERFACE:open("p"++integer_to_list(N)),
- Pid = ?INTERFACE:get_id(Prt),
- ?INTERFACE:close(Prt),
- Pid
- end || N <- lists:seq(1,Iterations)],
-
- [receive
- {mailbox_up,P,Ref,Pid} ->
- ok
- after 10 ->
- ct:fail({did_not_get,Pid,Ref})
- end || {Pid,Ref} <- lists:zip(Pids,Refs)],
- ?INTERFACE:close(P).
-
-
-dehunt(_Config) ->
- [P1] = multi_open(1,[]),
- Ref = ?INTERFACE:hunt(P1,"p2"),
- receive
- _Else -> ct:fail({got,_Else})
- after 1000 ->
- ok
- end,
- P2 = ?INTERFACE:open("p2"),
-
- % Make sure any messages are sent
- receive after 10 -> ok end,
-
- ok = ?INTERFACE:dehunt(P1,Ref),
-
- % Make sure no messages are received
- receive
- _Else2 -> ct:fail({got,_Else2})
- after 1000 ->
- ?INTERFACE:close(P1),
- ?INTERFACE:close(P2)
- end.
-
-%%%
-%%% This testcase basically:
-%%% spawn 10 processes that in parallel
-%%% adds some hunts for different OSE processes
-%%% maybe create hunted OSE process
-%%% dehunt half of the hunts
-%%% create more hunts
-%%% if not created create hunted OSE process
-%%% veryify that all expected hunt messages are received
-%%% verify that all processes exited correctly
-%%%
-%%% This complex test is done to make sure that the internal handling
-%%% of dehunt works as expected.
-%%%
-multi_dehunt(_Config) ->
- [P1] = multi_open(1,[]),
-
- Scenario =
- fun(Iterations) ->
-
- Hunted = "p"++integer_to_list(Iterations),
- %% Start a couple of hunts
- Refs = [?INTERFACE:hunt(P1,Hunted) || _ <- lists:seq(1,Iterations)],
-
- %% We alternate if the process is opened before or after the dehunt
- P2O = if Iterations rem 2 == 0 ->
- ?INTERFACE:open(Hunted);
- true ->
- undefined
- end,
-
- %% Remove half of them
- {RemRefs,_} = lists:mapfoldl(fun(Ref,Acc) when Acc rem 2 == 0 ->
- ok = ?INTERFACE:dehunt(P1,Ref),
- {[],Acc+1};
- (Ref,Acc) ->
- {Ref,Acc+1}
- end,0,Refs),
-
- %% Add some new ones
- NewRefs = [?INTERFACE:hunt(P1,Hunted)
- || _ <- lists:seq(1,Iterations div 4)]
- ++ lists:flatten(RemRefs),
-
- P2 = if P2O == undefined ->
- ?INTERFACE:open(Hunted);
- true ->
- P2O
- end,
- P2Id = ?INTERFACE:get_id(P2),
-
- %% Receive all the expected ones
- lists:foreach(fun(Ref) ->
- receive
- {mailbox_up,P1,Ref,P2Id} ->
- ok
- after 1000 ->
- io:format("Flush: ~p~n",[flush()]),
- io:format("~p~n",[{Iterations,{did_not_get, Ref}}]),
- ok = Ref
- end
- end,NewRefs),
-
- %% Check that no other have arrived
- receive
- _Else ->
- io:format("Flush: ~p~n",[flush()]),
- io:format("~p~n",[{Iterations,{got, _Else}}]),
- ok = _Else
- after 100 ->
- ok
- end,
- ?INTERFACE:close(P2)
- end,
-
- Self = self(),
-
- n(fun(N) ->
- spawn(fun() -> Self !
- Scenario(N*25)
- end),
- ok
- end,10),
-
- n(fun(_N) ->
- receive ok -> ok
- after 60000 -> ct:fail(failed)
- end
- end,10),
- ?INTERFACE:close(P1).
-
-attach(_Config) ->
- [P1,P2] = multi_open(2,[]),
-
- P2Id = ?INTERFACE:get_id(P2),
- Ref = ?INTERFACE:attach(P1,P2Id),
- ?INTERFACE:close(P2),
- receive
- {mailbox_down,P1,Ref,P2Id} ->
- ?INTERFACE:close(P1);
- _Else ->
- ct:fail({got,_Else, {P1,Ref,P2Id}})
- after 1000 ->
- ct:fail({did_not_get,P1,Ref,P2Id})
- end.
-
-multi_attach(_Config) ->
-
- Iterations = 100,
-
- [P1|Pids] = multi_open(Iterations,[]),
-
- Refs = [{?INTERFACE:get_id(Pid),?INTERFACE:attach(P1,?INTERFACE:get_id(Pid))} || Pid <- Pids],
-
- [?INTERFACE:close(Pid) || Pid <- Pids],
-
- [receive
- {mailbox_down,P1,Ref,Pid} ->
- ok
- after 10000 ->
- ct:fail({did_not_get,Pid,Ref})
- end || {Pid,Ref} <- Refs],
- ?INTERFACE:close(P1).
-
-detach(_Config) ->
- [P1,P2] = multi_open(2,[]),
- P2Id = ?INTERFACE:get_id(P2),
- Ref = ?INTERFACE:attach(P1,P2Id),
- receive
- _Else -> ct:fail({got,_Else})
- after 100 ->
- ok
- end,
-
- ?INTERFACE:close(P2),
-
- % Make sure any messages are sent
- receive after 10 -> ok end,
-
- ?INTERFACE:detach(P1,Ref),
-
- % Make sure no messages are received
- receive
- _Else2 -> ct:fail({got,_Else2})
- after 1000 ->
- ?INTERFACE:close(P1)
- end.
-
-%%%
-%%% This testcase basically:
-%%% spawn 10 processes that in parallel
-%%% adds some attach for different OSE processes
-%%% maybe close OSE process
-%%% dehunt half of the hunts
-%%% create more hunts
-%%% if not closed close attached OSE process
-%%% veryify that all expected attach messages are received
-%%% verify that all processes exited correctly
-%%%
-%%% This complex test is done to make sure that the internal handling
-%%% of dehunt works as expected.
-%%%
-multi_detach(_Config) ->
- [P1] = multi_open(1,[]),
-
- Scenario =
- fun(Iterations) ->
-
- Attached = ?INTERFACE:open("p"++integer_to_list(Iterations)),
- AttachedId = ?INTERFACE:get_id(Attached),
- %% Start a couple of attachs
- Refs = [?INTERFACE:attach(P1,AttachedId) || _ <- lists:seq(1,Iterations)],
-
- %% We alternate if the process is closed before or after the detach
- P2O = if Iterations rem 2 == 0 ->
- ?INTERFACE:close(Attached);
- true ->
- undefined
- end,
-
- %% Remove half of them
- {RemRefs,_} = lists:mapfoldl(fun(Ref,Acc) when Acc rem 2 == 0 ->
- ok = ?INTERFACE:detach(P1,Ref),
- {[],Acc+1};
- (Ref,Acc) ->
- {Ref,Acc+1}
- end,0,Refs),
-
- %% Add some new ones
- NewRefs = [?INTERFACE:attach(P1,AttachedId)
- || _ <- lists:seq(1,Iterations div 4)]
- ++ lists:flatten(RemRefs),
-
- if P2O == undefined ->
- ?INTERFACE:close(Attached);
- true ->
- P2O
- end,
-
- %% Receive all the expected ones
- lists:foreach(fun(Ref) ->
- receive
- {mailbox_down,P1,Ref,AttachedId} ->
- ok
- after 1000 ->
- io:format("Flush: ~p~n",[flush()]),
- io:format("~p~n",[{Iterations,{did_not_get, Ref}}]),
- ok = Ref
- end
- end,NewRefs),
-
- %% Check that no other have arrived
- receive
- _Else ->
- io:format("Flush: ~p~n",[flush()]),
- io:format("~p~n",[{Iterations,{got, _Else}}]),
- ok = _Else
- after 100 ->
- ok
- end
- end,
-
- Self = self(),
-
- n(fun(N) ->
- spawn(fun() -> Self !
- Scenario(N*5)
- end),
- ok
- end,10),
-
- n(fun(_N) ->
- receive ok -> ok
- after 60000 -> ct:fail(failed)
- end
- end,10),
- ?INTERFACE:close(P1).
-
-
-open_errors(_Config) ->
- {'EXIT',{badarg,[{?INTERFACE,open,[inval],_}|_]}} =
- (catch ?INTERFACE:open(inval)),
- {'EXIT',{badarg,[{?INTERFACE,open,[["p"|1]],_}|_]}} =
- (catch ?INTERFACE:open(["p"|1])),
- {'EXIT',{badarg,[{?INTERFACE,open,[["p",1234]],_}|_]}} =
- (catch ?INTERFACE:open(["p",1234])),
-
- ok.
-
-close_errors(_Config) ->
- {'EXIT',{badarg,[{?INTERFACE,close,[inval],_}|_]}} =
- (catch ?INTERFACE:close(inval)),
-
- P1 = ?INTERFACE:open("p1"),
- ok = ?INTERFACE:close(P1),
- ok = ?INTERFACE:close(P1).
-
-
-get_id_errors(_Config) ->
- {'EXIT',{badarg,[{?INTERFACE,get_id,[inval],_}|_]}} =
- (catch ?INTERFACE:get_id(inval)),
-
- P1 = ?INTERFACE:open("p1"),
- ok = ?INTERFACE:close(P1),
- {'EXIT',{badarg,[{?INTERFACE,get_id,[P1],_}|_]}} =
- (catch ?INTERFACE:get_id(P1)),
-
- ok.
-
-get_name_errors(_Config) ->
- P1 = ?INTERFACE:open("p1"),
- {'EXIT',{badarg,[{?INTERFACE,get_name,[P1,inval],_}|_]}} =
- (catch ?INTERFACE:get_name(P1,inval)),
-
- undefined = ?INTERFACE:get_name(P1,1234),
-
- P2 = ?INTERFACE:open("p2"),
- P2Id = ?INTERFACE:get_id(P2),
- ok = ?INTERFACE:close(P1),
- {'EXIT',{badarg,[{?INTERFACE,get_name,[P1,P2Id],_}|_]}} =
- (catch ?INTERFACE:get_name(P1,P2Id)),
- ?INTERFACE:close(P2),
-
- P3 = ?INTERFACE:open([255]),
- <<255>> = ?INTERFACE:get_name(P3, ?INTERFACE:get_id(P3)),
- ?INTERFACE:close(P3),
-
- ok.
-
-hunt_errors(_Config) ->
-
- {'EXIT',{badarg,[{?INTERFACE,hunt,[inval,"hello"],_}|_]}} =
- (catch ?INTERFACE:hunt(inval,"hello")),
-
- P1 = ?INTERFACE:open("p1"),
- {'EXIT',{badarg,[{?INTERFACE,hunt,[P1,["hello",12345]],_}|_]}} =
- (catch ?INTERFACE:hunt(P1,["hello",12345])),
-
- P2 = ?INTERFACE:open(<<255>>),
- P2Pid = ?INTERFACE:get_id(P2),
- Ref = ?INTERFACE:hunt(P1,[255]),
- receive
- {mailbox_up,P1,Ref,P2Pid} ->
- ok;
- Else ->
- ct:fail({got,Else,{mailbox_up,P1,Ref,P2Pid}})
- after 150 ->
- ct:fail({did_not_get,{mailbox_up,P1,Ref,P2Pid}})
- end,
-
- ok = ?INTERFACE:close(P1),
- ok = ?INTERFACE:close(P2),
- {'EXIT',{badarg,[{?INTERFACE,hunt,[P1,["hello"]],_}|_]}} =
- (catch ?INTERFACE:hunt(P1,["hello"])),
-
- ok.
-
-dehunt_errors(_Config) ->
- P1 = ?INTERFACE:open("p1"),
- Ref = ?INTERFACE:hunt(P1,"p2"),
-
- {'EXIT',{badarg,[{?INTERFACE,dehunt,[inval,Ref],_}|_]}} =
- (catch ?INTERFACE:dehunt(inval,Ref)),
-
- {'EXIT',{badarg,[{?INTERFACE,dehunt,[P1,inval],_}|_]}} =
- (catch ?INTERFACE:dehunt(P1,inval)),
-
- ok = ?INTERFACE:dehunt(P1,Ref),
- ok = ?INTERFACE:dehunt(P1,Ref),
-
- ok = ?INTERFACE:close(P1),
-
- {'EXIT',{badarg,[{?INTERFACE,dehunt,[P1,Ref],_}|_]}} =
- (catch ?INTERFACE:dehunt(P1,Ref)),
-
- case ?INTERFACE of
- ose -> ok;
- _ ->
- P2 = ?INTERFACE:open("p2"),
- ok = ?INTERFACE:close(P2)
- end,
-
- receive
- Else -> ct:fail({got,Else})
- after 100 ->
- ok
- end.
-
-attach_errors(_Config) ->
- P1 = ?INTERFACE:open("p1"),
- P2 = ?INTERFACE:open("p2"),
- P2Id = ?INTERFACE:get_id(P2),
-
- {'EXIT',{badarg,[{?INTERFACE,attach,[inval,P2Id],_}|_]}} =
- (catch ?INTERFACE:attach(inval,P2Id)),
-
- {'EXIT',{badarg,[{?INTERFACE,attach,[P1,[12345]],_}|_]}} =
- (catch ?INTERFACE:attach(P1,[12345])),
-
- ok = ?INTERFACE:close(P1),
- ok = ?INTERFACE:close(P2),
- {'EXIT',{badarg,[{?INTERFACE,attach,[P1,P2Id],_}|_]}} =
- (catch ?INTERFACE:attach(P1,P2Id)),
-
- ok.
-
-detach_errors(_Config) ->
- P1 = ?INTERFACE:open("p1"),
- P2 = ?INTERFACE:open("p2"),
- P2Id = ?INTERFACE:get_id(P2),
-
- Ref = ?INTERFACE:attach(P1,P2Id),
-
- {'EXIT',{badarg,[{?INTERFACE,detach,[inval,Ref],_}|_]}} =
- (catch ?INTERFACE:detach(inval,Ref)),
-
- {'EXIT',{badarg,[{?INTERFACE,detach,[P1,inval],_}|_]}} =
- (catch ?INTERFACE:detach(P1,inval)),
-
- ok = ?INTERFACE:detach(P1,Ref),
- ok = ?INTERFACE:detach(P1,Ref),
-
- case ?INTERFACE of
- ose -> ok;
- _ ->
- ok = ?INTERFACE:close(P1)
- end,
-
- ok = ?INTERFACE:close(P2),
- ok = ?INTERFACE:close(P1),
-
- {'EXIT',{badarg,[{?INTERFACE,detach,[P1,Ref],_}|_]}} =
- (catch ?INTERFACE:detach(P1,Ref)),
-
- receive
- Else -> ct:fail({got,Else})
- after 100 ->
- ok
- end.
-
-send_errors(_Config) ->
- P1 = ?INTERFACE:open("p1"),
- P2 = ?INTERFACE:open("p2"),
- P2Id = ?INTERFACE:get_id(P2),
-
- {'EXIT',{badarg,[{?INTERFACE,send,[inval,P2Id,42,"hello"],_}|_]}} =
- (catch ?INTERFACE:send(inval,P2Id,42,"hello")),
- {'EXIT',{badarg,[{?INTERFACE,send,[P1,inval,42,"hello"],_}|_]}} =
- (catch ?INTERFACE:send(P1,inval,42,"hello")),
- {'EXIT',{badarg,[{?INTERFACE,send,[P1,P2Id,inval,"hello"],_}|_]}} =
- (catch ?INTERFACE:send(P1,P2Id,inval,"hello")),
- {'EXIT',{badarg,[{?INTERFACE,send,[P1,P2Id,42,inval],_}|_]}} =
- (catch ?INTERFACE:send(P1,P2Id,42,inval)),
-
- ok = ?INTERFACE:close(P2),
- ok = ?INTERFACE:send(P1,P2Id,42,"hello"),
- ok = ?INTERFACE:close(P1),
-
- {'EXIT',{badarg,[{?INTERFACE,send,[P1,P2Id,42,"hello"],_}|_]}} =
- (catch ?INTERFACE:send(P1,P2Id,42,"hello")),
-
- receive
- Else -> ct:fail({got,Else})
- after 100 ->
- ok
- end.
-
-send_w_s_errors(_Config) ->
- P1 = ?INTERFACE:open("p1"),
- P1Id = ?INTERFACE:get_id(P1),
- P2 = ?INTERFACE:open("p2"),
- P2Id = ?INTERFACE:get_id(P2),
- P3 = ?INTERFACE:open("p3"),
- P3Id = ?INTERFACE:get_id(P3),
-
- {'EXIT',{badarg,[{?INTERFACE,send,[inval,P2Id,P1Id,42,"hello"],_}|_]}} =
- (catch ?INTERFACE:send(inval,P2Id,P1Id,42,"hello")),
- {'EXIT',{badarg,[{?INTERFACE,send,[P2,-1,P1Id,42,"hello"],_}|_]}} =
- (catch ?INTERFACE:send(P2,-1,P1Id,42,"hello")),
- {'EXIT',{badarg,[{?INTERFACE,send,[P2,P2Id,1 bsl 32,42,"hello"],_}|_]}} =
- (catch ?INTERFACE:send(P2,P2Id,1 bsl 32,42,"hello")),
- {'EXIT',{badarg,[{?INTERFACE,send,[P2,P2Id,P1Id,inval,"hello"],_}|_]}} =
- (catch ?INTERFACE:send(P2,P2Id,P1Id,inval,"hello")),
- {'EXIT',{badarg,[{?INTERFACE,send,[P2,P2Id,P1Id,42,inval],_}|_]}} =
- (catch ?INTERFACE:send(P2,P2Id,P1Id,42,inval)),
-
- ok = ?INTERFACE:close(P3),
- ok = ?INTERFACE:send(P2,P3Id,P1Id,42,"hello"),
-
- ok = ?INTERFACE:close(P1),
- ok = ?INTERFACE:send(P2,P2Id,P1Id,42,"hello"),
- ok = ?INTERFACE:close(P2),
-
- {'EXIT',{badarg,[{?INTERFACE,send,[P1,P2Id,P1Id,42,"hello"],_}|_]}} =
- (catch ?INTERFACE:send(P1,P2Id,P1Id,42,"hello")),
-
- receive
- Else -> ct:fail({got,Else})
- after 100 ->
- ok
- end.
-
-listen_errors(_Config) ->
-
- P1 = ?INTERFACE:open("p1"),
- P1Id = ?INTERFACE:get_id(P1),
-
- {'EXIT',{badarg,[{?INTERFACE,listen,[inval,[42]],_}|_]}} =
- (catch ?INTERFACE:listen(inval,[42])),
- {'EXIT',{badarg,[{?INTERFACE,listen,[P1,inval],_}|_]}} =
- (catch ?INTERFACE:listen(P1,inval)),
- {'EXIT',{badarg,[{?INTERFACE,listen,[P1,[1 bsl 33]],_}|_]}} =
- (catch ?INTERFACE:listen(P1,[1 bsl 33])),
-
- ok = ?INTERFACE:listen(P1,[42,42,42,42,42,42,42,42,42,42,42,42,42]),
-
- case ?INTERFACE of
- ose -> ok;
- _ ->
- ?INTERFACE:send(P1,P1Id,42,"hello"),
- timer:sleep(50),
- ?INTERFACE:listen(P1,[]),
- ?INTERFACE:send(P1,P1Id,42,"hello2"),
-
- receive
- {message,P1,42,"hello"} -> ok
- end,
-
- receive
- Else -> ct:fail({got,Else})
- after 100 ->
- ok
- end
- end,
-
- ok = ?INTERFACE:close(P1),
- {'EXIT',{badarg,[{?INTERFACE,listen,[P1,[42]],_}|_]}} =
- (catch ?INTERFACE:listen(P1,[42])),
-
- ok.
-
-%%
-%% Internal functions
-%%
-multi_open(N,ListenNums) ->
- multi_open(N,ListenNums,[]).
-
-multi_open(0,_,Acc) ->
- Acc;
-multi_open(N,ListenNums,Acc) ->
- P = ?INTERFACE:open("p"++integer_to_list(N)),
- ok = ?INTERFACE:listen(P,ListenNums),
- multi_open(N-1,ListenNums,[P|Acc]).
-
-n(_F,0) ->
- ok;
-n(F,N) ->
- ok = F(N),
- n(F,N-1).
-
-
-flush() ->
- receive
- Msg ->
- [Msg|flush()]
- after 0 ->
- []
- end.
diff --git a/lib/ose/Makefile b/lib/ose/Makefile
new file mode 100644
index 0000000000..2959f04c3e
--- /dev/null
+++ b/lib/ose/Makefile
@@ -0,0 +1,36 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 1996-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+include $(ERL_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+#
+# Macros
+#
+
+SUB_DIRECTORIES = src doc/src
+
+include vsn.mk
+VSN = $(OSE_VSN)
+
+SPECIAL_TARGETS =
+
+#
+# Default Subdir Targets
+#
+include $(ERL_TOP)/make/otp_subdir.mk
diff --git a/lib/ose/doc/html/.gitignore b/lib/ose/doc/html/.gitignore
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/lib/ose/doc/man3/.gitignore b/lib/ose/doc/man3/.gitignore
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/lib/ose/doc/man6/.gitignore b/lib/ose/doc/man6/.gitignore
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/lib/ose/doc/pdf/.gitignore b/lib/ose/doc/pdf/.gitignore
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/lib/ose/doc/src/.gitignore b/lib/ose/doc/src/.gitignore
new file mode 100644
index 0000000000..860e9e703e
--- /dev/null
+++ b/lib/ose/doc/src/.gitignore
@@ -0,0 +1 @@
+ose.xml
diff --git a/lib/ose/doc/src/Makefile b/lib/ose/doc/src/Makefile
new file mode 100644
index 0000000000..dd58029064
--- /dev/null
+++ b/lib/ose/doc/src/Makefile
@@ -0,0 +1,132 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 1997-2012. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+include $(ERL_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+# ----------------------------------------------------
+# Application version
+# ----------------------------------------------------
+include ../../vsn.mk
+VSN=$(OSE_VSN)
+APPLICATION=ose
+
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN)
+
+# ----------------------------------------------------
+# Help application directory specification
+# ----------------------------------------------------
+EDOC_DIR = $(ERL_TOP)/lib/edoc
+SYNTAX_TOOLS_DIR = $(ERL_TOP)/lib/syntax_tools
+
+# ----------------------------------------------------
+# Target Specs
+# ----------------------------------------------------
+XML_APPLICATION_FILES = ref_man.xml
+
+XML_REF3_FILES = \
+ ose.xml \
+ ose_erl_driver.xml
+
+XML_REF6_FILES = ose_app.xml
+
+XML_PART_FILES = part.xml
+XML_CHAPTER_FILES = notes.xml ose_intro.xml ose_signals_chapter.xml
+
+BOOK_FILES = book.xml
+
+XML_FILES = \
+ $(BOOK_FILES) $(XML_CHAPTER_FILES) \
+ $(XML_PART_FILES) $(XML_REF3_FILES) $(XML_REF6_FILES) \
+ $(XML_APPLICATION_FILES)
+
+# ----------------------------------------------------
+
+HTML_FILES = $(XML_APPLICATION_FILES:%.xml=$(HTMLDIR)/%.html) \
+ $(XML_PART_FILES:%.xml=$(HTMLDIR)/%.html)
+
+INFO_FILE = ../../info
+
+MAN3_FILES = $(XML_REF3_FILES:%.xml=$(MAN3DIR)/%.3)
+MAN6_FILES = $(XML_REF6_FILES:%_app.xml=$(MAN6DIR)/%.6)
+
+HTML_REF_MAN_FILE = $(HTMLDIR)/index.html
+
+TOP_PDF_FILE = $(PDFDIR)/$(APPLICATION)-$(VSN).pdf
+
+SPECS_FILES =
+
+TOP_SPECS_FILE =
+
+# ----------------------------------------------------
+# FLAGS
+# ----------------------------------------------------
+XML_FLAGS +=
+
+SPECS_FLAGS = -I../../include -I../../../kernel/include
+
+OSE_SRC_DIR = ../../src
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+docs: man pdf html
+
+$(TOP_PDF_FILE): $(XML_FILES)
+
+pdf: $(TOP_PDF_FILE)
+
+html: $(HTML_REF_MAN_FILE)
+
+man: $(MAN3_FILES) $(MAN6_FILES)
+
+ose.xml: $(OSE_SRC_DIR)/ose.erl
+ escript $(DOCGEN)/priv/bin/xml_from_edoc.escript\
+ $(OSE_SRC_DIR)/$(@:%.xml=%.erl)
+
+debug opt:
+
+clean clean_docs:
+ rm -rf $(HTMLDIR)/*
+ rm -f $(MAN3DIR)/*
+ rm -f $(MAN6DIR)/*
+ rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo)
+ rm -f $(SPECDIR)/*
+ rm -f errs core *~
+
+# ----------------------------------------------------
+# Release Target
+# ----------------------------------------------------
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+release_docs_spec: docs
+ $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf"
+ $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf"
+ $(INSTALL_DIR) "$(RELSYSDIR)/doc/html"
+ $(INSTALL_DATA) $(HTMLDIR)/* \
+ "$(RELSYSDIR)/doc/html"
+ $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)"
+ $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3"
+ $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3"
+ $(INSTALL_DIR) "$(RELEASE_PATH)/man/man6"
+ $(INSTALL_DATA) $(MAN6_FILES) "$(RELEASE_PATH)/man/man6"
+
+release_spec:
diff --git a/lib/ose/doc/src/book.xml b/lib/ose/doc/src/book.xml
new file mode 100644
index 0000000000..485806e05b
--- /dev/null
+++ b/lib/ose/doc/src/book.xml
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+ 20142014
+ Ericsson AB. All Rights Reserved.
+
+
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+
+
+ OSE
+ Lukas Larsson
+
+ 2014-01-08
+ 1.0
+ book.xml
+
+
+
+ OSE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/ose/doc/src/notes.xml b/lib/ose/doc/src/notes.xml
new file mode 100644
index 0000000000..760b92feed
--- /dev/null
+++ b/lib/ose/doc/src/notes.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+ 20142014
+ Ericsson AB. All Rights Reserved.
+
+
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+
+
+ OSE Release Notes
+
+
+
+
+ notes.xml
+
+ This document describes the changes made to the OSE application.
+
+
diff --git a/lib/ose/doc/src/ose_app.xml b/lib/ose/doc/src/ose_app.xml
new file mode 100644
index 0000000000..e40656fd7b
--- /dev/null
+++ b/lib/ose/doc/src/ose_app.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+ 20142014
+ Ericsson AB. All Rights Reserved.
+
+
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+
+
+ Enea OSE
+
+
+
+
+
+ ose
+ The OSE Application
+
+ The OSE application contains modules and documentation that only
+ applies when running Erlang/OTP on Enea OSE.
+
+
+
diff --git a/lib/ose/doc/src/ose_erl_driver.xml b/lib/ose/doc/src/ose_erl_driver.xml
new file mode 100644
index 0000000000..6687d78087
--- /dev/null
+++ b/lib/ose/doc/src/ose_erl_driver.xml
@@ -0,0 +1,109 @@
+
+
+
+
+
+
+ 20132014
+ Ericsson AB. All Rights Reserved.
+
+
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+
+
+ erl_driver for Enea OSE
+ Lukas Larsson
+
+ 2014-01-08
+ A
+ ose_erl_driver.xml
+
+ ose_erl_driver
+ Linked-in drivers in Enea OSE
+
+ Writing Linked-in drivers that also work on Enea OSE is very similar for
+ how you would do it for Unix. The difference from Unix is that
+ driver_select, ready_input and ready_output all work with signals
+ instead of file descriptors. This means that the driver_select is
+ used to specify which type of signal should trigger calls to
+ ready_input/ready_output. The functions described below are available
+ to driver programmers on Enea OSE to facilitate this.
+
+
+
+ DATA TYPES
+
+
+ union SIGNAL
+ - See the Enea OSE SPI documentation for a description.
+ SIGSELECT
+ - See the Enea OSE SPI documentation for a description.
+ ErlDrvEvent
+ - The ErlDrvEvent is a handle to a signal number and id combination. It is passed to driver_select(3).
+ ErlDrvOseEventId
+ - This is the id used to associate a specific signal to a
+ certain driver instance.
+
+
+
+
+ union SIGNAL *erl_drv_ose_get_signal(ErlDrvEvent drv_event)
+
+
+ Fetch the next signal associated with drv_event.
+ Signals will be returned in the order which they were received and
+ when no more signals are available NULL will be returned.
+ Use this function in the ready_input/ready_output callbacks
+ to get signals.
+
+
+
+ ErlDrvEventerl_drv_ose_event_alloc(SIGSELECT signo, ErlDrvOseEventId id, ErlDrvOseEventId (*resolve_signal)(union SIGNAL* sig))
+
+
+ Create a new ErlDrvEvent associated with signo,
+ id and uses the resolve_signal function to extract
+ the id from a signal with signo. See
+
+ Signals in a Linked-in driver in the OSE User's Guide.
+
+
+
+
+ voiderl_drv_ose_event_free(ErlDrvEvent drv_event)
+
+
+ Free a ErlDrvEvent. This should always be done in the
+ stop_select
+ callback when the event is no longer being used.
+
+
+
+ voiderl_drv_ose_event_fetch(ErlDrvEvent drv_event, SIGSELECT *signo, int *id)
+
+
+ Write the signal number and id associated with drv_event
+ into *signo and *id respectively. NULL can be
+ also passed as signo or id in order to ignore that field.
+
+
+
+
+
+ SEE ALSO
+
+ driver_entry(3),
+ erl_driver(3)
+
+
+
diff --git a/lib/ose/doc/src/ose_intro.xml b/lib/ose/doc/src/ose_intro.xml
new file mode 100644
index 0000000000..3bab325289
--- /dev/null
+++ b/lib/ose/doc/src/ose_intro.xml
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+ 20132014
+ Ericsson AB. All Rights Reserved.
+
+
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+
+
+ Introduction
+ Lukas Larsson
+
+ 2014-01-08
+ A
+ ose_intro.xml
+
+
+
+
+
+ run_erl and to_erl
+
+ In OSE run_erl and to_erl are combined into a single load module called
+ run_erl_lm. Installing and starting the load module will add two new
+ shell commands called run_erl and to_erl. They work in exactly the same
+ way as the unix variants of run_erl and to_erl, except that the read
+ and write pipes have to be placed under the /pipe vm. See also
+ run_erl for more details.
+
+
+
+
diff --git a/lib/ose/doc/src/ose_signals_chapter.xml b/lib/ose/doc/src/ose_signals_chapter.xml
new file mode 100644
index 0000000000..2a6ddb5765
--- /dev/null
+++ b/lib/ose/doc/src/ose_signals_chapter.xml
@@ -0,0 +1,197 @@
+
+
+
+
+
+
+ 20132014
+ Ericsson AB. All Rights Reserved.
+
+
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+
+
+ Interacting with Enea OSE
+ Lukas Larsson
+
+ 2014-01-08
+ A
+ ose_signals_chapter.xml
+
+
+
+
+ Introduction
+ The main way which programs on Enea OSE interact is through the
+ usage of message passing, much the same way as Erlang processes
+ communicate. There are two ways in which an Erlang programmer can
+ interact with the signals sent from other Enea OSE processes; either
+ through the provided ose module, or by writing a custom linked-in
+ driver. This User's Guide describes and provides examples for both
+ approaches.
+
+
+
+
+
+
+
+
+ Signals in a Linked-in driver
+
+ Writing Linked-in drivers for OSE is very similar to how it is done
+ for Unix/Windows. It is only the way in which the driver subscribes
+ and consumed external events that is different. In Unix (and Windows)
+ file descriptiors (and Event Objects) are used to select on. On OSE
+ we use signals to deliver the same functionality. There are two large
+ differences between a signal and an fd.
+
+
+ In OSE it is not possible for a signal number to be a unique identifier
+ for a resource in the same way as an fd is. For example; let's say we
+ implement a driver that does an asynchronous hunt that uses signal
+ number 1234 as the hunt_sig. If we want to be able to have multiple
+ hunt ports running at the same time we have to have someway of routing
+ the signal to the correct port. This is achieved by supplying a secondary
+ id that can be retrieved through the meta-data or payload of the signal,
+ e.g:
+ ErlDrvEvent event = erl_drv_ose_event_alloc(1234,port,resolver);
+ The event you get back from
+
+ erl_drv_ose_event_alloc can then be used by
+ driver_select
+ to subscribe to signals. The first argument is just the signal number
+ that we are interested in. The second is the id that we choose to use,
+ in this case the port id that we got in the
+ start callback is
+ used. The third argument is a function pointer to a function that can
+ be used to figure out the id from a given signal. There is a complete
+ example of what this could look like in
+ the next section.
+ It is very important to issue the driver_select call before
+ any of the signals you are interested in are sent. If driver_select
+ is called after the signal is sent, there is a high probability that it
+ will be lost.
+
+
+ The other difference from unix is that in OSE the payload of the event
+ (i.e. the signal data) is already received when the ready_output/input
+ callbacks are called. This means that you access the data of a signal
+ by calling
+ erl_drv_ose_get_signal. Additionally multiple signals might be
+ associated with the event, so you should call
+
+ erl_drv_ose_get_signal until NULL is returned.
+
+
+
+
+
+ Example Linked-in driver
+#include "erl_driver.h"
+#include "ose.h"
+
+struct huntsig {
+ SIGSELECT signo;
+ ErlDrvPort port;
+};
+
+union SIGNAL {
+ SIGSELECT signo;
+ struct huntsig;
+}
+
+/* Here we have to get the id from the signal. In this case we use the
+ port id since we have control over the data structure of the signal.
+ It is however possible to use anything in here. The only restriction
+ is that the same id has to be used for all signals of the same number.*/
+ErlDrvOseEventId resolver(union SIGNAL *sig) {
+ return (ErlDrvOseEventId)sig->huntsig.port;
+}
+
+static int drv_init(void) { return 0; };
+
+static ErlDrvData drv_start(ErlDrvPort port, char *command) {
+ return (ErlDrvData)port;
+}
+
+static ErlDrvSSizeT control(ErlDrvData driver_data, unsigned int cmd,
+ char *buf, ErlDrvSizeT len,
+ char **rbuf, ErlDrvSizeT rlen) {
+ ErlDrvPort port = (ErlDrvPort)driver_data;
+
+ /* Create a new event to select on */
+ ErlDrvOseEvent evt = erl_drv_ose_event_alloc(1234,port,resolver);
+
+ /* Make sure to do the select call _BEFORE_ the signal arrives.
+ The signal might get lost if the hunt call is done before the
+ select. */
+ driver_select(port,evt,ERL_DRV_READ|ERL_DRV_USE,1);
+
+ union SIGNAL *sig = alloc(sizeof(union SIGNAL),1234);
+ sig->huntsig.port = port;
+ hunt("testprocess",0,NULL,&sig);
+ return 0;
+}
+
+static void ready_input(ErlDrvData driver_data, ErlDrvEvent evt) {
+ /* Get the first signal payload from the event */
+ union SIGNAL *sig = erl_drv_ose_get_signal(evt);
+ ErlDrvPort port = (ErlDrvPort)driver_data;
+ while (sig != NULL) {
+ if (sig->signo == 1234) {
+ /* If it is our signal we send a message with the sender of the signal
+ to the controlling erlang process */
+ ErlDrvTermData reply[] = { ERL_DRV_UINT, (ErlDrvUInt)sender(&sig) };
+ erl_drv_send_term(port,reply,sizeof(reply) / sizeof(reply[0]));
+ }
+
+ /* Cleanup the signal and deselect on the event.
+ Note that the event itself has to be free'd in the stop_select
+ callback. */
+ free_buf(&sig);
+ driver_select(port,evt,ERL_DRV_READ|ERL_DRV_USE,0);
+
+ /* There could be more than one signal waiting in this event, so
+ we have to loop until sig == NULL */
+ sig = erl_drv_ose_get_signal(evt);
+ }
+}
+
+static void stop_select(ErlDrvEvent event, void *reserved)
+{
+ erl_drv_ose_event_free(event);
+}
+
+/**
+ * Setup the driver entry for the Erlang runtime
+ **/
+ErlDrvEntry ose_signal_driver_entry = {
+ .init = drv_init,
+ .start = drv_start,
+ .stop = drv_stop,
+ .ready_input = ready_input,
+ .driver_name = DRIVER_NAME,
+ .control = control,
+ .extended_marker = ERL_DRV_EXTENDED_MARKER,
+ .major_version = ERL_DRV_EXTENDED_MAJOR_VERSION,
+ .minor_version = ERL_DRV_EXTENDED_MINOR_VERSION,
+ .driver_flags = ERL_DRV_FLAG_USE_PORT_LOCKING,
+ .stop_select = stop_select
+};
+
+
+
+
diff --git a/lib/ose/doc/src/part.xml b/lib/ose/doc/src/part.xml
new file mode 100644
index 0000000000..250bb11f96
--- /dev/null
+++ b/lib/ose/doc/src/part.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+ 2014
+ 2014
+ Ericsson AB, All Rights Reserved
+
+
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ The Initial Developer of the Original Code is Ericsson AB.
+
+
+ OSE User's Guide
+ Lukas Larsson
+
+ 2014-01-08
+ 1.0
+ part.xml
+
+
+ OSE.
+
+
+
+
diff --git a/lib/ose/doc/src/ref_man.xml b/lib/ose/doc/src/ref_man.xml
new file mode 100644
index 0000000000..54c1182fcb
--- /dev/null
+++ b/lib/ose/doc/src/ref_man.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+ 20142014
+ Ericsson AB. All Rights Reserved.
+
+
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+
+
+ OSE Reference Manual
+ Lukas Larsson
+
+ 2014-01-08
+ 1.0
+ ref_man.xml
+
+
+ The Standard Erlang Libraries application, STDLIB,
+ contains modules for manipulating lists, strings and files etc.
+
+
+
+
+
+
diff --git a/lib/ose/ebin/.gitignore b/lib/ose/ebin/.gitignore
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/lib/ose/include/.gitignore b/lib/ose/include/.gitignore
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/lib/ose/info b/lib/ose/info
new file mode 100644
index 0000000000..85c07dbe82
--- /dev/null
+++ b/lib/ose/info
@@ -0,0 +1,2 @@
+group: misc Miscellaneous Applications
+short: Description of Enea OSE specific functionality
diff --git a/lib/ose/src/Makefile b/lib/ose/src/Makefile
new file mode 100644
index 0000000000..88f89578fb
--- /dev/null
+++ b/lib/ose/src/Makefile
@@ -0,0 +1,106 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 1996-2013. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+
+include $(ERL_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+# ----------------------------------------------------
+# Application version
+# ----------------------------------------------------
+include ../vsn.mk
+VSN=$(OSE_VSN)
+
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/lib/ose-$(VSN)
+
+# ----------------------------------------------------
+# Target Specs
+# ----------------------------------------------------
+MODULES= \
+ ose
+
+HRL_FILES=
+
+INTERNAL_HRL_FILES=
+
+ERL_FILES= $(MODULES:%=%.erl)
+
+TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR)) $(APP_TARGET) $(APPUP_TARGET)
+
+APP_FILE= ose.app
+
+APP_SRC= $(APP_FILE).src
+APP_TARGET= $(EBIN)/$(APP_FILE)
+
+APPUP_FILE= ose.appup
+
+APPUP_SRC= $(APPUP_FILE).src
+APPUP_TARGET= $(EBIN)/$(APPUP_FILE)
+
+# ----------------------------------------------------
+# FLAGS
+# ----------------------------------------------------
+
+ifeq ($(NATIVE_LIBS_ENABLED),yes)
+ERL_COMPILE_FLAGS += +native
+endif
+ERL_COMPILE_FLAGS += -I../include -I../../kernel/include -Werror
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+
+debug opt: $(TARGET_FILES)
+
+clean:
+ rm -f $(TARGET_FILES)
+ rm -f core
+ rm -f erl_parse.erl
+
+docs:
+
+# ----------------------------------------------------
+# Special Build Targets
+# ----------------------------------------------------
+
+$(APP_TARGET): $(APP_SRC) ../vsn.mk
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
+
+$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk
+ $(vsn_verbose)sed -e 's;%VSN%;$(VSN);' $< > $@
+
+# ----------------------------------------------------
+# Release Target
+# ----------------------------------------------------
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+release_spec: opt
+ $(INSTALL_DIR) "$(RELSYSDIR)/src"
+ $(INSTALL_DATA) $(ERL_FILES) "$(RELSYSDIR)/src"
+ $(INSTALL_DIR) "$(RELSYSDIR)/include"
+ $(INSTALL_DIR) "$(RELSYSDIR)/ebin"
+ $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin"
+
+release_docs_spec:
+
+# ----------------------------------------------------
+# Dependencies -- alphabetically, please
+# ----------------------------------------------------
diff --git a/lib/ose/src/ose.app.src b/lib/ose/src/ose.app.src
new file mode 100644
index 0000000000..c39d3f2d05
--- /dev/null
+++ b/lib/ose/src/ose.app.src
@@ -0,0 +1,26 @@
+%% This is an -*- erlang -*- file.
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+{application, ose,
+ [{description, "Enea OSE specific modules"},
+ {vsn, "%VSN%"},
+ {modules, [ose]},
+ {registered,[]},
+ {applications, [stdlib,kernel]},
+ {env, []}]}.
diff --git a/lib/ose/src/ose.appup.src b/lib/ose/src/ose.appup.src
new file mode 100644
index 0000000000..6654efde16
--- /dev/null
+++ b/lib/ose/src/ose.appup.src
@@ -0,0 +1,22 @@
+%% -*- erlang -*-
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-2013. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+{"%VSN%",
+ [
+ ],
+ [
+ ]}.
diff --git a/lib/ose/src/ose.erl b/lib/ose/src/ose.erl
new file mode 100644
index 0000000000..ff7147233f
--- /dev/null
+++ b/lib/ose/src/ose.erl
@@ -0,0 +1,452 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2013. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+%% @doc Interface module for OSE messaging and process monitoring from Erlang
+%%
+%% For each mailbox created through {@link open/1} a OSE phantom process with
+%% that name is started. Since phantom processes are used the memory footprint
+%% of each mailbox is quite small.
+%%
+%% To receive messages you first have to subscribe to the specific message
+%% numbers that you are interested in with {@link listen/2}. The messages
+%% will be sent to the Erlang process that created the mailbox.
+%%
+%% @end
+%%
+-module(ose).
+
+%%==============================================================================
+%% Exported API
+%%==============================================================================
+-export([open/1,
+ close/1,
+ get_id/1,
+ get_name/2,
+ hunt/2,
+ dehunt/2,
+ attach/2,
+ detach/2,
+ send/4,
+ send/5,
+ listen/2
+ ]).
+
+%%==============================================================================
+%% Types
+%%==============================================================================
+-opaque mailbox() :: port().
+%% Mailbox handle. Implemented as an erlang port.
+
+-opaque mailbox_id() :: integer().
+%% Mailbox ID, this is the same as the process id of an OSE process.
+%% An integer.
+
+-type message_number() :: 0..4294967295.
+%% OSE Signal number
+
+-opaque hunt_ref() :: {mailbox(),integer()}.
+%% Reference from a hunt request. This term will be included
+%% in a successful hunt response.
+
+-opaque attach_ref() :: {mailbox(),integer()}.
+%% Reference from an attach request. This term will be included
+%% in the term returned when the attached mailbox disappears.
+
+-export_type([mailbox_id/0,
+ message_number/0,
+ mailbox/0,
+ hunt_ref/0,
+ attach_ref/0]).
+
+%%==============================================================================
+%% Defines
+%%==============================================================================
+-define(DRIVER_NAME, "ose_signal_drv").
+-define(GET_SPID, 1).
+-define(GET_NAME, 2).
+-define(HUNT, 100).
+-define(DEHUNT, 101).
+-define(ATTACH, 102).
+-define(DETACH, 103).
+-define(SEND, 104).
+-define(SEND_W_S, 105).
+-define(LISTEN, 106).
+-define(OPEN, 200).
+
+-define(INT_32BIT(Int),(is_integer(Int) andalso (Int >= 0) andalso (Int < (1 bsl 32)))).
+
+%%==============================================================================
+%% API functions
+%%==============================================================================
+
+%%------------------------------------------------------------------------------
+%% @doc Create a mailbox with the given name and return a port that handles
+%% the mailbox.
+%%
+%% An OSE phantom process with the given name will be created that will send any
+%% messages sent through this mailbox. Any messages sent to the new OSE process
+%% will automatically be converted to an Erlang message and sent to the Erlang
+%% process that calls this function. See {@link listen/2} for details about the
+%% format of the message sent.
+%%
+%% The caller gets linked to the created mailbox.
+%%
+%% raises: `badarg' | `system_limit'
+%%
+%% @see liten/2
+%% @end
+%%------------------------------------------------------------------------------
+-spec open(Name) -> Port when
+ Name :: iodata(),
+ Port :: mailbox().
+open(Name) ->
+ try open_port({spawn_driver,?DRIVER_NAME}, [binary]) of
+ Port ->
+ try port_command(Port,[?OPEN,Name]) of
+ true ->
+ receive
+ {ose_drv_reply,Port,{error,Error}} ->
+ close(Port),
+ erlang:error(Error,[Name]);
+ {ose_drv_reply,Port,ok} ->
+ Port
+ end
+ catch
+ error:badarg -> close(Port),erlang:error(badarg,[Name])
+ end
+ catch
+ error:badarg -> erlang:error(badarg,[Name])
+ end.
+
+%%------------------------------------------------------------------------------
+%% @doc Close a mailbox
+%%
+%% This kills the OSE phantom process associated with this mailbox.
+%%
+%% Will also consume any ``{'EXIT',Port,_}'' message from the port that comes
+%% due to the port closing when the calling process traps exits.
+%%
+%% raises: `badarg'
+%% @end
+%%------------------------------------------------------------------------------
+-spec close(Port) -> ok when
+ Port :: mailbox().
+close(Port) when is_port(Port) ->
+ %% Copied from prim_inet
+ case erlang:process_info(self(), trap_exit) of
+ {trap_exit,true} ->
+ link(Port),
+ catch erlang:port_close(Port),
+ receive {'EXIT',Port,_} -> ok end;
+ {trap_exit,false} ->
+ catch erlang:port_close(Port),
+ ok
+ end;
+close(NotPort) ->
+ erlang:error(badarg,[NotPort]).
+
+%%------------------------------------------------------------------------------
+%% @doc Get the mailbox id for the given port.
+%%
+%% The mailbox id is the same as the OSE process id of the OSE phantom process
+%% that this mailbox represents.
+%%
+%% raises: `badarg'
+%% @end
+%%------------------------------------------------------------------------------
+-spec get_id(Port) -> Pid when
+ Port :: mailbox(),
+ Pid :: mailbox_id().
+get_id(Port) ->
+ try port_control(Port, ?GET_SPID, <<>>) of
+ <> -> Spid
+ catch error:_Error ->
+ erlang:error(badarg,[Port])
+ end.
+
+%%------------------------------------------------------------------------------
+%% @doc Get the mailbox name for the given mailbox id.
+%%
+%% The mailbox name is the name of the OSE process with process id Pid.
+%%
+%% This call will fail with badarg if the underlying system does not support
+%% getting the name from a process id.
+%%
+%% raises: `badarg'
+%% @end
+%%------------------------------------------------------------------------------
+-spec get_name(Port, Pid) -> Name | undefined when
+ Port :: mailbox(),
+ Pid :: mailbox_id(),
+ Name :: binary().
+get_name(Port, Pid) when ?INT_32BIT(Pid) ->
+ try port_control(Port, ?GET_NAME, <>) of
+ [] -> undefined;
+ Res -> Res
+ catch error:_Error ->
+ erlang:error(badarg,[Port,Pid])
+ end;
+get_name(Port, Pid) ->
+ erlang:error(badarg,[Port,Pid]).
+
+
+%%------------------------------------------------------------------------------
+%% @doc Hunt for OSE process by name.
+%%
+%% Will send `{mailbox_up, Port, Ref, MboxId}'
+%% to the calling process when the OSE process becomes available.
+%%
+%% Returns a reference term that can be used to cancel the hunt
+%% using {@link dehunt/2}.
+%%
+%% raises: `badarg'
+%%
+%% @end
+%%------------------------------------------------------------------------------
+-spec hunt(Port, HuntPath) -> Ref when
+ Port :: mailbox(),
+ HuntPath :: iodata(),
+ Ref :: hunt_ref().
+hunt(Port, HuntPath) ->
+ try port_command(Port, [?HUNT,HuntPath]) of
+ true ->
+ receive
+ {ose_drv_reply,Port,{error,Error}} ->
+ erlang:error(Error,[Port,HuntPath]);
+ {ose_drv_reply,Port,Ref} ->
+ Ref
+ end
+ catch error:_Error ->
+ erlang:error(badarg,[Port,HuntPath])
+ end.
+
+%%------------------------------------------------------------------------------
+%% @doc Stop hunting for OSE process.
+%%
+%% If a message for this hunt has been sent but not received
+%% by the calling process, it is removed from the message queue.
+%% Note that this only works if the same process that did
+%% the hunt does the dehunt.
+%%
+%% raises: `badarg'
+%%
+%% @see hunt/2
+%% @end
+%%------------------------------------------------------------------------------
+-spec dehunt(Port, Ref) -> ok when
+ Port :: mailbox(),
+ Ref :: hunt_ref().
+dehunt(Port, {Port,Ref}) when ?INT_32BIT(Ref) ->
+ try port_command(Port, <>) of
+ true ->
+ receive
+ {ose_drv_reply,Port,{error,enoent}} ->
+ %% enoent could mean that it is in the message queue
+ receive
+ {mailbox_up, Port, {Port,Ref}, _} ->
+ ok
+ after 0 ->
+ ok
+ end;
+ {ose_drv_reply,Port,ok} ->
+ ok
+ end
+ catch error:_Error ->
+ erlang:error(badarg,[Port,{Port,Ref}])
+ end;
+dehunt(Port,Ref) ->
+ erlang:error(badarg,[Port,Ref]).
+
+%%------------------------------------------------------------------------------
+%% @doc Attach to an OSE process.
+%%
+%% Will send `{mailbox_down, Port, Ref, MboxId}'
+%% to the calling process if the OSE process exits.
+%%
+%% Returns a reference that can be used to cancel the attachment
+%% using {@link detach/2}.
+%%
+%% raises: `badarg' | `enomem'
+%%
+%% @end
+%%------------------------------------------------------------------------------
+-spec attach(Port,Pid) -> Ref when
+ Port :: mailbox(),
+ Pid :: mailbox_id(),
+ Ref :: attach_ref().
+attach(Port, Spid) when ?INT_32BIT(Spid) ->
+ try port_command(Port, <>) of
+ true ->
+ receive
+ {ose_drv_reply,Port,{error,Error}} ->
+ erlang:error(Error,[Port,Spid]);
+ {ose_drv_reply,Port,Ref} ->
+ Ref
+ end
+ catch error:_Error ->
+ erlang:error(badarg,[Port,Spid])
+ end;
+attach(Port,Spid) ->
+ erlang:error(badarg,[Port,Spid]).
+
+
+%%------------------------------------------------------------------------------
+%% @doc Remove attachment to an OSE process.
+%%
+%% If a message for this monitor has been sent but not received
+%% by the calling process, it is removed from the message queue.
+%% Note that this only works of the same process
+%% that did the attach does the detach.
+%%
+%% raises: `badarg'
+%%
+%% @see attach/2
+%% @end
+%%------------------------------------------------------------------------------
+-spec detach(Port,Ref) -> ok when
+ Port :: mailbox(),
+ Ref :: attach_ref().
+detach(Port, {Port,Ref} ) when ?INT_32BIT(Ref) ->
+ try port_command(Port, <>) of
+ true ->
+ receive
+ {ose_drv_reply,Port,{error,enoent}} ->
+ %% enoent could mean that it is in the message queue
+ receive
+ {mailbox_down,Port,{Port,Ref},_} ->
+ ok
+ after 0 ->
+ ok
+ end;
+ {ose_drv_reply,Port,ok} ->
+ ok
+ end
+ catch error:_Error ->
+ erlang:error(badarg,[Port,{Port,Ref}])
+ end;
+detach(Port,Ref) ->
+ erlang:error(badarg,[Port,Ref]).
+
+%%------------------------------------------------------------------------------
+%% @doc Send an OSE message.
+%%
+%% The message is sent from the OSE process' own ID that is: `get_id(Port)'.
+%%
+%% raises: `badarg'
+%%
+%% @see send/5
+%% @end
+%%------------------------------------------------------------------------------
+-spec send(Port,Pid,SigNo,SigData) -> ok when
+ Port :: mailbox(),
+ Pid :: mailbox_id(),
+ SigNo :: message_number(),
+ SigData :: iodata().
+send(Port, Spid, SigNo, SigData) when ?INT_32BIT(Spid), ?INT_32BIT(SigNo) ->
+ try erlang:port_command(Port, [<>, SigData]) of
+ true -> ok
+ catch error:_Error ->
+ erlang:error(badarg,[Port,Spid,SigNo,SigData])
+ end;
+send(Port,Spid,SigNo,SigData) ->
+ erlang:error(badarg,[Port,Spid,SigNo,SigData]).
+
+
+%%------------------------------------------------------------------------------
+%% @doc Send an OSE message with different sender.
+%%
+%% As {@link send/4} but the sender will be `SenderPid'.
+%%
+%% raises: `badarg'
+%%
+%% @see send/4
+%% @end
+%%------------------------------------------------------------------------------
+-spec send(Port,Pid,SenderPid,SigNo,SigData) -> ok when
+ Port :: mailbox(),
+ Pid :: mailbox_id(),
+ SenderPid :: mailbox_id(),
+ SigNo :: message_number(),
+ SigData :: iodata().
+send(Port, Spid, SenderPid, SigNo, SigData)
+ when ?INT_32BIT(Spid), ?INT_32BIT(SenderPid), ?INT_32BIT(SigNo) ->
+ try erlang:port_command(Port, [<>, SigData]) of
+ true -> ok
+ catch error:_Error ->
+ erlang:error(badarg,[Port,Spid,SenderPid,SigNo,SigData])
+ end;
+send(Port,Spid,SenderPid,SigNo,SigData) ->
+ erlang:error(badarg,[Port,Spid,SenderPid,SigNo,SigData]).
+
+%%------------------------------------------------------------------------------
+%% @doc Start listening for specified OSE signal numbers.
+%%
+%% The mailbox will send `{message,Port,{FromMboxId,ToMboxId,MsgNo,MsgData}}'
+%% to the process that created the mailbox when an OSE message with any
+%% of the specified `SigNos' arrives.
+%%
+%% Repeated calls to listen will replace the current set of signal numbers to
+%% listen to. i.e
+%%
+%% ```1>ose:listen(MsgB,[1234,12345]).
+%% ok
+%% 2> ose:listen(MsgB,[1234,123456]).
+%% ok.'''
+%%
+%% The above will first listen for signals with numbers 1234 and 12345, and then
+%% replace that with only listening to 1234 and 123456.
+%%
+%% With the current implementation it is not possible to listen to all signal
+%% numbers.
+%%
+%% raises: `badarg' | `enomem'
+%%
+%% @end
+%%------------------------------------------------------------------------------
+-spec listen(Port, SigNos) -> ok when
+ Port :: mailbox(),
+ SigNos :: list(message_number()).
+listen(Port, SigNos) when is_list(SigNos) ->
+ USSigNos = lists:usort(SigNos),
+ BinSigNos = try
+ << <> ||
+ SigNo <- USSigNos,
+ ?INT_32BIT(SigNo) orelse erlang:error(badarg)
+ >>
+ catch _:_ ->
+ erlang:error(badarg,[Port,SigNos])
+ end,
+ try port_command(Port, [?LISTEN, BinSigNos]) of
+ true ->
+ receive
+ {ose_drv_reply,Port,{error,Error}} ->
+ erlang:error(Error,[Port,SigNos]);
+ {ose_drv_reply,Port,Else} ->
+ Else
+ end
+ catch error:_Error ->
+ erlang:error(badarg,[Port,SigNos])
+ end;
+listen(Port, SigNos) ->
+ erlang:error(badarg,[Port,SigNos]).
+
+
+%%%=============================================================================
+%%% Internal functions
+%%%=============================================================================
diff --git a/lib/ose/test/Makefile b/lib/ose/test/Makefile
new file mode 100644
index 0000000000..7e2080ba38
--- /dev/null
+++ b/lib/ose/test/Makefile
@@ -0,0 +1,67 @@
+include $(ERL_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+# ----------------------------------------------------
+# Target Specs
+# ----------------------------------------------------
+
+MODULES= \
+ ose_SUITE
+
+ERL_FILES= $(MODULES:%=%.erl)
+
+TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+
+INSTALL_PROGS= $(TARGET_FILES)
+
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/ose_test
+
+# ----------------------------------------------------
+# FLAGS
+# ----------------------------------------------------
+
+ERL_MAKE_FLAGS +=
+ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/test_server/include \
+ -I$(ERL_TOP)/lib/kernel/include
+
+EBIN = .
+
+EMAKEFILE=Emakefile
+COVERFILE=ose.cover
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+
+make_emakefile:
+ $(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) $(MODULES) \
+ > $(EMAKEFILE)
+
+tests debug opt: make_emakefile
+ erl $(ERL_MAKE_FLAGS) -make
+
+clean:
+ rm -f $(EMAKEFILE)
+ rm -f $(TARGET_FILES)
+ rm -f core
+
+docs:
+
+# ----------------------------------------------------
+# Release Target
+# ----------------------------------------------------
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+release_spec: opt
+
+release_tests_spec: make_emakefile
+ $(INSTALL_DIR) "$(RELSYSDIR)"
+ $(INSTALL_DATA) ose.spec $(EMAKEFILE) \
+ $(ERL_FILES) $(COVERFILE) "$(RELSYSDIR)"
+ chmod -R u+w "$(RELSYSDIR)"
+ @tar cf - *_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -)
+
+release_docs_spec:
diff --git a/lib/ose/test/ose.cover b/lib/ose/test/ose.cover
new file mode 100644
index 0000000000..7b846cfaf6
--- /dev/null
+++ b/lib/ose/test/ose.cover
@@ -0,0 +1,2 @@
+%% -*- erlang -*-
+{incl_app,ose,details}.
diff --git a/lib/ose/test/ose.spec b/lib/ose/test/ose.spec
new file mode 100644
index 0000000000..c897e8cd16
--- /dev/null
+++ b/lib/ose/test/ose.spec
@@ -0,0 +1 @@
+{suites,"../ose_test",all}.
diff --git a/lib/ose/test/ose_SUITE.erl b/lib/ose/test/ose_SUITE.erl
new file mode 100644
index 0000000000..7e81b19894
--- /dev/null
+++ b/lib/ose/test/ose_SUITE.erl
@@ -0,0 +1,765 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1998-2013. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+-module(ose_SUITE).
+
+%-compile(export_all).
+
+-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
+ init_per_group/2,end_per_group/2,init_per_testcase/2,
+ end_per_testcase/2]).
+-export([
+ basic/1,stress/1,multi_msg_numbers/1,multi_mailboxes/1,
+ hunt/1,multi_hunt/1,dehunt/1,multi_dehunt/1,
+ attach/1,multi_attach/1,detach/1,multi_detach/1,
+ open_errors/1,close_errors/1,get_id_errors/1,get_name_errors/1,
+ hunt_errors/1,dehunt_errors/1,attach_errors/1,detach_errors/1,
+ send_errors/1,send_w_s_errors/1,listen_errors/1
+ ]).
+
+-define(INTERFACE,ose).
+
+
+init_per_testcase(_Func, Config) ->
+ Config.
+end_per_testcase(_Func, _Config) ->
+ ok.
+
+suite() -> [{timeout,{30,seconds}}].
+
+all() ->
+ [
+ basic,stress,multi_msg_numbers,multi_mailboxes,
+ hunt,multi_hunt,dehunt,multi_dehunt,
+ attach,multi_attach,detach,multi_detach,
+
+ open_errors,close_errors,get_id_errors,get_name_errors,
+ hunt_errors,dehunt_errors,attach_errors,detach_errors,
+ send_errors,send_w_s_errors,listen_errors
+ ].
+
+groups() ->
+ [].
+
+init_per_suite(Config) ->
+ case os:type() of
+ {ose,_} ->
+ Config;
+ _Else ->
+ {skip,"Only run on OSE"}
+ end.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_group(_GroupName, Config) ->
+ Config.
+
+end_per_group(_GroupName, Config) ->
+ Config.
+
+basic(_Config) ->
+
+ [P1,P2] = multi_open(2,[42]),
+ P1Id = ?INTERFACE:get_id(P1),
+ P2Id = ?INTERFACE:get_id(P2),
+
+ ok = ?INTERFACE:send(P2,P1Id,42,<<"ping">>),
+ receive
+ {message,P1,V1} ->
+ {P2Id,P1Id,42,<<"ping">>} = V1,
+ ?INTERFACE:send(P1,P2Id,42,<<"pong">>);
+ Else1 ->
+ ct:fail({got_wrong_message,Else1})
+ end,
+
+ receive
+ {message,P2,V2} ->
+ {P1Id,P2Id,42,<<"pong">>} = V2;
+ Else2 ->
+ ct:fail({got_wrong_message,Else2})
+ end,
+
+ ?INTERFACE:close(P1),
+ ?INTERFACE:close(P2).
+
+%% Send 1000 messages and see if we can cope and that msg order is preserved
+stress(_Config) ->
+
+ Iterations = 1000,
+
+ [P1,P2] = multi_open(2,[42]),
+ P1Id = ?INTERFACE:get_id(P1),
+ P2Id = ?INTERFACE:get_id(P2),
+
+ spawn(fun() ->
+ n(fun(N) ->
+ Msg = [<<"ping">>|integer_to_list(N)],
+ ?INTERFACE:send(P2,P1Id,42,Msg)
+ end,Iterations)
+ end),
+ timer:sleep(100),
+ n(fun(N) ->
+ receive
+ {message,P1,Value} ->
+ Int = integer_to_binary(N),
+ {P2Id,P1Id,42,<<"ping",Int/binary>>} = Value,
+ ok;
+ Else ->
+ ct:fail({got_wrong_message,Else})
+ end
+ end,Iterations),
+
+ ?INTERFACE:close(P1),
+ ?INTERFACE:close(P2).
+
+%% Listen to 1000 different message numbers and send some random messages
+multi_msg_numbers(_Config) ->
+
+ Iterations = 100,
+
+ [P1,P2] = multi_open(2,lists:seq(2000,3000)),
+ P1Id = ?INTERFACE:get_id(P1),
+
+ n(fun(_) ->
+ Num = random:uniform(1000)+2000,
+ ?INTERFACE:send(P2,P1Id,Num,<<"ping",(integer_to_binary(Num))/binary>>)
+ end,Iterations),
+
+ n(fun(_) ->
+ receive
+ {message,P1,{_,_,Id,<<"ping",Num/binary>>}} when Id > 2000;
+ Id =< 3000 ->
+ Id = binary_to_integer(Num),
+ ok;
+ Else ->
+ ct:fail({got_wrong_message,Else})
+ end
+ end,Iterations),
+
+ ?INTERFACE:close(P1),
+ ?INTERFACE:close(P2).
+
+
+%% Create 100 mailboxes and send messages to them
+multi_mailboxes(_Config) ->
+
+ Mailboxes = 100,
+
+ [P1|MBs] = multi_open(Mailboxes,[42]),
+
+ [?INTERFACE:send(P1,?INTERFACE:get_id(P),42,[<<"ping">>,?INTERFACE:get_name(P,?INTERFACE:get_id(P))]) || P <- MBs],
+
+ [receive
+ {message,P,Value} ->
+ Name = ?INTERFACE:get_name(P,?INTERFACE:get_id(P)),
+ {_,_,42,<<"ping",Name/binary>>} = Value,
+ ok
+ end || P <- MBs],
+
+ [?INTERFACE:close(P) || P <- [P1|MBs]],
+ ok.
+
+hunt(_Config) ->
+ [P1,P2] = multi_open(2,[]),
+
+ Ref = ?INTERFACE:hunt(P1,"p2"),
+ receive
+ {mailbox_up,P1,Ref,Pid} ->
+ Pid = ?INTERFACE:get_id(P2),
+ ?INTERFACE:close(P1),
+ ?INTERFACE:close(P2);
+ Else ->
+ ct:fail({got_wrong_message,Else,Ref})
+ end.
+
+multi_hunt(_Config) ->
+
+ Iterations = 100,
+
+ P = ?INTERFACE:open("p"),
+
+ Refs = [?INTERFACE:hunt(P,"p"++integer_to_list(N))|| N <- lists:seq(1,Iterations)],
+
+ Pids = [begin
+ Prt = ?INTERFACE:open("p"++integer_to_list(N)),
+ Pid = ?INTERFACE:get_id(Prt),
+ ?INTERFACE:close(Prt),
+ Pid
+ end || N <- lists:seq(1,Iterations)],
+
+ [receive
+ {mailbox_up,P,Ref,Pid} ->
+ ok
+ after 10 ->
+ ct:fail({did_not_get,Pid,Ref})
+ end || {Pid,Ref} <- lists:zip(Pids,Refs)],
+ ?INTERFACE:close(P).
+
+
+dehunt(_Config) ->
+ [P1] = multi_open(1,[]),
+ Ref = ?INTERFACE:hunt(P1,"p2"),
+ receive
+ _Else -> ct:fail({got,_Else})
+ after 1000 ->
+ ok
+ end,
+ P2 = ?INTERFACE:open("p2"),
+
+ % Make sure any messages are sent
+ receive after 10 -> ok end,
+
+ ok = ?INTERFACE:dehunt(P1,Ref),
+
+ % Make sure no messages are received
+ receive
+ _Else2 -> ct:fail({got,_Else2})
+ after 1000 ->
+ ?INTERFACE:close(P1),
+ ?INTERFACE:close(P2)
+ end.
+
+%%%
+%%% This testcase basically:
+%%% spawn 10 processes that in parallel
+%%% adds some hunts for different OSE processes
+%%% maybe create hunted OSE process
+%%% dehunt half of the hunts
+%%% create more hunts
+%%% if not created create hunted OSE process
+%%% veryify that all expected hunt messages are received
+%%% verify that all processes exited correctly
+%%%
+%%% This complex test is done to make sure that the internal handling
+%%% of dehunt works as expected.
+%%%
+multi_dehunt(_Config) ->
+ [P1] = multi_open(1,[]),
+
+ Scenario =
+ fun(Iterations) ->
+
+ Hunted = "p"++integer_to_list(Iterations),
+ %% Start a couple of hunts
+ Refs = [?INTERFACE:hunt(P1,Hunted) || _ <- lists:seq(1,Iterations)],
+
+ %% We alternate if the process is opened before or after the dehunt
+ P2O = if Iterations rem 2 == 0 ->
+ ?INTERFACE:open(Hunted);
+ true ->
+ undefined
+ end,
+
+ %% Remove half of them
+ {RemRefs,_} = lists:mapfoldl(fun(Ref,Acc) when Acc rem 2 == 0 ->
+ ok = ?INTERFACE:dehunt(P1,Ref),
+ {[],Acc+1};
+ (Ref,Acc) ->
+ {Ref,Acc+1}
+ end,0,Refs),
+
+ %% Add some new ones
+ NewRefs = [?INTERFACE:hunt(P1,Hunted)
+ || _ <- lists:seq(1,Iterations div 4)]
+ ++ lists:flatten(RemRefs),
+
+ P2 = if P2O == undefined ->
+ ?INTERFACE:open(Hunted);
+ true ->
+ P2O
+ end,
+ P2Id = ?INTERFACE:get_id(P2),
+
+ %% Receive all the expected ones
+ lists:foreach(fun(Ref) ->
+ receive
+ {mailbox_up,P1,Ref,P2Id} ->
+ ok
+ after 1000 ->
+ io:format("Flush: ~p~n",[flush()]),
+ io:format("~p~n",[{Iterations,{did_not_get, Ref}}]),
+ ok = Ref
+ end
+ end,NewRefs),
+
+ %% Check that no other have arrived
+ receive
+ _Else ->
+ io:format("Flush: ~p~n",[flush()]),
+ io:format("~p~n",[{Iterations,{got, _Else}}]),
+ ok = _Else
+ after 100 ->
+ ok
+ end,
+ ?INTERFACE:close(P2)
+ end,
+
+ Self = self(),
+
+ n(fun(N) ->
+ spawn(fun() -> Self !
+ Scenario(N*25)
+ end),
+ ok
+ end,10),
+
+ n(fun(_N) ->
+ receive ok -> ok
+ after 60000 -> ct:fail(failed)
+ end
+ end,10),
+ ?INTERFACE:close(P1).
+
+attach(_Config) ->
+ [P1,P2] = multi_open(2,[]),
+
+ P2Id = ?INTERFACE:get_id(P2),
+ Ref = ?INTERFACE:attach(P1,P2Id),
+ ?INTERFACE:close(P2),
+ receive
+ {mailbox_down,P1,Ref,P2Id} ->
+ ?INTERFACE:close(P1);
+ _Else ->
+ ct:fail({got,_Else, {P1,Ref,P2Id}})
+ after 1000 ->
+ ct:fail({did_not_get,P1,Ref,P2Id})
+ end.
+
+multi_attach(_Config) ->
+
+ Iterations = 100,
+
+ [P1|Pids] = multi_open(Iterations,[]),
+
+ Refs = [{?INTERFACE:get_id(Pid),?INTERFACE:attach(P1,?INTERFACE:get_id(Pid))} || Pid <- Pids],
+
+ [?INTERFACE:close(Pid) || Pid <- Pids],
+
+ [receive
+ {mailbox_down,P1,Ref,Pid} ->
+ ok
+ after 10000 ->
+ ct:fail({did_not_get,Pid,Ref})
+ end || {Pid,Ref} <- Refs],
+ ?INTERFACE:close(P1).
+
+detach(_Config) ->
+ [P1,P2] = multi_open(2,[]),
+ P2Id = ?INTERFACE:get_id(P2),
+ Ref = ?INTERFACE:attach(P1,P2Id),
+ receive
+ _Else -> ct:fail({got,_Else})
+ after 100 ->
+ ok
+ end,
+
+ ?INTERFACE:close(P2),
+
+ % Make sure any messages are sent
+ receive after 10 -> ok end,
+
+ ?INTERFACE:detach(P1,Ref),
+
+ % Make sure no messages are received
+ receive
+ _Else2 -> ct:fail({got,_Else2})
+ after 1000 ->
+ ?INTERFACE:close(P1)
+ end.
+
+%%%
+%%% This testcase basically:
+%%% spawn 10 processes that in parallel
+%%% adds some attach for different OSE processes
+%%% maybe close OSE process
+%%% dehunt half of the hunts
+%%% create more hunts
+%%% if not closed close attached OSE process
+%%% veryify that all expected attach messages are received
+%%% verify that all processes exited correctly
+%%%
+%%% This complex test is done to make sure that the internal handling
+%%% of dehunt works as expected.
+%%%
+multi_detach(_Config) ->
+ [P1] = multi_open(1,[]),
+
+ Scenario =
+ fun(Iterations) ->
+
+ Attached = ?INTERFACE:open("p"++integer_to_list(Iterations)),
+ AttachedId = ?INTERFACE:get_id(Attached),
+ %% Start a couple of attachs
+ Refs = [?INTERFACE:attach(P1,AttachedId) || _ <- lists:seq(1,Iterations)],
+
+ %% We alternate if the process is closed before or after the detach
+ P2O = if Iterations rem 2 == 0 ->
+ ?INTERFACE:close(Attached);
+ true ->
+ undefined
+ end,
+
+ %% Remove half of them
+ {RemRefs,_} = lists:mapfoldl(fun(Ref,Acc) when Acc rem 2 == 0 ->
+ ok = ?INTERFACE:detach(P1,Ref),
+ {[],Acc+1};
+ (Ref,Acc) ->
+ {Ref,Acc+1}
+ end,0,Refs),
+
+ %% Add some new ones
+ NewRefs = [?INTERFACE:attach(P1,AttachedId)
+ || _ <- lists:seq(1,Iterations div 4)]
+ ++ lists:flatten(RemRefs),
+
+ if P2O == undefined ->
+ ?INTERFACE:close(Attached);
+ true ->
+ P2O
+ end,
+
+ %% Receive all the expected ones
+ lists:foreach(fun(Ref) ->
+ receive
+ {mailbox_down,P1,Ref,AttachedId} ->
+ ok
+ after 1000 ->
+ io:format("Flush: ~p~n",[flush()]),
+ io:format("~p~n",[{Iterations,{did_not_get, Ref}}]),
+ ok = Ref
+ end
+ end,NewRefs),
+
+ %% Check that no other have arrived
+ receive
+ _Else ->
+ io:format("Flush: ~p~n",[flush()]),
+ io:format("~p~n",[{Iterations,{got, _Else}}]),
+ ok = _Else
+ after 100 ->
+ ok
+ end
+ end,
+
+ Self = self(),
+
+ n(fun(N) ->
+ spawn(fun() -> Self !
+ Scenario(N*5)
+ end),
+ ok
+ end,10),
+
+ n(fun(_N) ->
+ receive ok -> ok
+ after 60000 -> ct:fail(failed)
+ end
+ end,10),
+ ?INTERFACE:close(P1).
+
+
+open_errors(_Config) ->
+ {'EXIT',{badarg,[{?INTERFACE,open,[inval],_}|_]}} =
+ (catch ?INTERFACE:open(inval)),
+ {'EXIT',{badarg,[{?INTERFACE,open,[["p"|1]],_}|_]}} =
+ (catch ?INTERFACE:open(["p"|1])),
+ {'EXIT',{badarg,[{?INTERFACE,open,[["p",1234]],_}|_]}} =
+ (catch ?INTERFACE:open(["p",1234])),
+
+ ok.
+
+close_errors(_Config) ->
+ {'EXIT',{badarg,[{?INTERFACE,close,[inval],_}|_]}} =
+ (catch ?INTERFACE:close(inval)),
+
+ P1 = ?INTERFACE:open("p1"),
+ ok = ?INTERFACE:close(P1),
+ ok = ?INTERFACE:close(P1).
+
+
+get_id_errors(_Config) ->
+ {'EXIT',{badarg,[{?INTERFACE,get_id,[inval],_}|_]}} =
+ (catch ?INTERFACE:get_id(inval)),
+
+ P1 = ?INTERFACE:open("p1"),
+ ok = ?INTERFACE:close(P1),
+ {'EXIT',{badarg,[{?INTERFACE,get_id,[P1],_}|_]}} =
+ (catch ?INTERFACE:get_id(P1)),
+
+ ok.
+
+get_name_errors(_Config) ->
+ P1 = ?INTERFACE:open("p1"),
+ {'EXIT',{badarg,[{?INTERFACE,get_name,[P1,inval],_}|_]}} =
+ (catch ?INTERFACE:get_name(P1,inval)),
+
+ undefined = ?INTERFACE:get_name(P1,1234),
+
+ P2 = ?INTERFACE:open("p2"),
+ P2Id = ?INTERFACE:get_id(P2),
+ ok = ?INTERFACE:close(P1),
+ {'EXIT',{badarg,[{?INTERFACE,get_name,[P1,P2Id],_}|_]}} =
+ (catch ?INTERFACE:get_name(P1,P2Id)),
+ ?INTERFACE:close(P2),
+
+ P3 = ?INTERFACE:open([255]),
+ <<255>> = ?INTERFACE:get_name(P3, ?INTERFACE:get_id(P3)),
+ ?INTERFACE:close(P3),
+
+ ok.
+
+hunt_errors(_Config) ->
+
+ {'EXIT',{badarg,[{?INTERFACE,hunt,[inval,"hello"],_}|_]}} =
+ (catch ?INTERFACE:hunt(inval,"hello")),
+
+ P1 = ?INTERFACE:open("p1"),
+ {'EXIT',{badarg,[{?INTERFACE,hunt,[P1,["hello",12345]],_}|_]}} =
+ (catch ?INTERFACE:hunt(P1,["hello",12345])),
+
+ P2 = ?INTERFACE:open(<<255>>),
+ P2Pid = ?INTERFACE:get_id(P2),
+ Ref = ?INTERFACE:hunt(P1,[255]),
+ receive
+ {mailbox_up,P1,Ref,P2Pid} ->
+ ok;
+ Else ->
+ ct:fail({got,Else,{mailbox_up,P1,Ref,P2Pid}})
+ after 150 ->
+ ct:fail({did_not_get,{mailbox_up,P1,Ref,P2Pid}})
+ end,
+
+ ok = ?INTERFACE:close(P1),
+ ok = ?INTERFACE:close(P2),
+ {'EXIT',{badarg,[{?INTERFACE,hunt,[P1,["hello"]],_}|_]}} =
+ (catch ?INTERFACE:hunt(P1,["hello"])),
+
+ ok.
+
+dehunt_errors(_Config) ->
+ P1 = ?INTERFACE:open("p1"),
+ Ref = ?INTERFACE:hunt(P1,"p2"),
+
+ {'EXIT',{badarg,[{?INTERFACE,dehunt,[inval,Ref],_}|_]}} =
+ (catch ?INTERFACE:dehunt(inval,Ref)),
+
+ {'EXIT',{badarg,[{?INTERFACE,dehunt,[P1,inval],_}|_]}} =
+ (catch ?INTERFACE:dehunt(P1,inval)),
+
+ ok = ?INTERFACE:dehunt(P1,Ref),
+ ok = ?INTERFACE:dehunt(P1,Ref),
+
+ ok = ?INTERFACE:close(P1),
+
+ {'EXIT',{badarg,[{?INTERFACE,dehunt,[P1,Ref],_}|_]}} =
+ (catch ?INTERFACE:dehunt(P1,Ref)),
+
+ case ?INTERFACE of
+ ose -> ok;
+ _ ->
+ P2 = ?INTERFACE:open("p2"),
+ ok = ?INTERFACE:close(P2)
+ end,
+
+ receive
+ Else -> ct:fail({got,Else})
+ after 100 ->
+ ok
+ end.
+
+attach_errors(_Config) ->
+ P1 = ?INTERFACE:open("p1"),
+ P2 = ?INTERFACE:open("p2"),
+ P2Id = ?INTERFACE:get_id(P2),
+
+ {'EXIT',{badarg,[{?INTERFACE,attach,[inval,P2Id],_}|_]}} =
+ (catch ?INTERFACE:attach(inval,P2Id)),
+
+ {'EXIT',{badarg,[{?INTERFACE,attach,[P1,[12345]],_}|_]}} =
+ (catch ?INTERFACE:attach(P1,[12345])),
+
+ ok = ?INTERFACE:close(P1),
+ ok = ?INTERFACE:close(P2),
+ {'EXIT',{badarg,[{?INTERFACE,attach,[P1,P2Id],_}|_]}} =
+ (catch ?INTERFACE:attach(P1,P2Id)),
+
+ ok.
+
+detach_errors(_Config) ->
+ P1 = ?INTERFACE:open("p1"),
+ P2 = ?INTERFACE:open("p2"),
+ P2Id = ?INTERFACE:get_id(P2),
+
+ Ref = ?INTERFACE:attach(P1,P2Id),
+
+ {'EXIT',{badarg,[{?INTERFACE,detach,[inval,Ref],_}|_]}} =
+ (catch ?INTERFACE:detach(inval,Ref)),
+
+ {'EXIT',{badarg,[{?INTERFACE,detach,[P1,inval],_}|_]}} =
+ (catch ?INTERFACE:detach(P1,inval)),
+
+ ok = ?INTERFACE:detach(P1,Ref),
+ ok = ?INTERFACE:detach(P1,Ref),
+
+ case ?INTERFACE of
+ ose -> ok;
+ _ ->
+ ok = ?INTERFACE:close(P1)
+ end,
+
+ ok = ?INTERFACE:close(P2),
+ ok = ?INTERFACE:close(P1),
+
+ {'EXIT',{badarg,[{?INTERFACE,detach,[P1,Ref],_}|_]}} =
+ (catch ?INTERFACE:detach(P1,Ref)),
+
+ receive
+ Else -> ct:fail({got,Else})
+ after 100 ->
+ ok
+ end.
+
+send_errors(_Config) ->
+ P1 = ?INTERFACE:open("p1"),
+ P2 = ?INTERFACE:open("p2"),
+ P2Id = ?INTERFACE:get_id(P2),
+
+ {'EXIT',{badarg,[{?INTERFACE,send,[inval,P2Id,42,"hello"],_}|_]}} =
+ (catch ?INTERFACE:send(inval,P2Id,42,"hello")),
+ {'EXIT',{badarg,[{?INTERFACE,send,[P1,inval,42,"hello"],_}|_]}} =
+ (catch ?INTERFACE:send(P1,inval,42,"hello")),
+ {'EXIT',{badarg,[{?INTERFACE,send,[P1,P2Id,inval,"hello"],_}|_]}} =
+ (catch ?INTERFACE:send(P1,P2Id,inval,"hello")),
+ {'EXIT',{badarg,[{?INTERFACE,send,[P1,P2Id,42,inval],_}|_]}} =
+ (catch ?INTERFACE:send(P1,P2Id,42,inval)),
+
+ ok = ?INTERFACE:close(P2),
+ ok = ?INTERFACE:send(P1,P2Id,42,"hello"),
+ ok = ?INTERFACE:close(P1),
+
+ {'EXIT',{badarg,[{?INTERFACE,send,[P1,P2Id,42,"hello"],_}|_]}} =
+ (catch ?INTERFACE:send(P1,P2Id,42,"hello")),
+
+ receive
+ Else -> ct:fail({got,Else})
+ after 100 ->
+ ok
+ end.
+
+send_w_s_errors(_Config) ->
+ P1 = ?INTERFACE:open("p1"),
+ P1Id = ?INTERFACE:get_id(P1),
+ P2 = ?INTERFACE:open("p2"),
+ P2Id = ?INTERFACE:get_id(P2),
+ P3 = ?INTERFACE:open("p3"),
+ P3Id = ?INTERFACE:get_id(P3),
+
+ {'EXIT',{badarg,[{?INTERFACE,send,[inval,P2Id,P1Id,42,"hello"],_}|_]}} =
+ (catch ?INTERFACE:send(inval,P2Id,P1Id,42,"hello")),
+ {'EXIT',{badarg,[{?INTERFACE,send,[P2,-1,P1Id,42,"hello"],_}|_]}} =
+ (catch ?INTERFACE:send(P2,-1,P1Id,42,"hello")),
+ {'EXIT',{badarg,[{?INTERFACE,send,[P2,P2Id,1 bsl 32,42,"hello"],_}|_]}} =
+ (catch ?INTERFACE:send(P2,P2Id,1 bsl 32,42,"hello")),
+ {'EXIT',{badarg,[{?INTERFACE,send,[P2,P2Id,P1Id,inval,"hello"],_}|_]}} =
+ (catch ?INTERFACE:send(P2,P2Id,P1Id,inval,"hello")),
+ {'EXIT',{badarg,[{?INTERFACE,send,[P2,P2Id,P1Id,42,inval],_}|_]}} =
+ (catch ?INTERFACE:send(P2,P2Id,P1Id,42,inval)),
+
+ ok = ?INTERFACE:close(P3),
+ ok = ?INTERFACE:send(P2,P3Id,P1Id,42,"hello"),
+
+ ok = ?INTERFACE:close(P1),
+ ok = ?INTERFACE:send(P2,P2Id,P1Id,42,"hello"),
+ ok = ?INTERFACE:close(P2),
+
+ {'EXIT',{badarg,[{?INTERFACE,send,[P1,P2Id,P1Id,42,"hello"],_}|_]}} =
+ (catch ?INTERFACE:send(P1,P2Id,P1Id,42,"hello")),
+
+ receive
+ Else -> ct:fail({got,Else})
+ after 100 ->
+ ok
+ end.
+
+listen_errors(_Config) ->
+
+ P1 = ?INTERFACE:open("p1"),
+ P1Id = ?INTERFACE:get_id(P1),
+
+ {'EXIT',{badarg,[{?INTERFACE,listen,[inval,[42]],_}|_]}} =
+ (catch ?INTERFACE:listen(inval,[42])),
+ {'EXIT',{badarg,[{?INTERFACE,listen,[P1,inval],_}|_]}} =
+ (catch ?INTERFACE:listen(P1,inval)),
+ {'EXIT',{badarg,[{?INTERFACE,listen,[P1,[1 bsl 33]],_}|_]}} =
+ (catch ?INTERFACE:listen(P1,[1 bsl 33])),
+
+ ok = ?INTERFACE:listen(P1,[42,42,42,42,42,42,42,42,42,42,42,42,42]),
+
+ case ?INTERFACE of
+ ose -> ok;
+ _ ->
+ ?INTERFACE:send(P1,P1Id,42,"hello"),
+ timer:sleep(50),
+ ?INTERFACE:listen(P1,[]),
+ ?INTERFACE:send(P1,P1Id,42,"hello2"),
+
+ receive
+ {message,P1,42,"hello"} -> ok
+ end,
+
+ receive
+ Else -> ct:fail({got,Else})
+ after 100 ->
+ ok
+ end
+ end,
+
+ ok = ?INTERFACE:close(P1),
+ {'EXIT',{badarg,[{?INTERFACE,listen,[P1,[42]],_}|_]}} =
+ (catch ?INTERFACE:listen(P1,[42])),
+
+ ok.
+
+%%
+%% Internal functions
+%%
+multi_open(N,ListenNums) ->
+ multi_open(N,ListenNums,[]).
+
+multi_open(0,_,Acc) ->
+ Acc;
+multi_open(N,ListenNums,Acc) ->
+ P = ?INTERFACE:open("p"++integer_to_list(N)),
+ ok = ?INTERFACE:listen(P,ListenNums),
+ multi_open(N-1,ListenNums,[P|Acc]).
+
+n(_F,0) ->
+ ok;
+n(F,N) ->
+ ok = F(N),
+ n(F,N-1).
+
+
+flush() ->
+ receive
+ Msg ->
+ [Msg|flush()]
+ after 0 ->
+ []
+ end.
diff --git a/lib/ose/vsn.mk b/lib/ose/vsn.mk
new file mode 100644
index 0000000000..78ffa4d496
--- /dev/null
+++ b/lib/ose/vsn.mk
@@ -0,0 +1 @@
+OSE_VSN = 1.0
--
cgit v1.2.3
From 31c4876582acf42f77f65f0d822d4d224d642364 Mon Sep 17 00:00:00 2001
From: Lukas Larsson
Date: Mon, 27 Jan 2014 17:13:53 +0100
Subject: ose: Add -block option to run_erl ose docs
---
lib/ose/doc/src/ose_intro.xml | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
(limited to 'lib')
diff --git a/lib/ose/doc/src/ose_intro.xml b/lib/ose/doc/src/ose_intro.xml
index 3bab325289..8fe723ba83 100644
--- a/lib/ose/doc/src/ose_intro.xml
+++ b/lib/ose/doc/src/ose_intro.xml
@@ -40,7 +40,19 @@
run_erl_lm. Installing and starting the load module will add two new
shell commands called run_erl and to_erl. They work in exactly the same
way as the unix variants of run_erl and to_erl, except that the read
- and write pipes have to be placed under the /pipe vm. See also
+ and write pipes have to be placed under the /pipe vm. One additional
+ option also exists to run_erl on ose:
+
+ -block Name
+ - The name of the install handle and block that will be created/used by
+ installing and exectuting the first part of the command. If nothing
+ if given the basename of the load module will be used for this value.
+ Example:
+
pm_install erlang /path/to/erlang/vm
+run_erl -daemon -block erlang /pipe/ /mst/erlang_logs/ "erl -A 10"
+
+
+ See also
run_erl for more details.
--
cgit v1.2.3
From d58602adef3412b354fd521bbd4bda24a0b1a789 Mon Sep 17 00:00:00 2001
From: Lukas Larsson
Date: Thu, 13 Feb 2014 18:14:10 +0100
Subject: crypto: Add rand_seed function
This function is needed on OSs that do not automatically
initialize the PRNG seed.
---
lib/crypto/c_src/crypto.c | 15 ++++++++++++++-
lib/crypto/doc/src/crypto.xml | 15 +++++++++++++++
2 files changed, 29 insertions(+), 1 deletion(-)
(limited to 'lib')
diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c
index 925ad0c091..bf8107d10b 100644
--- a/lib/crypto/c_src/crypto.c
+++ b/lib/crypto/c_src/crypto.c
@@ -254,6 +254,8 @@ static ERL_NIF_TERM ecdsa_sign_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM
static ERL_NIF_TERM ecdsa_verify_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
static ERL_NIF_TERM ecdh_compute_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
+static ERL_NIF_TERM rand_seed_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
+
/* helpers */
static void init_algorithms_types(ErlNifEnv*);
@@ -381,7 +383,9 @@ static ErlNifFunc nif_funcs[] = {
{"ec_key_generate", 1, ec_key_generate},
{"ecdsa_sign_nif", 4, ecdsa_sign_nif},
{"ecdsa_verify_nif", 5, ecdsa_verify_nif},
- {"ecdh_compute_key_nif", 3, ecdh_compute_key_nif}
+ {"ecdh_compute_key_nif", 3, ecdh_compute_key_nif},
+
+ {"rand_seed_nif", 1, rand_seed_nif}
};
ERL_NIF_INIT(crypto,nif_funcs,load,NULL,upgrade,unload)
@@ -3374,6 +3378,15 @@ out_err:
#endif
}
+static ERL_NIF_TERM rand_seed_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ ErlNifBinary seed_bin;
+ if (!enif_inspect_binary(env, argv[0], &seed_bin))
+ return enif_make_badarg(env);
+ RAND_seed(seed_bin.data,seed_bin.size);
+ return atom_ok;
+}
+
/* HMAC */
diff --git a/lib/crypto/doc/src/crypto.xml b/lib/crypto/doc/src/crypto.xml
index 40f829e704..952808d9db 100644
--- a/lib/crypto/doc/src/crypto.xml
+++ b/lib/crypto/doc/src/crypto.xml
@@ -552,6 +552,21 @@
+
+ rand_seed(Seed) -> ok
+ Set the seed for random bytes generation
+
+ Seed = binary()
+
+
+ Set the seed for PRNG to the given binary. This calls the
+ RAND_seed function from openssl. Only use this if the system
+ you are running on does not have enough "randomness" built in.
+ Normally this is when
+ stong_rand_bytes/1 returns low_entropy
+
+
+
rand_uniform(Lo, Hi) -> N
Generate a random number
--
cgit v1.2.3
From 6c4ee8337dff6e9b680dbff0796038948d718b5a Mon Sep 17 00:00:00 2001
From: Lukas Larsson
Date: Thu, 13 Feb 2014 17:16:42 +0100
Subject: ose: Fix support for crypto
To enable it you have to modify the OSESSL variable in the
ose xcomp file.
---
lib/crypto/Makefile | 4 +
lib/crypto/c_src/crypto.c | 205 +++++++++++++++++++++++++++++++++++----
lib/crypto/src/crypto.erl | 7 ++
lib/crypto/test/crypto_SUITE.erl | 16 ++-
4 files changed, 211 insertions(+), 21 deletions(-)
(limited to 'lib')
diff --git a/lib/crypto/Makefile b/lib/crypto/Makefile
index 2adcfd7f31..e893c914e6 100644
--- a/lib/crypto/Makefile
+++ b/lib/crypto/Makefile
@@ -23,7 +23,11 @@ include $(ERL_TOP)/make/$(TARGET)/otp.mk
# Macros
#
+ifneq ($(findstring ose,$(TARGET)),ose)
SUB_DIRECTORIES = src c_src doc/src
+else
+SUB_DIRECTORIES = src doc/src
+endif
static_lib: SUB_DIRECTORIES = c_src
include vsn.mk
diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c
index bf8107d10b..bd027cf1ba 100644
--- a/lib/crypto/c_src/crypto.c
+++ b/lib/crypto/c_src/crypto.c
@@ -455,6 +455,46 @@ static ERL_NIF_TERM atom_onbasis;
#define PRINTF_ERR0(FMT)
#define PRINTF_ERR1(FMT,A1)
+#ifdef __OSE__
+
+/* For crypto on OSE we have to initialize the crypto library on each
+ process that uses it. So since we do not know which scheduler is going
+ to execute the nif we have to check before each nif call that we have
+ initialized crypto in that process. */
+
+#include "ose.h"
+#include "openssl/osessl.h"
+
+static ErlNifTSDKey crypto_init_key;
+static int check_ose_crypto(void);
+static int init_ose_crypto(void);
+
+static int check_ose_crypto() {
+ int key = (int)enif_tsd_get(crypto_init_key);
+ if (!key) {
+ if (!CRYPTO_OSE5_init()) {
+ PRINTF_ERR0("CRYPTO: Call to CRYPTO_OSE5_init failed");
+ return 0;
+ }
+ enif_tsd_set(crypto_init_key,1);
+ }
+ return 1;
+}
+
+static int init_ose_crypto() {
+ /* Crypto nif upgrade does not work on OSE so no need to
+ destroy this key */
+ enif_tsd_key_create("crypto_init_key", &crypto_init_key);
+ return check_ose_crypto();
+}
+
+#define INIT_OSE_CRYPTO() init_ose_crypto()
+#define CHECK_OSE_CRYPTO() check_ose_crypto()
+#else
+#define INIT_OSE_CRYPTO() 1
+#define CHECK_OSE_CRYPTO()
+#endif
+
#ifdef HAVE_DYNAMIC_CRYPTO_LIB
static int change_basename(ErlNifBinary* bin, char* buf, int bufsz, const char* newfile)
{
@@ -491,6 +531,9 @@ static int init(ErlNifEnv* env, ERL_NIF_TERM load_info)
ErlNifBinary lib_bin;
char lib_buf[1000];
+ if (!INIT_OSE_CRYPTO())
+ return 0;
+
/* load_info: {301, <<"/full/path/of/this/library">>} */
if (!enif_get_tuple(env, load_info, &tpl_arity, &tpl_array)
|| tpl_arity != 2
@@ -714,7 +757,7 @@ static ERL_NIF_TERM md5(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* (Data) */
ErlNifBinary ibin;
ERL_NIF_TERM ret;
-
+ CHECK_OSE_CRYPTO();
if (!enif_inspect_iolist_as_binary(env, argv[0], &ibin)) {
return enif_make_badarg(env);
}
@@ -726,6 +769,7 @@ static ERL_NIF_TERM md5(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
static ERL_NIF_TERM md5_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* () */
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
MD5_Init((MD5_CTX *) enif_make_new_binary(env, MD5_CTX_LEN, &ret));
return ret;
}
@@ -734,6 +778,7 @@ static ERL_NIF_TERM md5_update(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv
MD5_CTX* new_ctx;
ErlNifBinary ctx_bin, data_bin;
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
if (!enif_inspect_binary(env, argv[0], &ctx_bin)
|| ctx_bin.size != MD5_CTX_LEN
|| !enif_inspect_iolist_as_binary(env, argv[1], &data_bin)) {
@@ -750,6 +795,7 @@ static ERL_NIF_TERM md5_final(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[
ErlNifBinary ctx_bin;
MD5_CTX ctx_clone;
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
if (!enif_inspect_binary(env, argv[0], &ctx_bin) || ctx_bin.size != MD5_CTX_LEN) {
return enif_make_badarg(env);
}
@@ -762,7 +808,7 @@ static ERL_NIF_TERM ripemd160(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[
{/* (Data) */
ErlNifBinary ibin;
ERL_NIF_TERM ret;
-
+ CHECK_OSE_CRYPTO();
if (!enif_inspect_iolist_as_binary(env, argv[0], &ibin)) {
return enif_make_badarg(env);
}
@@ -774,6 +820,7 @@ static ERL_NIF_TERM ripemd160(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[
static ERL_NIF_TERM ripemd160_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* () */
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
RIPEMD160_Init((RIPEMD160_CTX *) enif_make_new_binary(env, RIPEMD160_CTX_LEN, &ret));
return ret;
}
@@ -782,6 +829,7 @@ static ERL_NIF_TERM ripemd160_update(ErlNifEnv* env, int argc, const ERL_NIF_TER
RIPEMD160_CTX* new_ctx;
ErlNifBinary ctx_bin, data_bin;
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
if (!enif_inspect_binary(env, argv[0], &ctx_bin)
|| ctx_bin.size != RIPEMD160_CTX_LEN
|| !enif_inspect_iolist_as_binary(env, argv[1], &data_bin)) {
@@ -798,6 +846,7 @@ static ERL_NIF_TERM ripemd160_final(ErlNifEnv* env, int argc, const ERL_NIF_TERM
ErlNifBinary ctx_bin;
RIPEMD160_CTX ctx_clone;
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
if (!enif_inspect_binary(env, argv[0], &ctx_bin) || ctx_bin.size != RIPEMD160_CTX_LEN) {
return enif_make_badarg(env);
}
@@ -811,7 +860,7 @@ static ERL_NIF_TERM sha(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* (Data) */
ErlNifBinary ibin;
ERL_NIF_TERM ret;
-
+ CHECK_OSE_CRYPTO();
if (!enif_inspect_iolist_as_binary(env, argv[0], &ibin)) {
return enif_make_badarg(env);
}
@@ -823,6 +872,7 @@ static ERL_NIF_TERM sha(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
static ERL_NIF_TERM sha_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* () */
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
SHA1_Init((SHA_CTX *) enif_make_new_binary(env, SHA_CTX_LEN, &ret));
return ret;
}
@@ -831,6 +881,7 @@ static ERL_NIF_TERM sha_update(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv
SHA_CTX* new_ctx;
ErlNifBinary ctx_bin, data_bin;
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
if (!enif_inspect_binary(env, argv[0], &ctx_bin) || ctx_bin.size != SHA_CTX_LEN
|| !enif_inspect_iolist_as_binary(env, argv[1], &data_bin)) {
return enif_make_badarg(env);
@@ -846,6 +897,7 @@ static ERL_NIF_TERM sha_final(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[
ErlNifBinary ctx_bin;
SHA_CTX ctx_clone;
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
if (!enif_inspect_binary(env, argv[0], &ctx_bin) || ctx_bin.size != SHA_CTX_LEN) {
return enif_make_badarg(env);
}
@@ -859,7 +911,7 @@ static ERL_NIF_TERM sha224_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv
#ifdef HAVE_SHA224
ErlNifBinary ibin;
ERL_NIF_TERM ret;
-
+ CHECK_OSE_CRYPTO();
if (!enif_inspect_iolist_as_binary(env, argv[0], &ibin)) {
return enif_make_badarg(env);
}
@@ -875,6 +927,7 @@ static ERL_NIF_TERM sha224_init_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM
{/* () */
#ifdef HAVE_SHA224
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
SHA224_Init((SHA256_CTX *) enif_make_new_binary(env, sizeof(SHA256_CTX), &ret));
return ret;
#else
@@ -887,6 +940,7 @@ static ERL_NIF_TERM sha224_update_nif(ErlNifEnv* env, int argc, const ERL_NIF_TE
SHA256_CTX* new_ctx;
ErlNifBinary ctx_bin, data_bin;
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
if (!enif_inspect_binary(env, argv[0], &ctx_bin) || ctx_bin.size != sizeof(SHA256_CTX)
|| !enif_inspect_iolist_as_binary(env, argv[1], &data_bin)) {
return enif_make_badarg(env);
@@ -906,6 +960,7 @@ static ERL_NIF_TERM sha224_final_nif(ErlNifEnv* env, int argc, const ERL_NIF_TER
ErlNifBinary ctx_bin;
SHA256_CTX ctx_clone;
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
if (!enif_inspect_binary(env, argv[0], &ctx_bin) || ctx_bin.size != sizeof(SHA256_CTX)) {
return enif_make_badarg(env);
}
@@ -922,7 +977,7 @@ static ERL_NIF_TERM sha256_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv
#ifdef HAVE_SHA256
ErlNifBinary ibin;
ERL_NIF_TERM ret;
-
+ CHECK_OSE_CRYPTO();
if (!enif_inspect_iolist_as_binary(env, argv[0], &ibin)) {
return enif_make_badarg(env);
}
@@ -938,6 +993,7 @@ static ERL_NIF_TERM sha256_init_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM
{/* () */
#ifdef HAVE_SHA256
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
SHA256_Init((SHA256_CTX *) enif_make_new_binary(env, sizeof(SHA256_CTX), &ret));
return ret;
#else
@@ -950,6 +1006,7 @@ static ERL_NIF_TERM sha256_update_nif(ErlNifEnv* env, int argc, const ERL_NIF_TE
SHA256_CTX* new_ctx;
ErlNifBinary ctx_bin, data_bin;
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
if (!enif_inspect_binary(env, argv[0], &ctx_bin) || ctx_bin.size != sizeof(SHA256_CTX)
|| !enif_inspect_iolist_as_binary(env, argv[1], &data_bin)) {
return enif_make_badarg(env);
@@ -969,6 +1026,7 @@ static ERL_NIF_TERM sha256_final_nif(ErlNifEnv* env, int argc, const ERL_NIF_TER
ErlNifBinary ctx_bin;
SHA256_CTX ctx_clone;
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
if (!enif_inspect_binary(env, argv[0], &ctx_bin) || ctx_bin.size != sizeof(SHA256_CTX)) {
return enif_make_badarg(env);
}
@@ -985,7 +1043,7 @@ static ERL_NIF_TERM sha384_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv
#ifdef HAVE_SHA384
ErlNifBinary ibin;
ERL_NIF_TERM ret;
-
+ CHECK_OSE_CRYPTO();
if (!enif_inspect_iolist_as_binary(env, argv[0], &ibin)) {
return enif_make_badarg(env);
}
@@ -1001,6 +1059,7 @@ static ERL_NIF_TERM sha384_init_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM
{/* () */
#ifdef HAVE_SHA384
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
SHA384_Init((SHA512_CTX *) enif_make_new_binary(env, sizeof(SHA512_CTX), &ret));
return ret;
#else
@@ -1013,6 +1072,7 @@ static ERL_NIF_TERM sha384_update_nif(ErlNifEnv* env, int argc, const ERL_NIF_TE
SHA512_CTX* new_ctx;
ErlNifBinary ctx_bin, data_bin;
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
if (!enif_inspect_binary(env, argv[0], &ctx_bin) || ctx_bin.size != sizeof(SHA512_CTX)
|| !enif_inspect_iolist_as_binary(env, argv[1], &data_bin)) {
return enif_make_badarg(env);
@@ -1032,6 +1092,7 @@ static ERL_NIF_TERM sha384_final_nif(ErlNifEnv* env, int argc, const ERL_NIF_TER
ErlNifBinary ctx_bin;
SHA512_CTX ctx_clone;
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
if (!enif_inspect_binary(env, argv[0], &ctx_bin) || ctx_bin.size != sizeof(SHA512_CTX)) {
return enif_make_badarg(env);
}
@@ -1048,7 +1109,7 @@ static ERL_NIF_TERM sha512_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv
#ifdef HAVE_SHA512
ErlNifBinary ibin;
ERL_NIF_TERM ret;
-
+ CHECK_OSE_CRYPTO();
if (!enif_inspect_iolist_as_binary(env, argv[0], &ibin)) {
return enif_make_badarg(env);
}
@@ -1076,6 +1137,7 @@ static ERL_NIF_TERM sha512_update_nif(ErlNifEnv* env, int argc, const ERL_NIF_TE
SHA512_CTX* new_ctx;
ErlNifBinary ctx_bin, data_bin;
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
if (!enif_inspect_binary(env, argv[0], &ctx_bin) || ctx_bin.size != sizeof(SHA512_CTX)
|| !enif_inspect_iolist_as_binary(env, argv[1], &data_bin)) {
return enif_make_badarg(env);
@@ -1095,6 +1157,7 @@ static ERL_NIF_TERM sha512_final_nif(ErlNifEnv* env, int argc, const ERL_NIF_TER
ErlNifBinary ctx_bin;
SHA512_CTX ctx_clone;
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
if (!enif_inspect_binary(env, argv[0], &ctx_bin) || ctx_bin.size != sizeof(SHA512_CTX)) {
return enif_make_badarg(env);
}
@@ -1111,7 +1174,7 @@ static ERL_NIF_TERM md4(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* (Data) */
ErlNifBinary ibin;
ERL_NIF_TERM ret;
-
+ CHECK_OSE_CRYPTO();
if (!enif_inspect_iolist_as_binary(env, argv[0], &ibin)) {
return enif_make_badarg(env);
}
@@ -1123,6 +1186,7 @@ static ERL_NIF_TERM md4(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
static ERL_NIF_TERM md4_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* () */
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
MD4_Init((MD4_CTX *) enif_make_new_binary(env, MD4_CTX_LEN, &ret));
return ret;
}
@@ -1131,6 +1195,7 @@ static ERL_NIF_TERM md4_update(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv
MD4_CTX* new_ctx;
ErlNifBinary ctx_bin, data_bin;
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
if (!enif_inspect_binary(env, argv[0], &ctx_bin) || ctx_bin.size != MD4_CTX_LEN
|| !enif_inspect_iolist_as_binary(env, argv[1], &data_bin)) {
return enif_make_badarg(env);
@@ -1146,6 +1211,7 @@ static ERL_NIF_TERM md4_final(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[
ErlNifBinary ctx_bin;
MD4_CTX ctx_clone;
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
if (!enif_inspect_binary(env, argv[0], &ctx_bin) || ctx_bin.size != MD4_CTX_LEN) {
return enif_make_badarg(env);
}
@@ -1160,7 +1226,7 @@ static ERL_NIF_TERM md5_mac_n(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[
ErlNifBinary key, data;
unsigned mac_sz;
ERL_NIF_TERM ret;
-
+ CHECK_OSE_CRYPTO();
if (!enif_inspect_iolist_as_binary(env, argv[0], &key)
|| !enif_inspect_iolist_as_binary(env, argv[1], &data)
|| !enif_get_uint(env,argv[2],&mac_sz) || mac_sz > MD5_LEN) {
@@ -1178,7 +1244,7 @@ static ERL_NIF_TERM sha_mac_n(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[
ErlNifBinary key, data;
unsigned mac_sz;
ERL_NIF_TERM ret;
-
+ CHECK_OSE_CRYPTO();
if (!enif_inspect_iolist_as_binary(env, argv[0], &key)
|| !enif_inspect_iolist_as_binary(env, argv[1], &data)
|| !enif_get_uint(env,argv[2],&mac_sz) || mac_sz > SHA_LEN) {
@@ -1198,7 +1264,7 @@ static ERL_NIF_TERM sha224_mac_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM
ErlNifBinary key, data;
unsigned mac_sz;
ERL_NIF_TERM ret;
-
+ CHECK_OSE_CRYPTO();
if (!enif_inspect_iolist_as_binary(env, argv[0], &key)
|| !enif_inspect_iolist_as_binary(env, argv[1], &data)
|| !enif_get_uint(env,argv[2],&mac_sz) || mac_sz > SHA224_DIGEST_LENGTH) {
@@ -1221,7 +1287,7 @@ static ERL_NIF_TERM sha256_mac_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM
ErlNifBinary key, data;
unsigned mac_sz;
ERL_NIF_TERM ret;
-
+ CHECK_OSE_CRYPTO();
if (!enif_inspect_iolist_as_binary(env, argv[0], &key)
|| !enif_inspect_iolist_as_binary(env, argv[1], &data)
|| !enif_get_uint(env,argv[2],&mac_sz) || mac_sz > SHA256_DIGEST_LENGTH) {
@@ -1244,7 +1310,7 @@ static ERL_NIF_TERM sha384_mac_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM
ErlNifBinary key, data;
unsigned mac_sz;
ERL_NIF_TERM ret;
-
+ CHECK_OSE_CRYPTO();
if (!enif_inspect_iolist_as_binary(env, argv[0], &key)
|| !enif_inspect_iolist_as_binary(env, argv[1], &data)
|| !enif_get_uint(env,argv[2],&mac_sz) || mac_sz > SHA384_DIGEST_LENGTH) {
@@ -1268,7 +1334,7 @@ static ERL_NIF_TERM sha512_mac_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM
ErlNifBinary key, data;
unsigned mac_sz;
ERL_NIF_TERM ret;
-
+ CHECK_OSE_CRYPTO();
if (!enif_inspect_iolist_as_binary(env, argv[0], &key)
|| !enif_inspect_iolist_as_binary(env, argv[1], &data)
|| !enif_get_uint(env,argv[2],&mac_sz) || mac_sz > SHA512_DIGEST_LENGTH) {
@@ -1291,6 +1357,8 @@ static ERL_NIF_TERM hmac_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[
unsigned char * ctx_buf;
const EVP_MD *md;
+ CHECK_OSE_CRYPTO();
+
if (argv[0] == atom_sha) md = EVP_sha1();
#ifdef HAVE_SHA224
else if (argv[0] == atom_sha224) md = EVP_sha224();
@@ -1326,6 +1394,8 @@ static ERL_NIF_TERM hmac_update(ErlNifEnv* env, int argc, const ERL_NIF_TERM arg
ERL_NIF_TERM ret;
unsigned char * ctx_buf;
+ CHECK_OSE_CRYPTO();
+
if (!enif_inspect_binary(env, argv[0], &context)
|| !enif_inspect_iolist_as_binary(env, argv[1], &data)
|| context.size != sizeof(HMAC_CTX)) {
@@ -1349,7 +1419,9 @@ static ERL_NIF_TERM hmac_final(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv
unsigned char * mac_bin;
unsigned int req_len = 0;
unsigned int mac_len;
-
+
+ CHECK_OSE_CRYPTO();
+
if (!enif_inspect_binary(env, argv[0], &context)) {
return enif_make_badarg(env);
}
@@ -1382,6 +1454,8 @@ static ERL_NIF_TERM des_cbc_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM a
DES_cblock ivec_clone; /* writable copy */
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
+
if (!enif_inspect_iolist_as_binary(env, argv[0], &key) || key.size != 8
|| !enif_inspect_binary(env, argv[1], &ivec) || ivec.size != 8
|| !enif_inspect_iolist_as_binary(env, argv[2], &text)
@@ -1403,6 +1477,8 @@ static ERL_NIF_TERM des_cfb_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM a
DES_cblock ivec_clone; /* writable copy */
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
+
if (!enif_inspect_iolist_as_binary(env, argv[0], &key) || key.size != 8
|| !enif_inspect_binary(env, argv[1], &ivec) || ivec.size != 8
|| !enif_inspect_iolist_as_binary(env, argv[2], &text)) {
@@ -1421,6 +1497,7 @@ static ERL_NIF_TERM des_ecb_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM a
ErlNifBinary key, text;
DES_key_schedule schedule;
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
if (!enif_inspect_iolist_as_binary(env, argv[0], &key) || key.size != 8 ||
!enif_inspect_iolist_as_binary(env, argv[1], &text) || text.size != 8) {
return enif_make_badarg(env);
@@ -1440,6 +1517,8 @@ static ERL_NIF_TERM des_ede3_cbc_crypt(ErlNifEnv* env, int argc, const ERL_NIF_T
DES_cblock ivec_clone; /* writable copy */
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
+
if (!enif_inspect_iolist_as_binary(env, argv[0], &key1) || key1.size != 8
|| !enif_inspect_iolist_as_binary(env, argv[1], &key2) || key2.size != 8
|| !enif_inspect_iolist_as_binary(env, argv[2], &key3) || key3.size != 8
@@ -1468,6 +1547,8 @@ static ERL_NIF_TERM des_ede3_cfb_crypt_nif(ErlNifEnv* env, int argc, const ERL_N
DES_cblock ivec_clone; /* writable copy */
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
+
if (!enif_inspect_iolist_as_binary(env, argv[0], &key1) || key1.size != 8
|| !enif_inspect_iolist_as_binary(env, argv[1], &key2) || key2.size != 8
|| !enif_inspect_iolist_as_binary(env, argv[2], &key3) || key3.size != 8
@@ -1498,6 +1579,8 @@ static ERL_NIF_TERM aes_cfb_128_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TE
int new_ivlen = 0;
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
+
if (!enif_inspect_iolist_as_binary(env, argv[0], &key) || key.size != 16
|| !enif_inspect_binary(env, argv[1], &ivec) || ivec.size != 16
|| !enif_inspect_iolist_as_binary(env, argv[2], &text)) {
@@ -1525,6 +1608,8 @@ static ERL_NIF_TERM aes_ctr_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM
unsigned int num = 0;
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
+
if (!enif_inspect_iolist_as_binary(env, argv[0], &key)
|| AES_set_encrypt_key(key.data, key.size*8, &aes_key) != 0
|| !enif_inspect_binary(env, argv[1], &ivec) || ivec.size != 16
@@ -1556,6 +1641,8 @@ static ERL_NIF_TERM aes_ctr_stream_encrypt(ErlNifEnv* env, int argc, const ERL_N
unsigned char * ivec2_buf;
unsigned char * ecount2_buf;
+ CHECK_OSE_CRYPTO();
+
if (!enif_get_tuple(env, argv[0], &state_arity, &state_term)
|| state_arity != 4
|| !enif_inspect_iolist_as_binary(env, state_term[0], &key_bin)
@@ -1589,6 +1676,7 @@ static ERL_NIF_TERM rand_bytes_1(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar
unsigned bytes;
unsigned char* data;
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
if (!enif_get_uint(env, argv[0], &bytes)) {
return enif_make_badarg(env);
}
@@ -1602,6 +1690,7 @@ static ERL_NIF_TERM strong_rand_bytes_nif(ErlNifEnv* env, int argc, const ERL_NI
unsigned bytes;
unsigned char* data;
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
if (!enif_get_uint(env, argv[0], &bytes)) {
return enif_make_badarg(env);
}
@@ -1619,6 +1708,7 @@ static ERL_NIF_TERM rand_bytes_3(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar
unsigned char* data;
unsigned top_mask, bot_mask;
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
if (!enif_get_uint(env, argv[0], &bytes)
|| !enif_get_uint(env, argv[1], &top_mask)
|| !enif_get_uint(env, argv[2], &bot_mask)) {
@@ -1641,6 +1731,9 @@ static ERL_NIF_TERM strong_rand_mpint_nif(ErlNifEnv* env, int argc, const ERL_NI
unsigned char* data;
unsigned dlen;
ERL_NIF_TERM ret;
+
+ CHECK_OSE_CRYPTO();
+
if (!enif_get_uint(env, argv[0], &bits)
|| !enif_get_int(env, argv[1], &top)
|| !enif_get_int(env, argv[2], &bottom)) {
@@ -1708,6 +1801,9 @@ static ERL_NIF_TERM rand_uniform_nif(ErlNifEnv* env, int argc, const ERL_NIF_TER
unsigned char* data;
unsigned dlen;
ERL_NIF_TERM ret;
+
+ CHECK_OSE_CRYPTO();
+
if (!get_bn_from_mpint(env, argv[0], &bn_from)
|| !get_bn_from_mpint(env, argv[1], &bn_rand)) {
if (bn_from) BN_free(bn_from);
@@ -1739,6 +1835,8 @@ static ERL_NIF_TERM mod_exp_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM arg
unsigned extra_byte;
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
+
if (!get_bn_from_bin(env, argv[0], &bn_base)
|| !get_bn_from_bin(env, argv[1], &bn_exponent)
|| !get_bn_from_bin(env, argv[2], &bn_modulo)
@@ -1781,6 +1879,8 @@ static ERL_NIF_TERM dss_verify_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM
DSA *dsa;
int i;
+ CHECK_OSE_CRYPTO();
+
if (argv[0] == atom_sha) {
if (enif_get_tuple(env, argv[1], &tpl_arity, &tpl_terms)) {
if (tpl_arity != 2 || tpl_terms[0] != atom_digest
@@ -1948,6 +2048,8 @@ static ERL_NIF_TERM rsa_verify_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM
struct digest_type_t* digp = NULL;
unsigned char* digest = NULL;
+ CHECK_OSE_CRYPTO();
+
digp = get_digest_type(type);
if (!digp) {
return enif_make_badarg(env);
@@ -2007,6 +2109,8 @@ static ERL_NIF_TERM aes_cbc_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM a
unsigned char* ret_ptr;
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
+
if (!enif_inspect_iolist_as_binary(env, argv[0], &key_bin)
|| (key_bin.size != 16 && key_bin.size != 32)
|| !enif_inspect_binary(env, argv[1], &ivec_bin)
@@ -2043,6 +2147,8 @@ static ERL_NIF_TERM aes_ige_crypt_nif(ErlNifEnv* env, int argc, const ERL_NIF_TE
unsigned char* ret_ptr;
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
+
if (!enif_inspect_iolist_as_binary(env, argv[0], &key_bin)
|| (key_bin.size != 16 && key_bin.size != 32)
|| !enif_inspect_binary(env, argv[1], &ivec_bin)
@@ -2079,6 +2185,8 @@ static ERL_NIF_TERM do_exor(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
int i;
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
+
if (!enif_inspect_iolist_as_binary(env,argv[0], &d1)
|| !enif_inspect_iolist_as_binary(env,argv[1], &d2)
|| d1.size != d2.size) {
@@ -2099,6 +2207,8 @@ static ERL_NIF_TERM rc4_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM arg
RC4_KEY rc4_key;
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
+
if (!enif_inspect_iolist_as_binary(env,argv[0], &key)
|| !enif_inspect_iolist_as_binary(env,argv[1], &data)) {
return enif_make_badarg(env);
@@ -2115,6 +2225,8 @@ static ERL_NIF_TERM rc4_set_key(ErlNifEnv* env, int argc, const ERL_NIF_TERM arg
ErlNifBinary key;
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
+
if (!enif_inspect_iolist_as_binary(env,argv[0], &key)) {
return enif_make_badarg(env);
}
@@ -2130,6 +2242,8 @@ static ERL_NIF_TERM rc4_encrypt_with_state(ErlNifEnv* env, int argc, const ERL_N
RC4_KEY* rc4_key;
ERL_NIF_TERM new_state, new_data;
+ CHECK_OSE_CRYPTO();
+
if (!enif_inspect_iolist_as_binary(env,argv[0], &state)
|| state.size != sizeof(RC4_KEY)
|| !enif_inspect_iolist_as_binary(env,argv[1], &data)) {
@@ -2149,6 +2263,8 @@ static ERL_NIF_TERM rc2_cbc_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM a
RC2_KEY rc2_key;
ERL_NIF_TERM ret;
unsigned char iv_copy[8];
+
+ CHECK_OSE_CRYPTO();
if (!enif_inspect_iolist_as_binary(env, argv[0], &key_bin)
|| (key_bin.size != 5 && key_bin.size != 8 && key_bin.size != 16)
@@ -2210,6 +2326,8 @@ static ERL_NIF_TERM rsa_sign_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar
struct digest_type_t *digp;
unsigned char* digest;
+ CHECK_OSE_CRYPTO();
+
digp = get_digest_type(argv[0]);
if (!digp) {
return enif_make_badarg(env);
@@ -2276,6 +2394,8 @@ static ERL_NIF_TERM dss_sign_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar
DSA* dsa;
int i;
+ CHECK_OSE_CRYPTO();
+
if (argv[0] == atom_sha) {
if (enif_get_tuple(env, argv[1], &tpl_arity, &tpl_terms)) {
if (tpl_arity != 2 || tpl_terms[0] != atom_digest
@@ -2358,7 +2478,11 @@ static ERL_NIF_TERM rsa_public_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TER
ErlNifBinary data_bin, ret_bin;
ERL_NIF_TERM head, tail;
int padding, i;
- RSA* rsa = RSA_new();
+ RSA* rsa;
+
+ CHECK_OSE_CRYPTO();
+
+ rsa = RSA_new();
if (!enif_inspect_binary(env, argv[0], &data_bin)
|| !enif_get_list_cell(env, argv[1], &head, &tail)
@@ -2404,7 +2528,11 @@ static ERL_NIF_TERM rsa_private_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TE
{/* (Data, Key=[E,N,D]|[E,N,D,P1,P2,E1,E2,C], Padding, IsEncrypt) */
ErlNifBinary data_bin, ret_bin;
int padding, i;
- RSA* rsa = RSA_new();
+ RSA* rsa;
+
+ CHECK_OSE_CRYPTO();
+
+ rsa = RSA_new();
if (!enif_inspect_binary(env, argv[0], &data_bin)
|| !get_rsa_private_key(env, argv[1], rsa)
@@ -2450,6 +2578,8 @@ static ERL_NIF_TERM dh_generate_parameters_nif(ErlNifEnv* env, int argc, const E
unsigned char *p_ptr, *g_ptr;
ERL_NIF_TERM ret_p, ret_g;
+ CHECK_OSE_CRYPTO();
+
if (!enif_get_int(env, argv[0], &prime_len)
|| !enif_get_int(env, argv[1], &generator)) {
@@ -2473,10 +2603,14 @@ static ERL_NIF_TERM dh_generate_parameters_nif(ErlNifEnv* env, int argc, const E
static ERL_NIF_TERM dh_check(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* ([PrimeLen, Generator]) */
- DH* dh_params = DH_new();
+ DH* dh_params;
int i;
ERL_NIF_TERM ret, head, tail;
+ CHECK_OSE_CRYPTO();
+
+ dh_params = DH_new();
+
if (!enif_get_list_cell(env, argv[0], &head, &tail)
|| !get_bn_from_bin(env, head, &dh_params->p)
|| !enif_get_list_cell(env, tail, &head, &tail)
@@ -2503,12 +2637,16 @@ static ERL_NIF_TERM dh_check(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]
static ERL_NIF_TERM dh_generate_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* (PrivKey, DHParams=[P,G], Mpint) */
- DH* dh_params = DH_new();
+ DH* dh_params;
int pub_len, prv_len;
unsigned char *pub_ptr, *prv_ptr;
ERL_NIF_TERM ret, ret_pub, ret_prv, head, tail;
int mpint; /* 0 or 4 */
+ CHECK_OSE_CRYPTO();
+
+ dh_params = DH_new();
+
if (!(get_bn_from_bin(env, argv[0], &dh_params->priv_key)
|| argv[0] == atom_undefined)
|| !enif_get_list_cell(env, argv[1], &head, &tail)
@@ -2545,12 +2683,16 @@ static ERL_NIF_TERM dh_generate_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_
static ERL_NIF_TERM dh_compute_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* (OthersPublicKey, MyPrivateKey, DHParams=[P,G]) */
- DH* dh_params = DH_new();
+ DH* dh_params;
BIGNUM* pubkey = NULL;
int i;
ErlNifBinary ret_bin;
ERL_NIF_TERM ret, head, tail;
+ CHECK_OSE_CRYPTO();
+
+ dh_params = DH_new();
+
if (!get_bn_from_bin(env, argv[0], &pubkey)
|| !get_bn_from_bin(env, argv[1], &dh_params->priv_key)
|| !enif_get_list_cell(env, argv[2], &head, &tail)
@@ -2588,6 +2730,8 @@ static ERL_NIF_TERM srp_value_B_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM
unsigned dlen;
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
+
if (!get_bn_from_bin(env, argv[0], &bn_multiplier)
|| !get_bn_from_bin(env, argv[1], &bn_verifier)
|| !get_bn_from_bin(env, argv[2], &bn_generator)
@@ -2648,6 +2792,8 @@ static ERL_NIF_TERM srp_user_secret_nif(ErlNifEnv* env, int argc, const ERL_NIF_
unsigned dlen;
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
+
if (!get_bn_from_bin(env, argv[0], &bn_a)
|| !get_bn_from_bin(env, argv[1], &bn_u)
|| !get_bn_from_bin(env, argv[2], &bn_B)
@@ -2727,6 +2873,8 @@ static ERL_NIF_TERM srp_host_secret_nif(ErlNifEnv* env, int argc, const ERL_NIF_
unsigned dlen;
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
+
if (!get_bn_from_bin(env, argv[0], &bn_verifier)
|| !get_bn_from_bin(env, argv[1], &bn_b)
|| !get_bn_from_bin(env, argv[2], &bn_u)
@@ -2787,6 +2935,8 @@ static ERL_NIF_TERM bf_cfb64_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM
int bf_n = 0; /* blowfish ivec pos */
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
+
if (!enif_inspect_iolist_as_binary(env, argv[0], &key_bin)
|| !enif_inspect_binary(env, argv[1], &ivec_bin)
|| ivec_bin.size != 8
@@ -2810,6 +2960,8 @@ static ERL_NIF_TERM bf_cbc_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar
unsigned char bf_tkey[8]; /* blowfish ivec */
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
+
if (!enif_inspect_iolist_as_binary(env, argv[0], &key_bin)
|| !enif_inspect_binary(env, argv[1], &ivec_bin)
|| ivec_bin.size != 8
@@ -2833,6 +2985,8 @@ static ERL_NIF_TERM bf_ecb_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar
BF_KEY bf_key; /* blowfish key 8 */
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
+
if (!enif_inspect_iolist_as_binary(env, argv[0], &key_bin)
|| !enif_inspect_iolist_as_binary(env, argv[1], &data_bin)
|| data_bin.size < 8) {
@@ -2853,6 +3007,8 @@ static ERL_NIF_TERM blowfish_ofb64_encrypt(ErlNifEnv* env, int argc, const ERL_N
int bf_n = 0; /* blowfish ivec pos */
ERL_NIF_TERM ret;
+ CHECK_OSE_CRYPTO();
+
if (!enif_inspect_iolist_as_binary(env, argv[0], &key_bin)
|| !enif_inspect_binary(env, argv[1], &ivec_bin)
|| ivec_bin.size != 8
@@ -3171,6 +3327,8 @@ static ERL_NIF_TERM ec_key_generate(ErlNifEnv* env, int argc, const ERL_NIF_TERM
#if defined(HAVE_EC)
EC_KEY *key = ec_key_new(env, argv[0]);
+ CHECK_OSE_CRYPTO();
+
if (key && EC_KEY_generate_key(key)) {
const EC_GROUP *group;
const EC_POINT *public_key;
@@ -3208,6 +3366,8 @@ static ERL_NIF_TERM ecdsa_sign_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM
struct digest_type_t *digp;
unsigned char* digest;
+ CHECK_OSE_CRYPTO();
+
digp = get_digest_type(argv[0]);
if (!digp) {
return enif_make_badarg(env);
@@ -3275,6 +3435,8 @@ static ERL_NIF_TERM ecdsa_verify_nif(ErlNifEnv* env, int argc, const ERL_NIF_TER
struct digest_type_t* digp = NULL;
unsigned char* digest = NULL;
+ CHECK_OSE_CRYPTO();
+
digp = get_digest_type(type);
if (!digp) {
return enif_make_badarg(env);
@@ -3338,6 +3500,8 @@ static ERL_NIF_TERM ecdh_compute_key_nif(ErlNifEnv* env, int argc, const ERL_NIF
EC_POINT *my_ecpoint;
EC_KEY *other_ecdh = NULL;
+ CHECK_OSE_CRYPTO();
+
if (!get_ec_key(env, argv[1], argv[2], atom_undefined, &key))
return enif_make_badarg(env);
@@ -3381,6 +3545,7 @@ out_err:
static ERL_NIF_TERM rand_seed_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
ErlNifBinary seed_bin;
+ CHECK_OSE_CRYPTO();
if (!enif_inspect_binary(env, argv[0], &seed_bin))
return enif_make_badarg(env);
RAND_seed(seed_bin.data,seed_bin.size);
diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl
index d953bd3bca..5bf52fc8a4 100644
--- a/lib/crypto/src/crypto.erl
+++ b/lib/crypto/src/crypto.erl
@@ -35,6 +35,7 @@
-export([private_encrypt/4, public_decrypt/4]).
-export([dh_generate_parameters/2, dh_check/1]). %% Testing see
-export([ec_curve/1, ec_curves/0]).
+-export([rand_seed/1]).
%% DEPRECATED
%% Replaced by hash_*
@@ -437,6 +438,11 @@ rand_uniform_pos(_,_) ->
rand_uniform_nif(_From,_To) -> ?nif_stub.
+-spec rand_seed(binary()) -> ok.
+rand_seed(Seed) ->
+ rand_seed_nif(Seed).
+
+rand_seed_nif(_Seed) -> ?nif_stub.
-spec mod_pow(binary()|integer(), binary()|integer(), binary()|integer()) -> binary() | error.
mod_pow(Base, Exponent, Prime) ->
@@ -1774,6 +1780,7 @@ mod_exp_nif(_Base,_Exp,_Mod,_bin_hdr) -> ?nif_stub.
rand_bytes,
strong_rand_bytes,
rand_uniform,
+ rand_seed,
mod_pow,
exor,
%% deprecated
diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl
index d1be7cea68..d05277390a 100644
--- a/lib/crypto/test/crypto_SUITE.erl
+++ b/lib/crypto/test/crypto_SUITE.erl
@@ -104,7 +104,21 @@ groups() ->
init_per_suite(Config) ->
try crypto:start() of
ok ->
- Config
+ try crypto:strong_rand_bytes(1) of
+ _ ->
+ Config
+ catch error:low_entropy ->
+ %% Make sure we are on OSE, otherwise we want to crash
+ {ose,_} = os:type(),
+
+ %% This is NOT how you want to seed this, it is just here
+ %% to make the tests pass. Check your OS manual for how you
+ %% really want to seed.
+ {H,M,L} = erlang:now(),
+ Bin = <>,
+ crypto:rand_seed(<< <> || _ <- lists:seq(1,16) >>),
+ Config
+ end
catch _:_ ->
{skip, "Crypto did not start"}
end.
--
cgit v1.2.3
From ff77d5049cca221e82d1b28e862512069c399eb7 Mon Sep 17 00:00:00 2001
From: Lukas Larsson
Date: Fri, 14 Feb 2014 15:29:43 +0100
Subject: ose: Fix broken doc links
---
lib/ose/doc/src/ose_erl_driver.xml | 2 +-
lib/ose/doc/src/ose_signals_chapter.xml | 2 +-
lib/ose/src/ose.erl | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
(limited to 'lib')
diff --git a/lib/ose/doc/src/ose_erl_driver.xml b/lib/ose/doc/src/ose_erl_driver.xml
index 6687d78087..93cbd91be7 100644
--- a/lib/ose/doc/src/ose_erl_driver.xml
+++ b/lib/ose/doc/src/ose_erl_driver.xml
@@ -74,7 +74,7 @@
Create a new ErlDrvEvent associated with signo,
id and uses the resolve_signal function to extract
the id from a signal with signo. See
-
+
Signals in a Linked-in driver in the OSE User's Guide.
diff --git a/lib/ose/doc/src/ose_signals_chapter.xml b/lib/ose/doc/src/ose_signals_chapter.xml
index 2a6ddb5765..85849e1a39 100644
--- a/lib/ose/doc/src/ose_signals_chapter.xml
+++ b/lib/ose/doc/src/ose_signals_chapter.xml
@@ -79,7 +79,7 @@
used. The third argument is a function pointer to a function that can
be used to figure out the id from a given signal. There is a complete
example of what this could look like in
- the next section.
+ the next section.
It is very important to issue the driver_select call before
any of the signals you are interested in are sent. If driver_select
is called after the signal is sent, there is a high probability that it
diff --git a/lib/ose/src/ose.erl b/lib/ose/src/ose.erl
index ff7147233f..77f11addf9 100644
--- a/lib/ose/src/ose.erl
+++ b/lib/ose/src/ose.erl
@@ -108,7 +108,7 @@
%%
%% raises: `badarg' | `system_limit'
%%
-%% @see liten/2
+%% @see listen/2
%% @end
%%------------------------------------------------------------------------------
-spec open(Name) -> Port when
--
cgit v1.2.3
From 4a6850e522b91eb009ddd0ed9d9f542f1baf1bee Mon Sep 17 00:00:00 2001
From: Jonas Karlsson
Date: Fri, 21 Feb 2014 14:01:38 +0100
Subject: ose: Updating event and signal API for OSE
---
lib/ose/doc/src/ose_erl_driver.xml | 9 +++++----
lib/ose/doc/src/ose_signals_chapter.xml | 23 +++++++++++++++++++++--
2 files changed, 26 insertions(+), 6 deletions(-)
(limited to 'lib')
diff --git a/lib/ose/doc/src/ose_erl_driver.xml b/lib/ose/doc/src/ose_erl_driver.xml
index 93cbd91be7..1d89d7aeea 100644
--- a/lib/ose/doc/src/ose_erl_driver.xml
+++ b/lib/ose/doc/src/ose_erl_driver.xml
@@ -68,12 +68,13 @@
- ErlDrvEventerl_drv_ose_event_alloc(SIGSELECT signo, ErlDrvOseEventId id, ErlDrvOseEventId (*resolve_signal)(union SIGNAL* sig))
+ ErlDrvEventerl_drv_ose_event_alloc(SIGSELECT signo, ErlDrvOseEventId id, ErlDrvOseEventId (*resolve_signal)(union SIGNAL* sig), void *extra)
Create a new ErlDrvEvent associated with signo,
id and uses the resolve_signal function to extract
- the id from a signal with signo. See
+ the id from a signal with signo. The extra
+ parameter can be used for additional data. See
Signals in a Linked-in driver in the OSE User's Guide.
@@ -89,10 +90,10 @@
- voiderl_drv_ose_event_fetch(ErlDrvEvent drv_event, SIGSELECT *signo, int *id)
+ voiderl_drv_ose_event_fetch(ErlDrvEvent drv_event, SIGSELECT *signo, ErlDrvOseEventId *id, void **extra)
- Write the signal number and id associated with drv_event
+
Write the signal number, id and any extra data associated with drv_event
into *signo and *id respectively. NULL can be
also passed as signo or id in order to ignore that field.
diff --git a/lib/ose/doc/src/ose_signals_chapter.xml b/lib/ose/doc/src/ose_signals_chapter.xml
index 85849e1a39..c8d98f4099 100644
--- a/lib/ose/doc/src/ose_signals_chapter.xml
+++ b/lib/ose/doc/src/ose_signals_chapter.xml
@@ -77,7 +77,12 @@
in this case the port id that we got in the
start callback is
used. The third argument is a function pointer to a function that can
- be used to figure out the id from a given signal. There is a complete
+ be used to figure out the id from a given signal. The fourth argument can
+ point to any additional data you might want to associate with the event.
+ There is a complete. You can examine the data contained in the event with
+ erl_drv_ose_event_fetch
+ , eg:
+ erl_drv_ose_event_fetch(event, &signal, &port, (void **)&extra);
example of what this could look like in
the next section.
It is very important to issue the driver_select call before
@@ -132,8 +137,12 @@ static ErlDrvSSizeT control(ErlDrvData driver_data, unsigned int cmd,
char **rbuf, ErlDrvSizeT rlen) {
ErlDrvPort port = (ErlDrvPort)driver_data;
+ /* An example of extra data to associate with the event */
+ char *extra_data = driver_alloc(80);
+ snprintf("extra_data, "Event, sig_no: 1234, and port: %d", port);
+
/* Create a new event to select on */
- ErlDrvOseEvent evt = erl_drv_ose_event_alloc(1234,port,resolver);
+ ErlDrvOseEvent evt = erl_drv_ose_event_alloc(1234,port,resolver, extra_data);
/* Make sure to do the select call _BEFORE_ the signal arrives.
The signal might get lost if the hunt call is done before the
@@ -147,11 +156,16 @@ static ErlDrvSSizeT control(ErlDrvData driver_data, unsigned int cmd,
}
static void ready_input(ErlDrvData driver_data, ErlDrvEvent evt) {
+ char *extra_data;
/* Get the first signal payload from the event */
union SIGNAL *sig = erl_drv_ose_get_signal(evt);
ErlDrvPort port = (ErlDrvPort)driver_data;
while (sig != NULL) {
if (sig->signo == 1234) {
+ /* Print out the string we added as the extra parameter */
+ erl_drv_ose_event_fetch(evt, NULL, NULL, (void **)&extra_data);
+ printf("We've received: %s\n", extra_data);
+
/* If it is our signal we send a message with the sender of the signal
to the controlling erlang process */
ErlDrvTermData reply[] = { ERL_DRV_UINT, (ErlDrvUInt)sender(&sig) };
@@ -172,6 +186,11 @@ static void ready_input(ErlDrvData driver_data, ErlDrvEvent evt) {
static void stop_select(ErlDrvEvent event, void *reserved)
{
+ /* Free the extra_data */
+ erl_drv_ose_event_fetch(evt, NULL, NULL, (void **)&extra_data);
+ driver_free(extra_data);
+
+ /* Free the event itself */
erl_drv_ose_event_free(event);
}
--
cgit v1.2.3
From 13ed57745c639f72be8ae1f25fbd206f6e7307f3 Mon Sep 17 00:00:00 2001
From: Lukas Larsson
Date: Fri, 21 Feb 2014 15:19:53 +0100
Subject: ose: Expand OSE docs
---
lib/ose/doc/src/ose_intro.xml | 97 ++++++++++++++++++++++++++++++++-
lib/ose/doc/src/ose_signals_chapter.xml | 23 ++++++++
2 files changed, 118 insertions(+), 2 deletions(-)
(limited to 'lib')
diff --git a/lib/ose/doc/src/ose_intro.xml b/lib/ose/doc/src/ose_intro.xml
index 8fe723ba83..0dd3ec409e 100644
--- a/lib/ose/doc/src/ose_intro.xml
+++ b/lib/ose/doc/src/ose_intro.xml
@@ -33,6 +33,62 @@
Features
+
+ Starting Erlang/OTP
+
+ Starting Erlang/OTP on OSE is not as simple as on Unix/Windows (yet).
+ First of all you have to explicitly use the beam (or beam.smp) executables
+ found in erts-X.Y.Z/bin as the load module that you run. This in turn
+ means that you have to supply the raw beam arguments to the emulator
+ when starting. Fortunately erl on Unix/Windows has a
+ undocumented flag called -emu_args_exit that can be used to
+ figure out what the arguments to beam look like. For example:
+ # erl +Mut false +A 10 +S 4:4 +Muycs256 +P 2096 +Q 2096 -emu_args_exit
+-Mut
+false
+-A
+10
+-S
+4:4
+-Muycs256
+-P
+2096
+-Q
+2096
+--
+-root
+/usr/local/lib/erlang
+-progname
+erl
+--
+-home
+/home/erlang
+--
+
+ The arguments are printed on seperate lines to make it possible to know
+ what has to be quoted with ". Each line is one quotable unit.
+ So taking the arguments above you can supply them to pm_create or
+ just execute directly on the command line. For example:
+ rtose@acp3400> pm_install erlang /mst/erlang/erts-6.0/bin/beam.smp
+rtose@acp3400> pm_create -c ARGV="-Mut false -A 10 -S 4:4 -Muycs256 -P 2096 -Q 2099 -- -root /mst/erlang -progname erl -- -home /mst/erlang --" erlang
+pid: 0x110059
+rtose@acp3400> pm_start 0x110059
+
+ Also note that since we are running erl to figure out the arguments on a
+ seperate machine the paths have to be updated. In the example above
+ /usr/local/lib/erlang was replaced by /mst/erlang/. The
+ goal is to in future releases not have to do the special argument handling
+ but for now (17.0-rc2) you have to do it.
+
+
+ Because of a limitation in the way the OSE handles stdio when starting
+ load modules using pm_install/create the Erlang shell only reads every
+ other command from stdin. However if you start Erlang using run_erl
+ you do not have this problem. So it is highly recommended that you
+ start Erlang using run_erl.
+
+
+
run_erl and to_erl
@@ -48,13 +104,50 @@
installing and exectuting the first part of the command. If nothing
if given the basename of the load module will be used for this value.
Example:
- pm_install erlang /path/to/erlang/vm
-run_erl -daemon -block erlang /pipe/ /mst/erlang_logs/ "erl -A 10"
+ pm_install erlang /path/to/erlang/vm/beam.smp
+run_erl -daemon -block erlang /pipe/ /mst/erlang_logs/ "beam.smp -A 1 -- -root /mst/erlang -- -home /mst --"
+ The same argument munching as when starting Erlang/OTP without run_erl
+ has to be done. If -daemon is given then all error printouts
+ are sent to the ramlog.
See also
run_erl for more details.
+
+ Below is an example of how to get started with run_erl_lm.
+ rtose@acp3400> pm_install run_erl_lm /mst/erlang/erts-6.0/bin/run_erl_lm
+rtose@acp3400> pm_create run_erl_lm
+pid: 0x1c005d
+rtose@acp3400> pm_start 0x1c005d
+rtose@acp3400> mkdir /mst/erlang_log
+rtose@acp3400> run_erl -daemon /pipe/ /mst/erlang_log/ "/mst/erlang/erts-6.0/bin/beam.smp -A 1 -- -root /mst/erlang -- -home /mst --"
+rtose@acp3400> to_erl
+Attaching to /pipe/erlang.pipe.1 (^C to exit)
+os:type().
+{ose,release}
+2>
+'to_erl' terminated.
+ Note that Ctrl-C is used instead of Ctrl-D to exit the to_erl shell.
+
+
+
+
+ epmd
+
+ In OSE epmd will not be started automatically so if you want to use
+ Erlang distribution you have to manually start epmd.
+
+
+
+
+ VM Process Priorities
+
+ It is possible to set the priorities you want for the OSE processes that
+ thr emulator creates in the lmconf. An example of how to do it can be
+ found in the default lmconf file in
+ $ERL_TOP/erts/emulator/sys/ose/default.lmconf.
+
diff --git a/lib/ose/doc/src/ose_signals_chapter.xml b/lib/ose/doc/src/ose_signals_chapter.xml
index c8d98f4099..ff501777cc 100644
--- a/lib/ose/doc/src/ose_signals_chapter.xml
+++ b/lib/ose/doc/src/ose_signals_chapter.xml
@@ -45,6 +45,29 @@
Signals in Erlang
+ Erlang/OTP on OSE provides a erlang module called
+ ose that can be used to interact
+ with other OSE processes using message passing. The api in the module
+ is very similar to the native OSE api, so for details of how the
+ functions work please refer to the official OSE documenation. Below
+ is an example usage of the API.
+
+ 1> P1 = ose:open("p1").
+#Port>0.344>
+2> ose:hunt(P1,"p2").
+{#Port>0.344>,1}
+3> P2 = ose:open("p2").
+#Port>0.355>
+4> flush().
+Shell got {mailbox_up,#Port>0.344>,{#Port>0.344>,1},852189}
+ok
+5> ose:listen(P1,[1234]).
+ok
+6> ose:send(P2,ose:get_id(P1),1234,>>"hello">>).
+ok
+7> flush().
+Shell got {message,#Port>0.344>,{852189,1245316,1234,>>"hello">>}}
+ok
--
cgit v1.2.3