static ERL_NIF_TERM return_so_far(ErlNifEnv *env, ecsv_parser_t *parser) { if (parser->err) return enif_raise_exception(env, atoms.insufficient_memory); if (env != parser->env) { // it should never happen return enif_raise_exception(env, enif_make_atom(env, "env_mismatch")); } copy_current_line(enif_alloc_env(), parser); return parser->lines; }
static ERL_NIF_TERM call_dirty_nif_exception(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { switch (argc) { case 1: { int arg; if (enif_get_int(env, argv[0], &arg) && arg < 2) { ERL_NIF_TERM args[255]; int i; args[0] = argv[0]; for (i = 1; i < 255; i++) args[i] = enif_make_int(env, i); return enif_schedule_nif(env, "call_dirty_nif_exception", ERL_NIF_DIRTY_JOB_CPU_BOUND, call_dirty_nif_exception, 255, args); } else { return enif_raise_exception(env, argv[0]); } } case 2: { int return_badarg_directly; enif_get_int(env, argv[0], &return_badarg_directly); assert(return_badarg_directly == 1 || return_badarg_directly == 0); if (return_badarg_directly) return enif_make_badarg(env); else { /* ignore return value */ enif_make_badarg(env); return enif_make_atom(env, "ok"); } } default: return enif_schedule_nif(env, "call_dirty_nif_exception", ERL_NIF_DIRTY_JOB_CPU_BOUND, call_dirty_nif_exception, argc-1, argv); } }
/* For OpenSSL >= 1.1.1 the hmac_nif and cmac_nif could be integrated into poly1305 (with 'type' as parameter) */ ERL_NIF_TERM poly1305_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {/* (Key, Text) */ #ifdef HAVE_POLY1305 ErlNifBinary key_bin, text, ret_bin; ERL_NIF_TERM ret; EVP_PKEY *key = NULL; EVP_MD_CTX *mctx = NULL; EVP_PKEY_CTX *pctx = NULL; const EVP_MD *md = NULL; size_t size; int ret_bin_alloc = 0; ASSERT(argc == 2); if (!enif_inspect_binary(env, argv[0], &key_bin)) goto bad_arg; if (key_bin.size != 32) goto bad_arg; if (!enif_inspect_binary(env, argv[1], &text)) goto bad_arg; if ((key = EVP_PKEY_new_raw_private_key(EVP_PKEY_POLY1305, /*engine*/ NULL, key_bin.data, key_bin.size)) == NULL) goto err; if ((mctx = EVP_MD_CTX_new()) == NULL) goto err; if (EVP_DigestSignInit(mctx, &pctx, md, /*engine*/ NULL, key) != 1) goto err; if (EVP_DigestSignUpdate(mctx, text.data, text.size) != 1) goto err; if (EVP_DigestSignFinal(mctx, NULL, &size) != 1) goto err; if (!enif_alloc_binary(size, &ret_bin)) goto err; ret_bin_alloc = 1; if (EVP_DigestSignFinal(mctx, ret_bin.data, &size) != 1) goto err; if (size != ret_bin.size) { if (!enif_realloc_binary(&ret_bin, size)) goto err; } ret = enif_make_binary(env, &ret_bin); ret_bin_alloc = 0; goto done; bad_arg: return enif_make_badarg(env); err: if (ret_bin_alloc) enif_release_binary(&ret_bin); ret = atom_error; done: if (mctx) EVP_MD_CTX_free(mctx); if (key) EVP_PKEY_free(key); return ret; #else return enif_raise_exception(env, atom_notsup); #endif }