/* 0: file descriptor, 1: backlog */ static ERL_NIF_TERM nif_listen(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { int s = -1; int backlog = 5; if (!enif_get_int(env, argv[0], &s)) return enif_make_badarg(env); if (!enif_get_int(env, argv[1], &backlog)) return enif_make_badarg(env); if (listen(s, backlog) < 0) return error_tuple(env, errno); return atom_ok; }
static ERL_NIF_TERM get_element(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { State *state; int i, j; if (!enif_get_int(env, argv[1], &i))return enif_make_badarg(env); if (!enif_get_resource(env, argv[0], my_array_type, (void **)&state)) return enif_make_badarg(env); j = state->data[i]; return enif_make_int(env, j); }
static ERL_NIF_TERM gc(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { int i=0 , timestamp = 0; CHECK(enif_get_int(env, argv[0], ×tamp)); for(i=0; i<BUCKET_SIZE; i++) { if(hashmap[i]>0) { walk_hash(&hashmap[i],timestamp,NULL, 0); } } return enif_make_atom(env, "ok"); }
static ERL_NIF_TERM set_owner_nif(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { posix_errno_t posix_errno; efile_path_t path; Sint32 uid, gid; if(argc != 3 || !enif_get_int(env, argv[1], &uid) || !enif_get_int(env, argv[2], &gid)) { return enif_make_badarg(env); } if((posix_errno = efile_marshal_path(env, argv[0], &path))) { return posix_error_to_tuple(env, posix_errno); } else if((posix_errno = efile_set_owner(&path, uid, gid))) { return posix_error_to_tuple(env, posix_errno); } return am_ok; }
static ERL_NIF_TERM get_resource_type(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { PrivData* data = (PrivData*) enif_priv_data(env); int ix; if (!enif_get_int(env, argv[0], &ix) || ix >= 2) { return enif_make_badarg(env); } return enif_make_long(env, data->rt_arr[ix].l); }
static int test_int(ErlNifEnv* env, int i1) { int i2 = 0; ERL_NIF_TERM int_term = enif_make_int(env, i1); if (!enif_get_int(env,int_term, &i2) || i1 != i2) { fprintf(stderr, "test_int(%d) ...FAILED i2=%d\r\n", i1, i2); return 0; } return 1; }
static inline int match_int(ErlNifEnv* env, ERL_NIF_TERM term, State *st){ int ip, n; if(!enif_get_int(env, term, &ip)) return 0; b_reserve(24, st); n = sprintf((char*)(st->cur), "%d", ip); b_seek(n, st); return 1; }
// c_soc:op_alloc(ParentKey, Tuple, Arity) => ok static ERL_NIF_TERM op_alloc(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { soc::State* st = (soc::State*) enif_priv_data(env); int parentKey; int parentKeyInt; ERL_NIF_TERM* tuple; ERL_NIF_TERM* tupleInt; int tupleArity; int tupleArityInt; int arity; int arityInt; if (enif_get_int(env, argv[0], &parentKey) == 0) { printf("[op_alloc] error: failed to get parentKey\n"); return -1; } parentKeyInt = enif_make_copy(st->GetEnv(), parentKey); if (enif_get_tuple(env, argv[1], &tupleArity, &tuple) == 0) { printf("[op_alloc] error: failed to get tuple\n"); return -1; } (*tupleInt) = enif_make_copy(st->GetEnv(), (*tuple)); tupleArityInt = enif_make_copy(st->GetEnv(), tupleArity); if (enif_get_int(env, argv[2], &arity) == 0) { printf("[op_alloc] error: failed to initialize arity\n"); return -1; } arityInt = enif_make_copy(st->GetEnv(), arity); printf("operation start\n"); soc::Operation* op = new soc::Operation(parentKeyInt, tupleInt, tupleArityInt, arityInt); int currentIndex = st->Insert(op); int currentIndexExt = enif_make_copy(env, currentIndex); printf("operation index: %d end\n", currentIndexExt); return enif_make_int(env, currentIndexExt); }
static ERL_NIF_TERM closesockfd(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { int fd; enif_get_int(env, argv[0], &fd); sock_close(fd); return enif_make_int(env, fd); }
void* cb_mget_args(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { mget_args_t* args = (mget_args_t*)enif_alloc(sizeof(mget_args_t)); ERL_NIF_TERM* currKey; ERL_NIF_TERM tail; ErlNifBinary key_binary; if (!enif_get_list_length(env, argv[0], &args->numkeys)) goto error0; args->keys = malloc(sizeof(char*) * args->numkeys); args->nkeys = malloc(sizeof(size_t) * args->numkeys); currKey = malloc(sizeof(ERL_NIF_TERM)); tail = argv[0]; int i = 0; while(0 != enif_get_list_cell(env, tail, currKey, &tail)) { if (!enif_inspect_iolist_as_binary(env, *currKey, &key_binary)) goto error1; args->keys[i] = malloc(sizeof(char) * key_binary.size); memcpy(args->keys[i], key_binary.data, key_binary.size); args->nkeys[i] = key_binary.size; i++; } if (!enif_get_int(env, argv[1], &args->exp)) goto error1; if (!enif_get_int(env, argv[2], &args->lock)) goto error1; free(currKey); return (void*)args; int f = 0; error1: for(f = 0; f < i; f++) { free(args->keys[f]); } free(args->keys); free(args->nkeys); free(currKey); error0: enif_free(args); return NULL; }
/* 0: socket, 1: length, 2: flags, 3: struct sockaddr length */ static ERL_NIF_TERM nif_recvfrom(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { int sockfd = -1; unsigned long len = 0; unsigned long salen = 0; int flags = 0; ErlNifBinary buf = {0}; ErlNifBinary sa = {0}; ssize_t bufsz = 0; if (!enif_get_int(env, argv[0], &sockfd)) return enif_make_badarg(env); if (!enif_get_ulong(env, argv[1], &len)) return enif_make_badarg(env); if (!enif_get_int(env, argv[2], &flags)) return enif_make_badarg(env); if (!enif_get_ulong(env, argv[3], &salen)) return enif_make_badarg(env); if (!enif_alloc_binary(len, &buf)) return error_tuple(env, ENOMEM); if (!enif_alloc_binary(salen, &sa)) return error_tuple(env, ENOMEM); if ( (bufsz = recvfrom(sockfd, buf.data, buf.size, flags, (sa.size == 0 ? NULL : (struct sockaddr *)sa.data), (socklen_t *)&salen)) == -1) { int err = errno; enif_release_binary(&buf); enif_release_binary(&sa); return error_tuple(env, err); } PROCKET_REALLOC(buf, bufsz); PROCKET_REALLOC(sa, salen); return enif_make_tuple3(env, atom_ok, enif_make_binary(env, &buf), enif_make_binary(env, &sa)); }
/*-----------------------------------------------------------------------------------------------------------------------*/ static ERL_NIF_TERM get_group(ErlNifEnv* env, int32_t argc, ERL_NIF_TERM const argv[]) { ERL_NIF_TERM pres; ERL_NIF_TERM mres; ERL_NIF_TERM gres; ParserRes* parser = NULL; FIXMsg* msg = NULL; FIXGroup* group = NULL; ERL_NIF_TERM res = get_parser_msg_group(env, argv[0], &pres, &mres, &gres, &parser, &msg, &group); if (res != ok_atom) { return res; } int32_t tagNum = 0; if (!enif_get_int(env, argv[1], &tagNum)) { return make_error(env, FIX_FAILED, "Wrong tag num."); } int32_t idx = 0; if (!enif_get_int(env, argv[2], &idx)) { return make_error(env, FIX_FAILED, "Wrong idx."); } FIXError* error = NULL; pthread_rwlock_rdlock(&parser->lock); FIXGroup* ret_group = fix_msg_get_group(msg, group, tagNum, idx, &error); pthread_rwlock_unlock(&parser->lock); if (!ret_group) { ERL_NIF_TERM ret = make_parser_error(env, fix_error_get_code(error), fix_error_get_text(error)); fix_error_free(error); return ret; } FIXGroup** grp = (FIXGroup**)enif_alloc_resource(group_res, sizeof(FIXGroup*)); *grp = ret_group; ERL_NIF_TERM grp_term = enif_make_resource(env, grp); enif_release_resource(grp); return enif_make_tuple2(env, ok_atom, enif_make_tuple2( env, group_atom, enif_make_tuple3(env, pres, mres, grp_term))); }
static ERL_NIF_TERM serial_data_avail_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { int handle; if (!enif_get_int(env, argv[0], &handle)) { return enif_make_badarg(env); } int data_avail = serialDataAvail(handle); return enif_make_int(env, data_avail); }
static ERL_NIF_TERM serial_flush_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { int handle; if (!enif_get_int(env, argv[0], &handle)) { return enif_make_badarg(env); } serialFlush(handle); return atom_ok; }
static ERL_NIF_TERM lcd_clear_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { int handle; if (!enif_get_int(env, argv[0], &handle)) { return enif_make_badarg(env); } lcdClear(handle); return atom_ok; }
// SPI static ERL_NIF_TERM spi_get_fd_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { int channel; if (!enif_get_int(env, argv[0], &channel)) { return enif_make_badarg(env); } int fd = wiringPiSPIGetFd(channel); return enif_make_int(env, fd); }
/* 0: errno */ static ERL_NIF_TERM nif_errno_id(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { int err = -1; if (!enif_get_int(env, argv[0], &err)) return enif_make_badarg(env); return enif_make_atom(env, erl_errno_id(err)); }
static ERL_NIF_TERM serial_get_char_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { int handle; if (!enif_get_int(env, argv[0], &handle)) { return enif_make_badarg(env); } int c = serialGetchar(handle); return enif_make_int(env, c); }
static ERL_NIF_TERM digital_read_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { int pin, value; if (!enif_get_int(env, argv[0], &pin)) { return enif_make_badarg(env); } value = digitalRead(pin); return enif_make_int(env, value); }
static ERL_NIF_TERM nif_write(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { char message[MAXBUFLEN]; int log_level; if (!enif_get_int(env, argv[0], &log_level)) { return enif_make_badarg(env); } if (enif_get_string(env, argv[1], message, sizeof(message), ERL_NIF_LATIN1) < 1) { return enif_make_badarg(env); } syslog(log_level, "%s", message); return enif_make_atom(env, "ok"); }
static ERL_NIF_TERM ex_init_pair(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { int pair, f, b; if (argc != 3 ) return enif_make_badarg(env); if (! enif_get_int(env, argv[0], &pair)) return enif_make_badarg(env); if (! enif_get_int(env, argv[1], &f)) return enif_make_badarg(env); if (! enif_get_int(env, argv[2], &b)) return enif_make_badarg(env); int code = init_pair(pair, f, b); return done(env, code); }
int convert_nif_to_hsize_array(ErlNifEnv* env, hsize_t size, const ERL_NIF_TERM* arr_from, hsize_t *arr_to) { int n, i; for(i = 0; i < size; i++) { check(enif_get_int(env, arr_from[i], &n), "error getting diskspace dimensions"); arr_to[i] = (hsize_t)n; } return 0; error: return -1; };
/* 0: (int)socket descriptor, 1: (int)device dependent request, * 2: (char *)argp, pointer to structure | int */ static ERL_NIF_TERM nif_ioctl(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { int s = -1; unsigned long req = 0; ErlNifBinary arg = {0}; int n = 0; if (!enif_get_int(env, argv[0], &s)) return enif_make_badarg(env); if (!enif_get_ulong(env, argv[1], &req)) return enif_make_badarg(env); if (enif_inspect_binary(env, argv[2], &arg)) { /* Make the binary mutable */ if (!enif_realloc_binary(&arg, arg.size)) return error_tuple(env, ENOMEM); if (ioctl(s, req, arg.data) < 0) return error_tuple(env, errno); } else if (enif_get_int(env, argv[2], &n)) { /* XXX integer args allow the caller to * XXX pass in arbitrary pointers */ if (ioctl(s, req, n) < 0) return error_tuple(env, errno); /* return an empty binary */ if (!enif_alloc_binary(0, &arg)) return error_tuple(env, ENOMEM); } else return enif_make_badarg(env); return enif_make_tuple2(env, atom_ok, enif_make_binary(env, &arg)); }
/*-----------------------------------------------------------------------------------------------------------------------*/ static ERL_NIF_TERM set_char_field(ErlNifEnv* env, int32_t argc, ERL_NIF_TERM const argv[]) { ERL_NIF_TERM parser_res; ERL_NIF_TERM msg_res; ERL_NIF_TERM group_res; ParserRes* parser = NULL; FIXMsg* msg = NULL; FIXGroup* group = NULL; ERL_NIF_TERM res = get_parser_msg_group(env, argv[0], &parser_res, &msg_res, &group_res, &parser, &msg, &group); if (res != ok_atom) { return res; } int32_t tagNum = 0; if (!enif_get_int(env, argv[1], &tagNum)) { return make_error(env, FIX_FAILED, "Wrong tag num."); } if (!enif_is_number(env, argv[2])) { return make_error(env, FIX_FAILED, "Value is not a char."); } int32_t val = 0; enif_get_int(env, argv[2], &val); if (val < 32 || val > 126) { return make_error(env, FIX_FAILED, "Value is not a char."); } ERL_NIF_TERM ret = ok_atom; FIXError* error = NULL; pthread_rwlock_wrlock(&parser->lock); FIXErrCode err = fix_msg_set_char(msg, group, tagNum, (char)val, &error); pthread_rwlock_unlock(&parser->lock); if (err == FIX_FAILED) { ret = make_parser_error(env, fix_error_get_code(error), fix_error_get_text(error)); fix_error_free(error); } return ret; }
ERL_NIF_TERM date_get6(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { UErrorCode status = U_ZERO_ERROR; UCalendar* cal; cloner* ptr; int32_t year, month, day, hour, minute, second; if(!((argc == 7) && enif_get_resource(env, argv[0], calendar_type, (void**) &ptr) && enif_get_int(env, argv[1], &year) && enif_get_int(env, argv[2], &month) && enif_get_int(env, argv[3], &day) && enif_get_int(env, argv[4], &hour) && enif_get_int(env, argv[5], &minute) && enif_get_int(env, argv[6], &second))) { return enif_make_badarg(env); } month--; cal = (UCalendar*) cloner_get(ptr); CHECK_RES(env, cal); ucal_setDateTime(cal, year, month, day, hour, minute, second, &status); CHECK(env, status); return calendar_to_double(env, (const UCalendar*) cal); }
static int bind_cell(ErlNifEnv *env, const ERL_NIF_TERM cell, sqlite3_stmt *stmt, unsigned int i) { int the_int; ErlNifSInt64 the_long_int; double the_double; char the_atom[MAX_ATOM_LENGTH+1]; ErlNifBinary the_blob; int arity; const ERL_NIF_TERM* tuple; if(enif_get_int(env, cell, &the_int)) return sqlite3_bind_int(stmt, i, the_int); if(enif_get_int64(env, cell, &the_long_int)) return sqlite3_bind_int64(stmt, i, the_long_int); if(enif_get_double(env, cell, &the_double)) return sqlite3_bind_double(stmt, i, the_double); if(enif_get_atom(env, cell, the_atom, sizeof(the_atom), ERL_NIF_LATIN1)) { if(strcmp("undefined", the_atom) == 0) { return sqlite3_bind_null(stmt, i); } return sqlite3_bind_text(stmt, i, the_atom, strlen(the_atom), SQLITE_TRANSIENT); } /* Bind as text assume it is utf-8 encoded text */ if(enif_inspect_iolist_as_binary(env, cell, &the_blob)) return sqlite3_bind_text(stmt, i, (char *) the_blob.data, the_blob.size, SQLITE_TRANSIENT); /* Check for blob tuple */ if(enif_get_tuple(env, cell, &arity, &tuple)) { if(arity != 2) return -1; /* length 2! */ if(enif_get_atom(env, tuple[0], the_atom, sizeof(the_atom), ERL_NIF_LATIN1)) { /* its a blob... */ if(0 == strncmp("blob", the_atom, strlen("blob"))) { /* with a iolist as argument */ if(enif_inspect_iolist_as_binary(env, tuple[1], &the_blob)) { /* kaboom... get the blob */ return sqlite3_bind_blob(stmt, i, the_blob.data, the_blob.size, SQLITE_TRANSIENT); } } } } return -1; }
static ERL_NIF_TERM set_tty_speed(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { int fd = -1; unsigned int speed = 0; unsigned int new_ispeed = 0; unsigned int new_ospeed = 0; struct termios ttymodes = {0}; if (enif_get_int(env, argv[0], &fd) < 1) { return enif_make_badarg(env); } if (enif_get_uint(env, argv[1], &speed) < 1 || lookup_speed(speed, &new_ispeed) < 0) { return enif_make_badarg(env); } if (enif_get_uint(env, argv[2], &speed) < 1 || lookup_speed(speed, &new_ospeed) < 0) { return enif_make_badarg(env); } /* Get ttymodes */ if (tcgetattr(fd,&ttymodes) < 0) { return mk_errno(env, errno); } if (cfsetispeed(&ttymodes,new_ispeed) < 0) { return mk_errno(env, errno); } if (cfsetospeed(&ttymodes,new_ospeed) < 0) { return mk_errno(env, errno); } /* Apply changes */ if (tcsetattr(fd, TCSANOW, &ttymodes) < 0) { return mk_errno(env, errno); } return atom_ok; }
/* OGRDataSourceH CPL_DLL OGROpen(const char *, int, OGRSFDriverH *) CPL_WARN_UNUSED_RESULT; {ok, DataSource} = lgeo_ogr:open("test/polygon.shp"). {ok, DataSource} = lgeo_ogr:open("test/polygon.shp", 1). */ static ERL_NIF_TERM open(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { int update = 0; // read-only (default) OGRDataSourceH datasource; ERL_NIF_TERM eterm; /* OGRSFDriverH *pahDriver; ERL_NIF_TERM eterm1, eterm2; */ unsigned len; if (argc > 0 && !enif_get_list_length(env, argv[0], &len)) { return enif_make_badarg(env); } char * filename = enif_alloc(sizeof(char)*(len+1)); if(!enif_get_string(env, argv[0], filename, len+1, ERL_NIF_LATIN1)) { return enif_make_badarg(env); } if (argc == 2 && !enif_get_int(env, argv[1], &update)) { return enif_make_badarg(env); } datasource = OGROpen(filename, update, NULL); //datasource = OGROpen(filename, upadate, pahDriver); enif_free(filename); if(datasource == NULL) { return enif_make_atom(env, "undefined"); } OGRDataSourceH **hDS = \ enif_alloc_resource(OGR_DS_RESOURCE, sizeof(OGRDataSourceH*)); *hDS = datasource; /* OGRSFDriverH **hDriver = \ enif_alloc_resource(OGR_D_RESOURCE, sizeof(OGRSFDriverH*)); *hDriver = *pahDriver; */ eterm = enif_make_resource(env, hDS); enif_release_resource(hDS); return enif_make_tuple2(env, enif_make_atom(env, "ok"), eterm); /* eterm2 = enif_make_resource(env, hDriver); enif_release_resource(hDriver); return enif_make_tuple2(env, eterm1, eterm1); */ }
static ERL_NIF_TERM sync_nif_impl(efile_data_t *d, ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { int data_only; if(argc != 1 || !enif_get_int(env, argv[0], &data_only)) { return enif_make_badarg(env); } if(!efile_sync(d, data_only)) { return posix_error_to_tuple(env, d->posix_errno); } return am_ok; }
static ERL_NIF_TERM randombytes_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { int x; ERL_NIF_TERM term; unsigned char* binary = 0; if (!enif_get_int(env, argv[0], &x)) { return enif_make_badarg(env); } binary = enif_make_new_binary(env, x, &term); randombytes(binary, x); return term; }