// read_com(_PORTID, _DATACNT) static ERL_NIF_TERM read_com(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]){ int ret = 0; int port = 0; int data_cnt = 0; DWORD dwBytesTransferred; ErlNifBinary bin; unsigned char* data; if (argc < 2) return enif_make_badarg(env); if (!enif_get_int (env, argv[0], &port)) return enif_make_badarg(env); if (!enif_get_int (env, argv[1], &data_cnt)) return enif_make_badarg(env); if (port > cur_port || port < 1 || data_cnt < 1 || data_cnt > INT_MAX) return enif_make_badarg(env); if(ports[port - 1] == NULL) return enif_make_string(env, "Port is already closed!", ERL_NIF_LATIN1); data = (unsigned char*) malloc(sizeof(unsigned char)*(data_cnt)); ReadFile (ports[port - 1], data, data_cnt, &dwBytesTransferred, 0); //read 1 if(! enif_alloc_binary(dwBytesTransferred, &bin)){ return enif_make_string(env, "Memory cannot be allocated!", ERL_NIF_LATIN1); } memcpy(bin.data, data, dwBytesTransferred); return enif_make_binary(env, &bin); }
static ERL_NIF_TERM setup_2(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { unsigned int channel; unsigned long speed; int error; if (argc != 2 || !enif_is_number(env, argv[0]) || !enif_is_number(env, argv[1])) { return enif_make_badarg(env); } if (!enif_get_uint(env, argv[0], &channel)) { return enif_make_badarg(env); } if (!enif_get_ulong(env, argv[1], &speed)) { return enif_make_badarg(env); } if (speed < 500000 || speed > 32000000) { return enif_make_badarg(env); } switch (channel) { case 0: if (state0.fd != 0) { return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_string(env, "channel already opened", ERL_NIF_LATIN1)); } else { state0.env = env; state0.fd = wiringPiSPISetup(channel, speed); if (state0.fd == 0) { error = errno; return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_int(env, error)); } else { return enif_make_tuple2(env, enif_make_atom(env, "ok"), enif_make_int(env, channel)); } } break; case 1: if (state1.fd != 0) { return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_string(env, "channel already opened", ERL_NIF_LATIN1)); } else { state1.env = env; state1.fd = wiringPiSPISetup(channel, speed); if (state1.fd == 0) { error = errno; return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_int(env, error)); } else { return enif_make_tuple2(env, enif_make_atom(env, "ok"), enif_make_int(env, channel)); } } break; default: return enif_make_badarg(env); } }
// convert a python object to an erlang term, return the atom 'unknown' if // the type can't be converted static ERL_NIF_TERM pynerl_obj_to_term(ErlNifEnv* env, PyObject* obj) { ERL_NIF_TERM term; if (obj == Py_False) { term = enif_make_atom(env, "false"); } else if (obj == Py_True) { term = enif_make_atom(env, "true"); } else if (PyLong_Check(obj)) { // TODO: make ints when the size allows to. term = enif_make_long(env, PyLong_AsLong(obj)); } else if (PyFloat_Check(obj)) { term = enif_make_double(env, PyFloat_AsDouble(obj)); } else if (PyTuple_Check(obj)) { Py_ssize_t i, arity = PyTuple_Size(obj); ERL_NIF_TERM *terms = (ERL_NIF_TERM*) malloc(sizeof(ERL_NIF_TERM) * (int)arity); for (i = 0; i < arity; i++) { terms[(int)i] = pynerl_obj_to_term(env, PyTuple_GetItem(obj, i)); } term = enif_make_tuple_from_array(env, terms, (unsigned int)arity); } else if (PyBytes_Check(obj)) { // XXX: the encoding must be latin1 term = enif_make_string(env, PyBytes_AsString(obj), ERL_NIF_LATIN1); } else if (PyUnicode_Check(obj)) { // XXX: the encoding must be latin1 term = enif_make_string(env, PyBytes_AsString(PyUnicode_AsLatin1String(obj)), ERL_NIF_LATIN1); } else if (PyList_Check(obj)) { Py_ssize_t i, arity = PyList_Size(obj); ERL_NIF_TERM *terms = (ERL_NIF_TERM*) malloc(sizeof(ERL_NIF_TERM) * (int)arity); for (i = 0; i < arity; i++) { terms[(int)i] = pynerl_obj_to_term(env, PyList_GetItem(obj, i)); } term = enif_make_list_from_array(env, terms, (unsigned int)arity); } else if (obj == Py_None) { term = enif_make_atom(env, "none"); } else { term = enif_make_atom(env, "unknown"); } return term; }
static ERL_NIF_TERM make_strings(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { const char a0string[8] = {'a','0','s','t','r','i','n','g'}; const char a0string0[9] = {'a','\0','s','t','r','i','n','g',0}; const char astringwith8bits[37] = {'E','r','l','a','n','g',' ',0xE4 /* 'ä' */,'r',' ','e','t','t',' ','g','e','n','e','r','e','l','l','t',' ','p','r','o','g','r','a','m','s','p','r', 0xE5 /* 'å' */,'k',0}; return enif_make_tuple5(env, enif_make_string(env, "a0string", ERL_NIF_LATIN1), enif_make_string_len(env, "a0string", 8, ERL_NIF_LATIN1), enif_make_string_len(env, a0string, 8, ERL_NIF_LATIN1), enif_make_string_len(env, a0string0, 9, ERL_NIF_LATIN1), enif_make_string(env, astringwith8bits, ERL_NIF_LATIN1)); }
static ERL_NIF_TERM error_tuple(ErlNifEnv *env, char *err) { return enif_make_tuple(env, 2, atom_error, enif_make_string(env, err, ERL_NIF_LATIN1)); }
static enum CXChildVisitResult visitor_enum_cb(CXCursor cursor, CXCursor parent, CXClientData client_data) { EnumData* data = (EnumData*)client_data; ErlNifEnv *env = data->env; ERL_NIF_TERM name; ERL_NIF_TERM value; long long cvalue; CXString tmp; char* cstr; switch (clang_getCursorKind(cursor)) { case CXCursor_EnumConstantDecl: { tmp = clang_getCursorSpelling(cursor); cstr = (char*)clang_getCString(tmp); cvalue = clang_getEnumConstantDeclValue(cursor); name = enif_make_string(env, cstr, ERL_NIF_LATIN1); value = enif_make_int64(env, cvalue); data->enum_values = enif_make_list_cell(env, enif_make_tuple2(env, name, value), data->enum_values); } default: { return CXChildVisit_Continue; } } }
/* OGRSFDriverH CPL_DLL OGRGetDriver( int ); {ok, Driver} = lgeo_ogr:get_driver(0), */ static ERL_NIF_TERM get_driver(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { int driver_idx; ERL_NIF_TERM eterm; if (argc != 1) { return enif_make_badarg(env); } if (!enif_get_int(env, argv[0], &driver_idx)) { return enif_make_badarg(env); } OGRSFDriverH drv = OGRGetDriver(driver_idx); if (!drv) { return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_string(env, "Driver not found", ERL_NIF_LATIN1)); } OGRSFDriverH **driver = \ enif_alloc_resource(OGR_D_RESOURCE, sizeof(OGRSFDriverH*)); *driver = drv; eterm = enif_make_resource(env, driver); enif_release_resource(driver); return enif_make_tuple2(env, enif_make_atom(env, "ok"), eterm); }
/* OGR_G_ExportToWkt(OGRGeometryH, char **) {ok, DataSource} = lgeo_ogr:open("test/polygon.shp"), {ok, Layer} = lgeo_ogr:ds_get_layer(DataSource, 0), {ok, Feature} = lgeo_ogr:l_get_feature(Layer, 0), {ok, Geometry} = lgeo_ogr:f_get_geometry_ref(Feature), {ok, Wkt} = lgeo_ogr:g_export_to_wkt(Geometry). */ static ERL_NIF_TERM g_export_to_wkt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { EnvGeometry_t **geom; ERL_NIF_TERM eterm; if (argc != 1) { return enif_make_badarg(env); } if (!enif_get_resource(env, argv[0], OGR_G_RESOURCE, (void**)&geom)) { return enif_make_badarg(env); } char *wkt = NULL; OGRErr eErr = OGR_G_ExportToWkt((**geom).obj, &wkt); if (eErr != OGRERR_NONE) { return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_int(env, eErr)); } eterm = enif_make_string(env, wkt, ERL_NIF_LATIN1); OGRFree(wkt); return enif_make_tuple2(env, enif_make_atom(env, "ok"), eterm); }
/* {ok, DataSource} = lgeo_ogr:open("test/polygon.shp"), {ok, Layer} = lgeo_ogr:ds_get_layer(DataSource, 0), {ok, FeatureDefn} = lgeo_ogr:l_get_layer_defn(Layer), {ok, Types} = lgeo_ogr:fd_get_fields_type(FeatureDefn). {"Integer","String"} */ static ERL_NIF_TERM fd_get_fields_type(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { EnvFeatureDefn_t **feat_defn; ERL_NIF_TERM eterm; if (argc != 1) { return enif_make_badarg(env); } if(!enif_get_resource(env, argv[0], OGR_FD_RESOURCE, (void**)&feat_defn)) { return enif_make_badarg(env); } int count = OGR_FD_GetFieldCount((**feat_defn).obj); ERL_NIF_TERM *arr = (ERL_NIF_TERM *) malloc(sizeof(ERL_NIF_TERM)*count); int index; for(index=0; index<count; index++) { OGRFieldDefnH field_defn = OGR_FD_GetFieldDefn((**feat_defn).obj, index); arr[index] = enif_make_string(env, OGR_GetFieldTypeName(OGR_Fld_GetType(field_defn)), ERL_NIF_LATIN1); } eterm = enif_make_tuple_from_array(env, arr, index); free(arr); return enif_make_tuple2(env, enif_make_atom(env, "ok"), eterm); }
static ERL_NIF_TERM format_error(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { unsigned len; int res; if (!enif_get_atom_length(env, argv[0], &len, ERL_NIF_LATIN1)) return enif_make_badarg(env); char *atom = malloc(len+1); if (!enif_get_atom(env, argv[0], atom, len+1, ERL_NIF_LATIN1)) { free(atom); return enif_make_badarg(env); } if (!strcmp("done", atom)) res = RS_DONE; else if (!strcmp("blocked", atom)) res = RS_BLOCKED; else if (!strcmp("running", atom)) res = RS_RUNNING; else if (!strcmp("test_skipped", atom)) res = RS_TEST_SKIPPED; else if (!strcmp("io_error", atom)) res = RS_IO_ERROR; else if (!strcmp("syntax_error", atom)) res = RS_SYNTAX_ERROR; else if (!strcmp("mem_error", atom)) res = RS_MEM_ERROR; else if (!strcmp("input_ended", atom)) res = RS_INPUT_ENDED; else if (!strcmp("bad_magic", atom)) res = RS_BAD_MAGIC; else if (!strcmp("unimplemented", atom)) res = RS_UNIMPLEMENTED; else if (!strcmp("corrupt", atom)) res = RS_CORRUPT; else if (!strcmp("internal_error", atom)) res = RS_INTERNAL_ERROR; else if (!strcmp("param_error", atom)) res = RS_PARAM_ERROR; else res = -1; free(atom); return enif_make_string(env, rs_strerror(res), ERL_NIF_LATIN1); }
static ERL_NIF_TERM element_to(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[], int as_string) { ErlNifBinary output; ERL_NIF_TERM result; struct buf *rbuf; if (argc == 1) { rbuf = init_buf(env); if (make_element(env, rbuf, argv[0])) { if (as_string) { (rbuf->b)[rbuf->len] = 0; result = enif_make_string(env, (char *) rbuf->b, ERL_NIF_LATIN1); destroy_buf(env, rbuf); return result; } else { if (ENIF_ALLOC_BINARY(rbuf->len, &output)) { memcpy(output.data, rbuf->b, rbuf->len); result = enif_make_binary(env, &output); destroy_buf(env, rbuf); return result; }; }; }; destroy_buf(env, rbuf); }; return enif_make_badarg(env); }
void ewpcap_error(EWPCAP_STATE *ep, char *msg) { int rv = 0; if (ep->p == NULL) return; /* {ewpcap_error, Ref, Error} */ rv = enif_send( NULL, &ep->pid, ep->env, enif_make_tuple3(ep->env, atom_ewpcap_error, enif_make_copy(ep->env, ep->ref), enif_make_string(ep->env, msg, ERL_NIF_LATIN1) ) ); if (!rv) pcap_breakloop(ep->p); enif_clear_env(ep->env); }
static ERL_NIF_TERM write_com(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]){ int ret = 0; int port = 0; DWORD dwBytesTransferred; ErlNifBinary bin; if (argc < 2) return enif_make_badarg(env); if (!enif_get_int (env, argv[0], &port)) return enif_make_badarg(env); if (!enif_inspect_binary(env, argv[1], &bin)) return enif_make_badarg(env); if (port > cur_port || port < 1 || bin.size < 1 || bin.size > INT_MAX) return enif_make_badarg(env); if(ports[port - 1] == NULL) return enif_make_string(env, "Port is already closed!", ERL_NIF_LATIN1); if((int) WriteFile(ports[port - 1], bin.data, (DWORD) bin.size, &dwBytesTransferred, NULL)) ret = dwBytesTransferred; else ret = 0; return enif_make_int(env, ret); }
static ERL_NIF_TERM newstate(ErlNifEnv *env, ErlNifEnv *hold_env) { ERL_NIF_TERM ret; lua_State *L; elua_t *res; L = luaL_newstate(); if(L==NULL) { return enif_make_tuple2(env, atom_error, enif_make_string(env, STR_NOT_ENOUGHT_MEMORY, ERL_NIF_LATIN1)); } luaL_openlibs(L); res = enif_alloc_resource(RES_SYNC, sizeof(elua_t)); if(res == NULL) return enif_make_badarg(env); //printf("alloc res 0x%x\n" ,(unsigned int)res); ret = enif_make_resource(env, res); enif_release_resource(res); res->L = L; return enif_make_tuple2(env, atom_ok, ret); }
static ERL_NIF_TERM parse(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { XML_Parser **parser; int is_final, res, errcode; ErlNifBinary stream; char *errstring; assert(argc == 3); if (!enif_get_resource(env, argv[0], PARSER_POINTER, (void **)&parser)) return enif_make_badarg(env); if (!enif_is_binary(env, argv[1])) return enif_make_badarg(env); enif_get_int(env, argv[2], &is_final); enif_inspect_binary(env, argv[1], &stream); expat_parser *parser_data = XML_GetUserData((XML_Parser)(*parser)); parser_data->result = enif_make_list(env, 0); parser_data->env = env; XML_SetUserData((XML_Parser)(*parser), parser_data); res = XML_Parse((XML_Parser)(*parser), (const char *)stream.data, stream.size, is_final); if(!res) { errcode = XML_GetErrorCode((XML_Parser)(*parser)); errstring = (char *)XML_ErrorString(errcode); return enif_make_tuple(env, 2, ERROR, enif_make_string(env, errstring, ERL_NIF_LATIN1)); } return enif_make_tuple(env, 2, OK, parser_data->result); };
static ERL_NIF_TERM float_ref(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { int err; double helper; float *value; value = enif_alloc(sizeof(float)); if (!value) { goto error; } err = enif_get_double(env, argv[0], &helper); if (!err) { enif_free(value); goto error; } *value = (float)helper; return enif_make_tuple2(env, nifty_make_ptr(env, (ptr_t)value), enif_make_string(env, "nifty.float *", ERL_NIF_LATIN1)); error: return enif_make_badarg(env); }
static ERL_NIF_TERM nif_pcap_stats(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { EWPCAP_STATE *ep = NULL; struct pcap_stat ps = {0}; if (!enif_get_resource(env, argv[0], EWPCAP_RESOURCE, (void **)&ep) || ep->p == NULL) return enif_make_badarg(env); if (pcap_stats(ep->p, &ps)) return enif_make_tuple2(env, atom_error, enif_make_string(env, pcap_geterr(ep->p), ERL_NIF_LATIN1)); return enif_make_tuple2(env, atom_ok, enif_make_tuple5(env, atom_ewpcap_stat, enif_make_uint(env, ps.ps_recv), enif_make_uint(env, ps.ps_drop), enif_make_uint(env, ps.ps_ifdrop), #ifdef WIN32 enif_make_uint(env, ps.bs_capt) #else enif_make_uint(env, 0) #endif )); }
static ERL_NIF_TERM list_to_cstr(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { int err, written, tmp; unsigned int l; char* cstr; err = enif_get_list_length(env, argv[0], &l); if (!err) { goto error; } l+=1; // Null Termination cstr = enif_alloc(sizeof(char)*l); if (!cstr) { goto error; } written = 0; while (written<(l)) { tmp = enif_get_string(env, argv[0], cstr+written, l-written, ERL_NIF_LATIN1); if (tmp<=0) { enif_free(cstr); goto error; } written += tmp; } return enif_make_tuple2(env, enif_make_int64(env, (ptr_t)cstr), enif_make_string(env, "nifty.char *", ERL_NIF_LATIN1)); error: return enif_make_badarg(env); }
static ERL_NIF_TERM get_env(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { return enif_make_tuple2(env, nifty_make_ptr(env, (ptr_t)env), enif_make_string(env, "nifty.void *", ERL_NIF_LATIN1)); }
static ERL_NIF_TERM set_dtr(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]){ int ret = 0; int port = 0; int state = 0; if (argc < 1) return enif_make_badarg(env); if (!enif_get_int (env, argv[0], &port)) return enif_make_badarg(env); if (!enif_get_int (env, argv[0], &state)) return enif_make_badarg(env); if (port > cur_port || port < 1) return enif_make_badarg(env); if(ports[port - 1] == NULL) return enif_make_string(env, "Port is already closed!", ERL_NIF_LATIN1); if(state) ret = (int) EscapeCommFunction(ports[port - 1], SETDTR); else ret = (int) EscapeCommFunction(ports[port - 1], CLRDTR); return enif_make_int(env, ret); }
void update_callback(void *arg, int sqlite_operation_type, char const *sqlite_database, char const *sqlite_table, sqlite3_int64 sqlite_rowid) { esqlite_connection *db = (esqlite_connection *)arg; esqlite_command *cmd = NULL; ERL_NIF_TERM type, table, rowid; cmd = command_create(); if(db == NULL) return; if(!cmd) return; rowid = enif_make_int64(cmd->env, sqlite_rowid); table = enif_make_string(cmd->env, sqlite_table, ERL_NIF_LATIN1); switch(sqlite_operation_type) { case SQLITE_INSERT: type = make_atom(cmd->env, "insert"); break; case SQLITE_DELETE: type = make_atom(cmd->env, "delete"); break; case SQLITE_UPDATE: type = make_atom(cmd->env, "update"); break; default: return; } cmd->type = cmd_notification; cmd->arg = enif_make_tuple3(cmd->env, type, table, rowid); push_command(cmd->env, db, cmd); }
ERL_NIF_TERM snappy_decompress_impl(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { ctx_t *ctx; task_t *task; ErlNifPid pid; if (argc != 4) { return enif_make_badarg(env); } if (!enif_get_resource(env, argv[0], res_type, reinterpret_cast<void**>(&ctx))) { return enif_make_badarg(env); } if (!enif_is_ref(env, argv[1])) { return enif_make_tuple2(env, atom_error, enif_make_string(env, "Second arg. is not a reference", ERL_NIF_LATIN1)); } if (!enif_get_local_pid(env, argv[2], &pid)) { return enif_make_tuple2(env, atom_error, enif_make_string(env, "Third arg. is not a pid of local process", ERL_NIF_LATIN1)); } if (!enif_is_binary(env, argv[3])) { return enif_make_tuple2(env, atom_error, enif_make_string(env, "Forth arg. is not a binary", ERL_NIF_LATIN1)); } task = init_task(DECOMPRESS, argv[1], pid, argv[3]); if (!task) { return enif_make_tuple2(env, atom_error, enif_make_string(env, "Failed to create a task", ERL_NIF_LATIN1)); } async_queue_push(ctx->queue, static_cast<void*>(task)); return atom_ok; }
work_result(ErlNifEnv *env, const ERL_NIF_TERM& error, rocksdb::Status& status) : _is_set(true) { ERL_NIF_TERM reason = enif_make_string(env, status.ToString().c_str(), ERL_NIF_LATIN1); _result = enif_make_tuple2(env, erocksdb::ATOM_ERROR, enif_make_tuple2(env, error, reason)); }
static ERL_NIF_TERM string(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { struct regexp *r = NULL; if (!enif_get_resource(env, argv[0], regexp_type, (void **)&r)) { return enif_make_badarg(env); } return enif_make_string(env, r->string, ERL_NIF_LATIN1); }
/*-----------------------------------------------------------------------------------------------------------------------*/ static ERL_NIF_TERM make_error(ErlNifEnv* env, int32_t errCode, char const* errorMsg, ...) { va_list ap; va_start(ap, errorMsg); char text[1024]; vsnprintf(text, sizeof(text), errorMsg, ap); return enif_make_tuple3(env, error_atom, enif_make_int(env, errCode), enif_make_string(env, text, ERL_NIF_LATIN1)); }
ERL_NIF_TERM decompress(task_t *task) { size_t len; bool status; ERL_NIF_TERM result; ErlNifBinary bin; len = -1; status = snappy::GetUncompressedLength( reinterpret_cast<const char *>(task->data.data), task->data.size, &len); if (!status) { result = enif_make_tuple2(task->env, atom_error, enif_make_string(task->env, "Data is not compressed", ERL_NIF_LATIN1)); goto done; } if (!enif_alloc_binary(len, &bin)) { result = enif_make_tuple2(task->env, atom_error, enif_make_string(task->env, "Couldn't allocate memory", ERL_NIF_LATIN1)); goto done; } status = snappy::RawUncompress( reinterpret_cast<const char*>(task->data.data), task->data.size, reinterpret_cast<char*>(bin.data)); if (!status) { result = enif_make_tuple2(task->env, atom_error, enif_make_string(task->env, "Failed to decompress", ERL_NIF_LATIN1)); goto done; } result = enif_make_tuple3(task->env, atom_ok, task->ref, enif_make_binary(task->env, &bin)); done: return result; }
static ERL_NIF_TERM allocate_pty_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { int master; int slave; char* name; openpty(&master, &slave, NULL, NULL, NULL); name = ttyname(slave); return enif_make_tuple2(env, enif_make_int(env, master), enif_make_string(env, name, ERL_NIF_LATIN1)); }
static ERL_NIF_TERM nif_pcap_lookupdev(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { char *dev = NULL; char errbuf[PCAP_ERRBUF_SIZE] = {0}; dev = pcap_lookupdev(errbuf); if (dev == NULL) return enif_make_tuple2(env, atom_error, enif_make_string(env, errbuf, ERL_NIF_LATIN1)); return enif_make_tuple2(env, atom_ok, enif_make_string(env, dev, ERL_NIF_LATIN1)); }
static ERL_NIF_TERM _test(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { UNUSED(argc); char result[MAXBUFLEN]; char path[MAXBUFLEN]; enif_get_string(env, argv[0], path, 1024, ERL_NIF_LATIN1); return enif_make_string(env, result, ERL_NIF_LATIN1); }
static ERL_NIF_TERM xfer2_1(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { int status, val, i; struct spi_ioc_transfer xfer; uint8_t *txbuf, *rxbuf; unsigned int length; ERL_NIF_TERM cell, head, tail, res, list; if (state.fd == -1) return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_string(env, "device closed", ERL_NIF_LATIN1)); if (argc != 1 || !enif_is_list(env, argv[0])) return enif_make_badarg(env); if (!enif_get_list_length(env, argv[0], &length)) return enif_make_badarg(env); txbuf = (uint8_t *) enif_alloc(sizeof(uint8_t) * length); rxbuf = (uint8_t *) enif_alloc(sizeof(uint8_t) * length); list = argv[0]; for (i = 0; enif_get_list_cell(env, list, &head, &tail); ++i, list = tail) { if (!enif_get_int(env, head, &val)) { return enif_make_badarg(env); } txbuf[i] = val; } xfer.tx_buf = (unsigned long) txbuf; xfer.rx_buf = (unsigned long) rxbuf; xfer.len = length; status = ioctl(state.fd, SPI_IOC_MESSAGE(1), &xfer); if (status < 0) { enif_free(txbuf); enif_free(rxbuf); return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_string(env, "spi ioc message", ERL_NIF_LATIN1)); } list = enif_make_list(env, 0); for (i = length - 1; i >= 0; --i) { cell = enif_make_uint(env, (unsigned int) rxbuf[i]); list = enif_make_list_cell(env, cell, list); } res = enif_make_tuple2(env, enif_make_atom(env, "ok"), list); enif_free(txbuf); enif_free(rxbuf); return res; }