diff options
author | Lukas Larsson <lukas@erlang-solutions.com> | 2014-02-24 16:45:04 +0100 |
---|---|---|
committer | Lukas Larsson <lukas@erlang-solutions.com> | 2014-02-24 16:45:04 +0100 |
commit | a157ffce8e25012512e0e5d88e05fb135792f161 (patch) | |
tree | 8c2bf21e8a401f696483d6e7d08ff00dd805c06c /lib | |
parent | 4ce83eb728748787f8a2da6155112c6da42a0eba (diff) | |
parent | 81abbc48e12317a07a8d2fcc041031c1c1567c8d (diff) | |
download | otp-a157ffce8e25012512e0e5d88e05fb135792f161.tar.gz otp-a157ffce8e25012512e0e5d88e05fb135792f161.tar.bz2 otp-a157ffce8e25012512e0e5d88e05fb135792f161.zip |
Merge branch 'lukas/ose/master/OTP-11334'
* lukas/ose/master/OTP-11334: (71 commits)
erts: Fix unix efile assert
ose: Use -O2 when building
ose: Expand OSE docs
ose: Add dummy ttsl driver
ose: Cleanup cleanup of mutex selection defines
ose: Polish mmap configure checks
ose: Add ose specific x-compile flags
ose: Updating fd_driver and spawn_driver for OSE
ose: Updating event and signal API for OSE
ose: Cleanup of mutex selection defines
win32: Compile erl_log.exe
ose: Remove uneccesary define
ose: Fix ssl configure test for osx
erts: Fix sys_msg_dispatcher assert
ose: Fix broken doc links
ose: Thread priorities configurable from lmconf
ose: Yielding the cpu is done "the OSE" way
ose: Start using ppdata for tse key
ose: Do not use spinlocks on OSE
ose: Fix support for crypto
...
Conflicts:
lib/crypto/c_src/crypto.c
Diffstat (limited to 'lib')
51 files changed, 2935 insertions, 117 deletions
diff --git a/lib/Makefile b/lib/Makefile index 4b979fc28a..95170d8a56 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -35,7 +35,7 @@ ALL_ERLANG_APPLICATIONS = xmerl edoc erl_docgen snmp otp_mibs erl_interface \ 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/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/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/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/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c index 2e1a21178f..fca08c4eed 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) @@ -460,6 +464,46 @@ static void hmac_context_dtor(ErlNifEnv* env, struct hmac_context*); #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) { @@ -496,6 +540,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 @@ -728,7 +775,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); } @@ -740,6 +787,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; } @@ -748,6 +796,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)) { @@ -764,6 +813,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); } @@ -776,7 +826,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); } @@ -788,6 +838,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; } @@ -796,6 +847,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)) { @@ -812,6 +864,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); } @@ -825,7 +878,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); } @@ -837,6 +890,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; } @@ -845,6 +899,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); @@ -860,6 +915,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); } @@ -873,7 +929,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); } @@ -889,6 +945,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 @@ -901,6 +958,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); @@ -920,6 +978,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); } @@ -936,7 +995,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); } @@ -952,6 +1011,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 @@ -964,6 +1024,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); @@ -983,6 +1044,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); } @@ -999,7 +1061,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); } @@ -1015,6 +1077,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 @@ -1027,6 +1090,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); @@ -1046,6 +1110,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); } @@ -1062,7 +1127,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); } @@ -1090,6 +1155,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); @@ -1109,6 +1175,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); } @@ -1125,7 +1192,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); } @@ -1137,6 +1204,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; } @@ -1145,6 +1213,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); @@ -1160,6 +1229,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); } @@ -1174,7 +1244,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) { @@ -1192,7 +1262,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) { @@ -1212,7 +1282,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) { @@ -1235,7 +1305,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) { @@ -1258,7 +1328,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) { @@ -1282,7 +1352,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) { @@ -1313,6 +1383,8 @@ static ERL_NIF_TERM hmac_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[ struct hmac_context* obj; 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(); @@ -1349,6 +1421,8 @@ static ERL_NIF_TERM hmac_update(ErlNifEnv* env, int argc, const ERL_NIF_TERM arg ErlNifBinary data; struct hmac_context* obj; + CHECK_OSE_CRYPTO(); + if (!enif_get_resource(env, argv[0], hmac_context_rtype, (void**)&obj) || !enif_inspect_iolist_as_binary(env, argv[1], &data)) { return enif_make_badarg(env); @@ -1373,6 +1447,8 @@ 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_get_resource(env,argv[0],hmac_context_rtype, (void**)&obj) || (argc == 2 && !enif_get_uint(env, argv[1], &req_len))) { @@ -1407,6 +1483,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) @@ -1428,6 +1506,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)) { @@ -1446,6 +1526,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); @@ -1465,6 +1546,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 @@ -1493,6 +1576,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 @@ -1523,6 +1608,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)) { @@ -1550,6 +1637,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 @@ -1581,6 +1670,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) @@ -1614,6 +1705,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); } @@ -1627,6 +1719,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); } @@ -1644,6 +1737,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)) { @@ -1666,6 +1760,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)) { @@ -1733,6 +1830,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); @@ -1764,6 +1864,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) @@ -1806,6 +1908,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 @@ -1973,6 +2077,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); @@ -2032,6 +2138,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) @@ -2068,6 +2176,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) @@ -2104,6 +2214,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) { @@ -2124,6 +2236,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); @@ -2140,6 +2254,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); } @@ -2155,6 +2271,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)) { @@ -2174,6 +2292,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) @@ -2235,6 +2355,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); @@ -2301,6 +2423,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 @@ -2383,7 +2507,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) @@ -2429,7 +2557,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) @@ -2475,6 +2607,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)) { @@ -2498,10 +2632,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) @@ -2528,12 +2666,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) @@ -2570,12 +2712,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) @@ -2613,6 +2759,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) @@ -2673,6 +2821,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) @@ -2752,6 +2902,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) @@ -2812,6 +2964,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 @@ -2835,6 +2989,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 @@ -2858,6 +3014,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) { @@ -2878,6 +3036,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 @@ -3196,6 +3356,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; @@ -3233,6 +3395,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); @@ -3300,6 +3464,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); @@ -3363,6 +3529,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); @@ -3403,6 +3571,16 @@ out_err: #endif } +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); + return atom_ok; +} + /* HMAC */ diff --git a/lib/crypto/doc/src/crypto.xml b/lib/crypto/doc/src/crypto.xml index c95827c371..e88bf01491 100644 --- a/lib/crypto/doc/src/crypto.xml +++ b/lib/crypto/doc/src/crypto.xml @@ -556,6 +556,21 @@ </desc> </func> + <func> + <name>rand_seed(Seed) -> ok</name> + <fsummary>Set the seed for random bytes generation</fsummary> + <type> + <v>Seed = binary()</v> + </type> + <desc> + <p>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 <seealso marker="#strong_rand_bytes/1"> + stong_rand_bytes/1</seealso> returns <c>low_entropy</c></p> + </desc> + </func> + <func> <name>rand_uniform(Lo, Hi) -> N</name> <fsummary>Generate a random number</fsummary> 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 8efd962283..63552d2e70 100644 --- a/lib/crypto/test/crypto_SUITE.erl +++ b/lib/crypto/test/crypto_SUITE.erl @@ -105,7 +105,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 = <<H:24,M:20,L:20>>, + crypto:rand_seed(<< <<Bin/binary>> || _ <- lists:seq(1,16) >>), + Config + end catch _:_ -> {skip, "Crypto did not start"} end. diff --git a/lib/erl_interface/aclocal.m4 b/lib/erl_interface/aclocal.m4 index 46b30a16b3..c51c26794a 100644 --- a/lib/erl_interface/aclocal.m4 +++ b/lib/erl_interface/aclocal.m4 @@ -74,6 +74,19 @@ 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_ARG_VAR(erl_xcomp_ose_CONFD, [OSE OSE confd source file]) +AC_ARG_VAR(erl_xcomp_ose_CRT0_LM, [OSE crt0 lm source file]) + ]) AC_DEFUN(ERL_XCOMP_SYSROOT_INIT, @@ -488,6 +501,8 @@ AC_CACHE_VAL(ac_cv_sys_ipv6_support, #ifdef __WIN32__ #include <winsock2.h> #include <ws2tcpip.h> +#elif __OSE__ +#error "no ipv6" #else #include <netinet/in.h> #endif], @@ -500,6 +515,8 @@ else #ifdef __WIN32__ #include <winsock2.h> #include <ws2tcpip.h> +#elif __OSE__ +#error "no ipv6" #else #include <netinet/in.h> #endif], @@ -728,6 +745,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 +1101,22 @@ 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 + AC_CHECK_HEADER(ose_spi/ose_spi.h, + AC_DEFINE(HAVE_OSE_SPI_H, 1, + [Define if you have the "ose_spi/ose_spi.h" header file.])) + ;; + 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 +1175,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 +1188,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 <pthread.h> header file.])) @@ -1184,7 +1220,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 +1347,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/kernel/doc/src/Makefile b/lib/kernel/doc/src/Makefile index de3ca1e176..ec5d1f09e4 100644 --- a/lib/kernel/doc/src/Makefile +++ b/lib/kernel/doc/src/Makefile @@ -76,8 +76,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_REF4_FILES)\ + $(XML_REF6_FILES) $(XML_APPLICATION_FILES) # ---------------------------------------------------- diff --git a/lib/kernel/doc/src/ref_man.xml b/lib/kernel/doc/src/ref_man.xml index c1b9eac9d7..bd25d1e78d 100644 --- a/lib/kernel/doc/src/ref_man.xml +++ b/lib/kernel/doc/src/ref_man.xml @@ -13,12 +13,12 @@ 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. - + </legalnotice> <title>Kernel Reference Manual</title> @@ -65,4 +65,3 @@ <xi:include href="app.xml"/> <xi:include href="config.xml"/> </application> - 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 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE application SYSTEM "application.dtd"> + +<application xmlns:xi="http://www.w3.org/2001/XInclude"> + <header> + <copyright> + <year>1996</year><year>2013</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + 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. + + </legalnotice> + + <title>Kernel Reference Manual</title> + <prepared></prepared> + <docno></docno> + <date></date> + <rev></rev> + </header> + <description> + <p>The <em>Kernel</em> application has all the code necessary to run + the Erlang runtime system itself: file servers and code servers + and so on.</p> + </description> + <xi:include href="kernel_app.xml"/> + <xi:include href="application.xml"/> + <xi:include href="auth.xml"/> + <xi:include href="code.xml"/> + <xi:include href="disk_log.xml"/> + <xi:include href="erl_boot_server.xml"/> + <xi:include href="erl_ddll.xml"/> + <xi:include href="erl_prim_loader_stub.xml"/> + <xi:include href="erlang_stub.xml"/> + <xi:include href="error_handler.xml"/> + <xi:include href="error_logger.xml"/> + <xi:include href="file.xml"/> + <xi:include href="gen_tcp.xml"/> + <xi:include href="gen_udp.xml"/> + <xi:include href="gen_sctp.xml"/> + <xi:include href="global.xml"/> + <xi:include href="global_group.xml"/> + <xi:include href="heart.xml"/> + <xi:include href="inet.xml"/> + <xi:include href="inet_res.xml"/> + <xi:include href="init_stub.xml"/> + <xi:include href="net_adm.xml"/> + <xi:include href="net_kernel.xml"/> + <xi:include href="os.xml"/> + <xi:include href="pg2.xml"/> + <xi:include href="rpc.xml"/> + <xi:include href="seq_trace.xml"/> + <xi:include href="user.xml"/> + <xi:include href="wrap_log_reader.xml"/> + <xi:include href="zlib_stub.xml"/> + <xi:include href="app.xml"/> + <xi:include href="config.xml"/> +</application> diff --git a/lib/kernel/test/file_SUITE.erl b/lib/kernel/test/file_SUITE.erl index c75639ae7e..6b52493f46 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), @@ -1246,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). @@ -2030,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(), @@ -2140,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(), @@ -2171,13 +2189,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. @@ -2220,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 199e597e78..3e6a85eadd 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. @@ -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 + {ok,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), @@ -843,7 +846,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 +1571,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 +1659,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; + {unix, _ } -> OtherFs = "/tmp", ?line NameOnOtherFs = filename:join(OtherFs, @@ -1681,10 +1689,8 @@ e_rename(Config) when is_list(Config) -> Else end, Com; - {win32, _} -> - %% At least Windows NT can - %% successfully move a file to - %% another drive. + {ose, _} -> + %% disabled for now ok end, ?line test_server:timetrap_cancel(Dog), @@ -1714,14 +1720,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 +1773,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. diff --git a/lib/megaco/aclocal.m4 b/lib/megaco/aclocal.m4 index 46b30a16b3..c51c26794a 100644 --- a/lib/megaco/aclocal.m4 +++ b/lib/megaco/aclocal.m4 @@ -74,6 +74,19 @@ 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_ARG_VAR(erl_xcomp_ose_CONFD, [OSE OSE confd source file]) +AC_ARG_VAR(erl_xcomp_ose_CRT0_LM, [OSE crt0 lm source file]) + ]) AC_DEFUN(ERL_XCOMP_SYSROOT_INIT, @@ -488,6 +501,8 @@ AC_CACHE_VAL(ac_cv_sys_ipv6_support, #ifdef __WIN32__ #include <winsock2.h> #include <ws2tcpip.h> +#elif __OSE__ +#error "no ipv6" #else #include <netinet/in.h> #endif], @@ -500,6 +515,8 @@ else #ifdef __WIN32__ #include <winsock2.h> #include <ws2tcpip.h> +#elif __OSE__ +#error "no ipv6" #else #include <netinet/in.h> #endif], @@ -728,6 +745,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 +1101,22 @@ 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 + AC_CHECK_HEADER(ose_spi/ose_spi.h, + AC_DEFINE(HAVE_OSE_SPI_H, 1, + [Define if you have the "ose_spi/ose_spi.h" header file.])) + ;; + 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 +1175,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 +1188,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 <pthread.h> header file.])) @@ -1184,7 +1220,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 +1347,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..c51c26794a 100644 --- a/lib/odbc/aclocal.m4 +++ b/lib/odbc/aclocal.m4 @@ -74,6 +74,19 @@ 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_ARG_VAR(erl_xcomp_ose_CONFD, [OSE OSE confd source file]) +AC_ARG_VAR(erl_xcomp_ose_CRT0_LM, [OSE crt0 lm source file]) + ]) AC_DEFUN(ERL_XCOMP_SYSROOT_INIT, @@ -488,6 +501,8 @@ AC_CACHE_VAL(ac_cv_sys_ipv6_support, #ifdef __WIN32__ #include <winsock2.h> #include <ws2tcpip.h> +#elif __OSE__ +#error "no ipv6" #else #include <netinet/in.h> #endif], @@ -500,6 +515,8 @@ else #ifdef __WIN32__ #include <winsock2.h> #include <ws2tcpip.h> +#elif __OSE__ +#error "no ipv6" #else #include <netinet/in.h> #endif], @@ -728,6 +745,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 +1101,22 @@ 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 + AC_CHECK_HEADER(ose_spi/ose_spi.h, + AC_DEFINE(HAVE_OSE_SPI_H, 1, + [Define if you have the "ose_spi/ose_spi.h" header file.])) + ;; + 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 +1175,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 +1188,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 <pthread.h> header file.])) @@ -1184,7 +1220,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 +1347,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/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 --- /dev/null +++ b/lib/ose/doc/html/.gitignore diff --git a/lib/ose/doc/man3/.gitignore b/lib/ose/doc/man3/.gitignore new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/lib/ose/doc/man3/.gitignore diff --git a/lib/ose/doc/man6/.gitignore b/lib/ose/doc/man6/.gitignore new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/lib/ose/doc/man6/.gitignore diff --git a/lib/ose/doc/pdf/.gitignore b/lib/ose/doc/pdf/.gitignore new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/lib/ose/doc/pdf/.gitignore 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 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE book SYSTEM "book.dtd"> + +<book xmlns:xi="http://www.w3.org/2001/XInclude"> + <header titlestyle="normal"> + <copyright> + <year>2014</year><year>2014</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + 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. + + </legalnotice> + + <title>OSE</title> + <prepared>Lukas Larsson</prepared> + <docno></docno> + <date>2014-01-08</date> + <rev>1.0</rev> + <file>book.xml</file> + </header> + <insidecover> + </insidecover> + <pagetext>OSE</pagetext> + <preamble> + <contents level="2"></contents> + </preamble> + <parts> + <xi:include href="part.xml"/> + </parts> + <applications> + <xi:include href="ref_man.xml"/> + </applications> + <releasenotes> + <xi:include href="notes.xml"/> + </releasenotes> + <listofterms></listofterms> + <index></index> +</book> 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 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE chapter SYSTEM "chapter.dtd"> + +<chapter> + <header> + <copyright> + <year>2014</year><year>2014</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + 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. + + </legalnotice> + + <title>OSE Release Notes</title> + <prepared></prepared> + <docno></docno> + <date></date> + <rev></rev> + <file>notes.xml</file> + </header> + <p>This document describes the changes made to the OSE application.</p> + +</chapter> 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 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE appref SYSTEM "appref.dtd"> + +<appref> + <header> + <copyright> + <year>2014</year><year>2014</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + 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. + + </legalnotice> + + <title>Enea OSE</title> + <prepared></prepared> + <docno></docno> + <date></date> + <rev></rev> + </header> + <app>ose</app> + <appsummary>The OSE Application</appsummary> + <description> + <p>The OSE application contains modules and documentation that only + applies when running Erlang/OTP on Enea OSE.</p> + </description> + +</appref> 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..1d89d7aeea --- /dev/null +++ b/lib/ose/doc/src/ose_erl_driver.xml @@ -0,0 +1,110 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE cref SYSTEM "cref.dtd"> + +<cref> + <header> + <copyright> + <year>2013</year><year>2014</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + 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. + + </legalnotice> + + <title>erl_driver for Enea OSE</title> + <prepared>Lukas Larsson</prepared> + <docno></docno> + <date>2014-01-08</date> + <rev>A</rev> + <file>ose_erl_driver.xml</file> + </header> + <lib>ose_erl_driver</lib> + <libsummary>Linked-in drivers in Enea OSE</libsummary> + <description> + <p>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. + </p> + </description> + <section> + <title>DATA TYPES</title> + + <taglist> + <tag><marker id="union_SIGNAL"/>union SIGNAL</tag> + <item>See the Enea OSE SPI documentation for a description.</item> + <tag><marker id="SIGSELECT"/>SIGSELECT</tag> + <item>See the Enea OSE SPI documentation for a description.</item> + <tag><marker id="ErlDrvEvent"/>ErlDrvEvent</tag> + <item>The <c>ErlDrvEvent</c> is a handle to a signal number and id combination. It is passed to <seealso marker="erts:erl_driver#driver_select">driver_select(3)</seealso>.</item> + <tag><marker id="ErlDrvOseEventId"/>ErlDrvOseEventId</tag> + <item>This is the id used to associate a specific signal to a + certain driver instance. </item> + </taglist> + </section> + <funcs> + <func> + <name><ret>union SIGNAL *</ret><nametext>erl_drv_ose_get_signal(ErlDrvEvent drv_event)</nametext></name> + <desc> + <marker id="erl_drv_ose_get_signal"></marker> + <p>Fetch the next signal associated with <c>drv_event</c>. + Signals will be returned in the order which they were received and + when no more signals are available <c>NULL</c> will be returned. + Use this function in the ready_input/ready_output callbacks + to get signals.</p> + </desc> + </func> + <func> + <name><ret>ErlDrvEvent</ret><nametext>erl_drv_ose_event_alloc(SIGSELECT signo, ErlDrvOseEventId id, ErlDrvOseEventId (*resolve_signal)(union SIGNAL* sig), void *extra)</nametext></name> + <desc> + <marker id="erl_drv_ose_event_alloc"></marker> + <p>Create a new <c>ErlDrvEvent</c> associated with <c>signo</c>, + <c>id</c> and uses the <c>resolve_signal</c> function to extract + the <c>id</c> from a signal with <c>signo</c>. The <c>extra</c> + parameter can be used for additional data. See + <seealso marker="ose_signals_chapter#driver"> + Signals in a Linked-in driver</seealso> in the OSE User's Guide. + </p> + </desc> + </func> + <func> + <name><ret>void</ret><nametext>erl_drv_ose_event_free(ErlDrvEvent drv_event)</nametext></name> + <desc> + <marker id="erl_drv_ose_event_free"></marker> + <p>Free a <c>ErlDrvEvent</c>. This should always be done in the + <seealso marker="erts:driver_entry#stop_select">stop_select</seealso> + callback when the event is no longer being used.</p> + </desc> + </func> + <func> + <name><ret>void</ret><nametext>erl_drv_ose_event_fetch(ErlDrvEvent drv_event, SIGSELECT *signo, ErlDrvOseEventId *id, void **extra)</nametext></name> + <desc> + <marker id="erl_drv_ose_event_fetch"></marker> + <p>Write the signal number, id and any extra data associated with <c>drv_event</c> + into <c>*signo</c> and <c>*id</c> respectively. <c>NULL</c> can be + also passed as <c>signo</c> or <c>id</c> in order to ignore that field. + </p> + </desc> + </func> + </funcs> + <section> + <title>SEE ALSO</title> + <p> + <seealso marker="erts:driver_entry">driver_entry(3)</seealso>, + <seealso marker="erts:erl_driver">erl_driver(3)</seealso> + </p> + </section> +</cref> diff --git a/lib/ose/doc/src/ose_intro.xml b/lib/ose/doc/src/ose_intro.xml new file mode 100644 index 0000000000..0dd3ec409e --- /dev/null +++ b/lib/ose/doc/src/ose_intro.xml @@ -0,0 +1,153 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE chapter SYSTEM "chapter.dtd"> + +<chapter> + <header> + <copyright> + <year>2013</year><year>2014</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + 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. + + </legalnotice> + + <title>Introduction</title> + <prepared>Lukas Larsson</prepared> + <docno></docno> + <date>2014-01-08</date> + <rev>A</rev> + <file>ose_intro.xml</file> + </header> + + <section> + <title>Features</title> + </section> + + <section> + <title>Starting Erlang/OTP</title> + <p> + 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 <c>erl</c> on Unix/Windows has a + undocumented flag called <c>-emu_args_exit</c> that can be used to + figure out what the arguments to beam look like. For example:</p> + <code># 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 +--</code> + <p> + 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:</p> + <code>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</code> + <p> + 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 + <c>/usr/local/lib/erlang</c> was replaced by <c>/mst/erlang/</c>. 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. + </p> + <note> + 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. + </note> + </section> + + <section> + <title>run_erl and to_erl</title> + <p> + 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. One additional + option also exists to run_erl on ose: + <taglist> + <tag><c>-block Name</c></tag> + <item>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: + <code>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 --"</code> + </item> + </taglist> + The same argument munching as when starting Erlang/OTP without run_erl + has to be done. If <c>-daemon</c> is given then all error printouts + are sent to the ramlog. + See also + <seealso marker="erts:run_erl">run_erl</seealso> for more details. + </p> + <p> + Below is an example of how to get started with <c>run_erl_lm</c>. + <code>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.</code> + Note that Ctrl-C is used instead of Ctrl-D to exit the to_erl shell. + </p> + </section> + + <section> + <title>epmd</title> + <p> + In OSE epmd will not be started automatically so if you want to use + Erlang distribution you have to manually start epmd. + </p> + </section> + + <section> + <title>VM Process Priorities</title> + <p> + 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. + </p> + </section> + +</chapter> 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..ff501777cc --- /dev/null +++ b/lib/ose/doc/src/ose_signals_chapter.xml @@ -0,0 +1,239 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE chapter SYSTEM "chapter.dtd"> + +<chapter> + <header> + <copyright> + <year>2013</year><year>2014</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + 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. + + </legalnotice> + + <title>Interacting with Enea OSE</title> + <prepared>Lukas Larsson</prepared> + <docno></docno> + <date>2014-01-08</date> + <rev>A</rev> + <file>ose_signals_chapter.xml</file> + </header> + + <marker id="introduction"></marker> + <section> + <title>Introduction</title> + <p>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 <c>ose</c> module, or by writing a custom linked-in + driver. This User's Guide describes and provides examples for both + approaches. + </p> + </section> + + <marker id="erlang"></marker> + <section> + <title>Signals in Erlang</title> + <p>Erlang/OTP on OSE provides a erlang module called + <seealso marker="ose:ose">ose</seealso> 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. + </p> + <code>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</code> + </section> + + <marker id="driver"></marker> + <section> + <title>Signals in a Linked-in driver</title> + <p> + 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. + </p> + <p> + 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: + <code>ErlDrvEvent event = erl_drv_ose_event_alloc(1234,port,resolver);</code> + The event you get back from + <seealso marker="ose_erl_driver#erl_drv_ose_event_alloc"> + erl_drv_ose_event_alloc</seealso> can then be used by + <seealso marker="erts:erl_driver#driver_select">driver_select</seealso> + 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 + <seealso marker="erts:driver_entry#start">start</seealso> 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. 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 + <seealso marker="ose_erl_driver#erl_drv_ose_event_fetch">erl_drv_ose_event_fetch</seealso> + , eg: + <code>erl_drv_ose_event_fetch(event, &signal, &port, (void **)&extra);</code> + example of what this could look like in + <seealso marker="#example">the next section</seealso>. + <note>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.</note> + </p> + <p> + 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 <seealso marker="ose_erl_driver#erl_drv_ose_get_signal"> + erl_drv_ose_get_signal</seealso>. Additionally multiple signals might be + associated with the event, so you should call + <seealso marker="ose_erl_driver#erl_drv_ose_get_signal"> + erl_drv_ose_get_signal</seealso> until <c>NULL</c> is returned. + </p> + </section> + + <marker id="example"></marker> + <section> + <title>Example Linked-in driver</title> +<code>#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; + + /* 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, 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 + 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) { + 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) }; + 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) +{ + /* 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); +} + +/** + * 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 +}; +</code> + </section> + +</chapter> 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 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE part SYSTEM "part.dtd"> + +<part xmlns:xi="http://www.w3.org/2001/XInclude"> + <header> + <copyright> + <year>2014</year> + <year>2014</year> + <holder>Ericsson AB, All Rights Reserved</holder> + </copyright> + <legalnotice> + 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. + </legalnotice> + + <title>OSE User's Guide</title> + <prepared>Lukas Larsson</prepared> + <docno></docno> + <date>2014-01-08</date> + <rev>1.0</rev> + <file>part.xml</file> + </header> + <description> + <p><em>OSE</em>.</p> + </description> + <xi:include href="ose_intro.xml"/> + <xi:include href="ose_signals_chapter.xml"/> +</part> 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 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE application SYSTEM "application.dtd"> + +<application xmlns:xi="http://www.w3.org/2001/XInclude"> + <header> + <copyright> + <year>2014</year><year>2014</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + 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. + + </legalnotice> + + <title>OSE Reference Manual</title> + <prepared>Lukas Larsson</prepared> + <docno></docno> + <date>2014-01-08</date> + <rev>1.0</rev> + <file>ref_man.xml</file> + </header> + <description> + <p>The Standard Erlang Libraries application, <em>STDLIB</em>, + contains modules for manipulating lists, strings and files etc.</p> + <br></br> + </description> + <xi:include href="ose_app.xml"/> + <xi:include href="ose.xml"/> + <xi:include href="ose_erl_driver.xml"/> +</application> diff --git a/lib/ose/ebin/.gitignore b/lib/ose/ebin/.gitignore new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/lib/ose/ebin/.gitignore diff --git a/lib/ose/include/.gitignore b/lib/ose/include/.gitignore new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/lib/ose/include/.gitignore 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..77f11addf9 --- /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 listen/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:32>> -> 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, <<Pid:32>>) 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, <<?DEHUNT:8, Ref:32>>) 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, <<?ATTACH:8, Spid:32>>) 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, <<?DETACH:8, Ref:32>>) 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, [<<?SEND:8, Spid:32, SigNo:32>>, 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, [<<?SEND_W_S:8, Spid:32, SenderPid:32, + SigNo:32>>, 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:32>> || + 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 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/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">>, <<Drive:8,":/">>), 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 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..c51c26794a 100644 --- a/lib/wx/aclocal.m4 +++ b/lib/wx/aclocal.m4 @@ -74,6 +74,19 @@ 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_ARG_VAR(erl_xcomp_ose_CONFD, [OSE OSE confd source file]) +AC_ARG_VAR(erl_xcomp_ose_CRT0_LM, [OSE crt0 lm source file]) + ]) AC_DEFUN(ERL_XCOMP_SYSROOT_INIT, @@ -488,6 +501,8 @@ AC_CACHE_VAL(ac_cv_sys_ipv6_support, #ifdef __WIN32__ #include <winsock2.h> #include <ws2tcpip.h> +#elif __OSE__ +#error "no ipv6" #else #include <netinet/in.h> #endif], @@ -500,6 +515,8 @@ else #ifdef __WIN32__ #include <winsock2.h> #include <ws2tcpip.h> +#elif __OSE__ +#error "no ipv6" #else #include <netinet/in.h> #endif], @@ -728,6 +745,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 +1101,22 @@ 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 + AC_CHECK_HEADER(ose_spi/ose_spi.h, + AC_DEFINE(HAVE_OSE_SPI_H, 1, + [Define if you have the "ose_spi/ose_spi.h" header file.])) + ;; + 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 +1175,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 +1188,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 <pthread.h> header file.])) @@ -1184,7 +1220,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 +1347,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) |