static ERL_NIF_TERM make_keypair_record(ErlNifEnv *env, brine_keypair_s *keypair) { return enif_make_tuple4(env, enif_make_copy(env, BRINE_ATOM_KEYPAIR), enif_make_resource(env, (void *) keypair), // private key enif_make_resource_binary(env, (void *) keypair, (void *) keypair->private_key, BRINE_PRIVKEY_SZ), // public key enif_make_resource_binary(env, (void *) keypair, (void *) keypair->public_key, BRINE_PUBKEY_SZ)); }
static ERL_NIF_TERM exmagick_image_dump_blob (ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { void *blob; size_t size; exm_resource_t *resource; EXM_INIT; ErlNifResourceType *type = (ErlNifResourceType *) enif_priv_data(env); if (0 == enif_get_resource(env, argv[0], type, (void **) &resource)) { EXM_FAIL(ehandler, "invalid handle"); } blob = ImageToBlob(resource->i_info, resource->image, &size, &resource->e_info); if (NULL == blob) { CatchException(&resource->e_info); EXM_FAIL(ehandler, resource->e_info.reason); } return(enif_make_tuple2(env, enif_make_atom(env, "ok"), enif_make_resource_binary(env, resource, blob, size))); ehandler: return(enif_make_tuple2(env, enif_make_atom(env, "error"), exmagick_make_utf8str(env, errmsg))); }
static ERL_NIF_TERM _open(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { CAN_handle* handle; ERL_NIF_TERM result; char dev_path[512]; if (!enif_get_string(env, argv[0], dev_path, 512, ERL_NIF_LATIN1)) return enif_make_int(env, -2000); handle = enif_alloc_resource(CAN_handle_type, sizeof(CAN_handle)); memset(handle, 0, sizeof(CAN_handle)); handle->device = open((const char*)dev_path, O_RDWR | O_SYNC); if (!enif_get_int(env, argv[1], &handle->raw)) return enif_make_int(env, -2001); handle->threaded = 0; if (handle->device >= 0) { int len = strlen(dev_path); result = enif_make_resource(env, handle); handle->devpath = enif_alloc(len); memcpy(handle->devpath, dev_path, len); handle->devpath_bin = enif_make_resource_binary(env, handle, handle->devpath, len); } else { result = enif_make_int(env, errno); } enif_release_resource(handle); return result; }
static ERL_NIF_TERM emmap_pread(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { unsigned long pos, bytes; mhandle *handle; if (argc==3 && enif_get_resource(env, argv[0], MMAP_RESOURCE, (void**)&handle) && enif_get_ulong(env, argv[1], &pos) && enif_get_ulong(env, argv[2], &bytes) && pos >= 0 && bytes >= 0 && (pos + bytes) <= handle->len ) { ErlNifBinary bin; if ((handle->prot & PROT_READ) == 0) { return make_error_tuple(env, EACCES); } // if this mmap is direct, use a resource binary if (handle->direct) { ERL_NIF_TERM res = enif_make_resource_binary (env, handle, (void*) (((char*)handle->mem) + pos), bytes); return enif_make_tuple2(env, ATOM_OK, res); } else { // When it is non-direct, we have to allocate the binary if (!enif_alloc_binary((size_t) bytes, &bin)) { return make_error_tuple(env, ENOMEM); } R_LOCK; if (handle->closed) { R_UNLOCK; return enif_make_badarg(env); } memcpy(bin.data, (void*) (((char*)handle->mem) + pos), bytes); R_UNLOCK; ERL_NIF_TERM res = enif_make_binary(env, &bin); return enif_make_tuple2(env, ATOM_OK, res); } } else { return enif_make_badarg(env); } }
static ERL_NIF_TERM emmap_read(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { mhandle *handle; unsigned long bytes; if (enif_get_resource(env, argv[0], MMAP_RESOURCE, (void**)&handle) && enif_get_ulong(env, argv[1], &bytes)) { RW_LOCK; if (handle->position == handle->len) { RW_UNLOCK; return ATOM_EOF; } unsigned long new_pos = handle->position + bytes; if (new_pos > handle->len) { new_pos = handle->len; } long size = new_pos - handle->position; long start = handle->position; handle->position = new_pos; RW_UNLOCK; if (handle->direct) { ERL_NIF_TERM res = enif_make_resource_binary (env, handle, (void*) (((char*)handle->mem) + start), size); return enif_make_tuple2(env, ATOM_OK, res); } else { ErlNifBinary bin; // When it is non-direct, we have to allocate the binary if (!enif_alloc_binary((size_t) size, &bin)) { return make_error_tuple(env, ENOMEM); } memcpy(bin.data, (void*) (((char*)handle->mem) + start), size); ERL_NIF_TERM res = enif_make_binary(env, &bin); return enif_make_tuple2(env, ATOM_OK, res); } } else { return enif_make_badarg(env); } }
void nif_write(couchfile_modify_request *rq, couchfile_pointer_info *dst, nif_writerq* wrq, ssize_t size) { dst->writerq_resource = wrq; dst->pointer = 0; wrq->ptr = dst; ErlNifEnv* msg_env = enif_alloc_env(); ERL_NIF_TERM msg_term = enif_make_tuple4(msg_env, get_atom(msg_env, "append_bin_btnif"), get_atom(msg_env, "snappy"), //COMPRESSION TYPE enif_make_resource(msg_env, wrq), enif_make_resource_binary(msg_env, wrq, &wrq->buf, size)); enif_send(rq->caller_env, &rq->writer, msg_env, msg_term); enif_free_env(msg_env); enif_release_resource(wrq); }
static ERL_NIF_TERM mpegts_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { Mpegts *ts; ERL_NIF_TERM reply; char info[] = "MPEG-TS decoder"; ts = (Mpegts *)enif_alloc_resource(MpegtsResource, sizeof(Mpegts)); ts->desc = (char *)malloc(sizeof(info)+1); memcpy(ts->desc, info, strlen(info) + 1); ts->last_ts_size = 0; ts->pmt = 0xFFFF; reply = enif_make_resource_binary(env, (void *)ts, ts->desc, strlen(ts->desc)); enif_release_resource(ts); return reply; }
static ERL_NIF_TERM make_new_resource_binary(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { ErlNifBinary data_bin; union { struct binary_resource* p; void* vp; long l;} br; void* buf; ERL_NIF_TERM ret; if (!enif_inspect_binary(env, argv[0], &data_bin) || (br.vp = enif_alloc_resource(binary_resource_type, sizeof(struct binary_resource)))==NULL || (buf = enif_alloc(data_bin.size)) == NULL) { return enif_make_badarg(env); } memset(br.vp,0xba,sizeof(struct binary_resource)); /* avoid valgrind warning */ br.p->data = buf; br.p->size = data_bin.size; memcpy(br.p->data, data_bin.data, data_bin.size); ret = enif_make_resource_binary(env, br.vp, br.p->data, br.p->size); enif_release_resource(br.p); return enif_make_tuple2(env, enif_make_long(env,br.l), ret); }
static ERL_NIF_TERM mmap_open(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { Mmap *desc; ERL_NIF_TERM f; ErlNifBinary bin_path; char path[PATH_SIZE]; int fd; struct stat st; int debug = 0; ERL_NIF_TERM opt, opts; if (!enif_inspect_binary(env, argv[0], &bin_path)) { return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_string(env, "Should pass binary filename", ERL_NIF_LATIN1)); } if (!enif_is_list(env, argv[1])) { return enif_make_badarg(env); } bzero(path, PATH_SIZE); strncpy(path, (const char *)bin_path.data, bin_path.size >= PATH_SIZE ? PATH_SIZE - 1 : bin_path.size); opts = argv[1]; while(enif_get_list_cell(env, opts, &opt, &opts)) { if(!enif_compare(opt, enif_make_atom(env, "debug"))) { debug = 1; } } fd = open(path, O_RDONLY); if(fd == -1) { return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_string(env, strerror(errno), ERL_NIF_LATIN1)); } if(fstat(fd, &st)) { close(fd); return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_string(env, strerror(errno), ERL_NIF_LATIN1)); } if (debug) fprintf(stderr, "Opened file %s %ld\r\n", path, (ssize_t)st.st_size); desc = (Mmap *)enif_alloc_resource(MmapResource, sizeof(Mmap)); if(!desc) { close(fd); return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_string(env, "Couldn't allocate mmap resource", ERL_NIF_LATIN1)); } desc->fd = fd; desc->size = st.st_size; if (debug) fprintf(stderr, "Mmaping file: %p\r\n", desc); desc->ptr = mmap(NULL, desc->size, PROT_READ, MAP_FILE | MAP_PRIVATE, desc->fd, 0); close(fd); if(desc->ptr == MAP_FAILED) { enif_release_resource(desc); return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_string(env, "Couldn't mmap", ERL_NIF_LATIN1)); } if (debug) fprintf(stderr, "Mmaped file to %p\r\n", desc->ptr); f = enif_make_resource_binary(env, (void *)desc, desc->ptr, desc->size); enif_release_resource(desc); desc->debug = debug; return enif_make_tuple2(env, enif_make_atom(env, "ok"), f); }
static ERL_NIF_TERM get(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { ERL_NIF_TERM atom; ErlNifBinary kbin; struct cache *c; struct cache_node *n; struct cache_incr_node *in; struct timespec now; int incrqs, hashv, bkt; ERL_NIF_TERM ret; ErlNifTid tid; if (!enif_is_atom(env, argv[0])) return enif_make_badarg(env); atom = argv[0]; if (!enif_inspect_binary(env, argv[1], &kbin)) return enif_make_badarg(env); if ((c = get_cache(atom))) { enif_rwlock_rlock(c->lookup_lock); HASH_FIND(hh, c->lookup, kbin.data, kbin.size, n); if (!n) { enif_rwlock_runlock(c->lookup_lock); __sync_add_and_fetch(&c->miss, 1); enif_consume_timeslice(env, 10); return enif_make_atom(env, "notfound"); } if (n->expiry.tv_sec != 0) { clock_now(&now); if (n->expiry.tv_sec < now.tv_sec) { enif_rwlock_runlock(c->lookup_lock); __sync_add_and_fetch(&c->miss, 1); enif_consume_timeslice(env, 10); return enif_make_atom(env, "notfound"); } } in = enif_alloc(sizeof(*in)); memset(in, 0, sizeof(*in)); in->node = n; __sync_add_and_fetch(&c->hit, 1); tid = enif_thread_self(); HASH_SFH(&tid, sizeof(ErlNifTid), N_INCR_BKT, hashv, bkt); enif_mutex_lock(c->incr_lock[bkt]); TAILQ_INSERT_TAIL(&(c->incr_head[bkt]), in, entry); enif_mutex_unlock(c->incr_lock[bkt]); incrqs = __sync_add_and_fetch(&(c->incr_count), 1); ret = enif_make_resource_binary(env, n->val, n->val, n->vsize); enif_rwlock_runlock(c->lookup_lock); if (incrqs > 1024) enif_cond_broadcast(c->check_cond); enif_consume_timeslice(env, 20); return ret; } return enif_make_atom(env, "notfound"); }