static void output(ErlDrvData drv_data, char *buf, ErlDrvSizeT len) { Otp9302Data *data = (Otp9302Data *) drv_data; ErlDrvTermData td_port = driver_mk_port(data->port); ErlDrvTermData td_receiver = driver_caller(data->port); ErlDrvTermData td_job = driver_mk_atom("job"); unsigned int key = (unsigned int) (ErlDrvSInt) data->port; long id[5]; Otp9302AsyncData *ad[5]; int i; for (i = 0; i < sizeof(ad)/sizeof(ad[0]); i++) { ad[i] = driver_alloc(sizeof(Otp9302AsyncData)); if (!ad[i]) abort(); ad[i]->smp = data->smp; ad[i]->port = data->port; ad[i]->block = 0; ad[i]->refc = 1; ad[i]->term_data.port = td_port; ad[i]->term_data.receiver = td_receiver; ad[i]->term_data.msg = td_job; ad[i]->msgq = &data->msgq; } ad[0]->block = 1; ad[0]->term_data.msg = driver_mk_atom("block"); ad[2]->term_data.msg = driver_mk_atom("cancel"); ad[4]->term_data.msg = driver_mk_atom("end_of_jobs"); for (i = 0; i < sizeof(id)/sizeof(id[0]); i++) id[i] = driver_async(data->port, &key, async_invoke, ad[i], driver_free); if (id[2] > 0) driver_async_cancel(id[2]); }
static void process(ErlDrvData handle, ErlIOVec *ev) { baberl_drv_t* driver_data = (baberl_drv_t*) handle; ErlDrvBinary* args = ev->binv[1]; char *data = args->orig_bytes; char *from_encoding, *to_encoding, *text; converted_text_t cv; from_encoding = read_string(&data); to_encoding = read_string(&data); text = read_string(&data); cv.error = 0; convert_text(from_encoding, to_encoding, text, strlen(text), &cv); if (cv.error == 0) { ErlDrvTermData spec[] = {ERL_DRV_ATOM, driver_mk_atom("ok"), ERL_DRV_BUF2BINARY, cv.text, cv.text_size, ERL_DRV_TUPLE, 2 }; driver_output_term(driver_data->port, spec, sizeof(spec) / sizeof(spec[0])); } else { ErlDrvTermData spec[] = {ERL_DRV_ATOM, driver_mk_atom("error"), ERL_DRV_ATOM, driver_mk_atom("iconv_coding"), ERL_DRV_TUPLE, 2 }; driver_output_term(driver_data->port, spec, sizeof(spec) / sizeof(spec[0])); } driver_free(from_encoding); driver_free(to_encoding); driver_free(text); driver_free(cv.text); }
static void fill_passwd (ErlDrvTermData *data, struct passwd *pwd, char **name, char **passwd) { char *pw_name = pwd->pw_name; char *pw_passwd = pwd->pw_passwd; size_t len_name = strlen (pw_name); size_t len_passwd = strlen (pw_passwd); if (name) { *name = (char *) driver_alloc (sizeof (char) * (len_name + 1)); memcpy (*name, pw_name, sizeof (char) * (len_name + 1)); pw_name = *name; } if (passwd) { *passwd = (char *) driver_alloc (sizeof (char *) * (len_passwd + 1)); memcpy (*passwd, pw_passwd, sizeof (char) * (len_passwd + 1)); pw_passwd = *passwd; } *data++ = ERL_DRV_ATOM; *data++ = driver_mk_atom ("pw_name"); *data++ = ERL_DRV_STRING; *data++ = (ErlDrvTermData) pw_name; *data++ = strlen (pwd->pw_name); *data++ = ERL_DRV_TUPLE; *data++ = 2; *data++ = ERL_DRV_ATOM; *data++ = driver_mk_atom ("pw_passwd"); *data++ = ERL_DRV_STRING; *data++ = (ErlDrvTermData) pw_passwd; *data++ = strlen (pwd->pw_name); *data++ = ERL_DRV_TUPLE; *data++ = 2; *data++ = ERL_DRV_ATOM; *data++ = driver_mk_atom ("pw_uid"); *data++ = ERL_DRV_UINT; *data++ = pwd->pw_uid; *data++ = ERL_DRV_TUPLE; *data++ = 2; *data++ = ERL_DRV_ATOM; *data++ = driver_mk_atom ("pw_gid"); *data++ = ERL_DRV_UINT; *data++ = pwd->pw_gid; *data++ = ERL_DRV_TUPLE; *data++ = 2; *data++ = ERL_DRV_TUPLE; *data++ = 4; }
void dthread_lib_init() { dterm_lib_init(); am_data = driver_mk_atom("data"); am_ok = driver_mk_atom("ok"); am_error = driver_mk_atom("error"); }
// Unkown Command static void unkown(bdb_drv_t *bdb_drv, ErlIOVec *ev) { // Return {error, unkown_command} ErlDrvTermData spec[] = {ERL_DRV_ATOM, driver_mk_atom("error"), ERL_DRV_ATOM, driver_mk_atom("uknown_command"), ERL_DRV_TUPLE, 2}; driver_output_term(bdb_drv->port, spec, sizeof(spec) / sizeof(spec[0])); }
void send_geometry(GEOSCommand *command, GEOSGeometry *geom) { //GEOSContextHandle_t context = command->driver_data->handle; //int type = GEOSGeomTypeId_r(context, geom); if(geom == NULL) { ErlDrvTermData spec[] = {ERL_DRV_ATOM, driver_mk_atom("ok"), ERL_DRV_ATOM, driver_mk_atom("ggeom"), ERL_DRV_ATOM, driver_mk_atom("empty"), ERL_DRV_TUPLE, 2, ERL_DRV_TUPLE, 2}; driver_output_term(command->driver_data->port, spec, sizeof(spec) / sizeof(spec[0])); return; } ErlDrvTermData spec[] = {ERL_DRV_ATOM, driver_mk_atom("ok"), ERL_DRV_ATOM, driver_mk_atom("ggeom"), // ERL_DRV_INT, (ErlDrvTermData) type, ERL_DRV_INT, (ErlDrvTermData) geom, ERL_DRV_TUPLE, 2, ERL_DRV_TUPLE, 2}; driver_output_term(command->driver_data->port, spec, sizeof(spec) / sizeof(spec[0])); }
void erl_luam_maybe_atom(lua_drv_t *driver_data, char *buf, int index) { long i; int is_atom; char *atom; ei_decode_long(buf, &index, &i); lua_getglobal(driver_data->L, "erlang"); lua_getfield(driver_data->L, -1, "t_atom"); lua_getmetatable(driver_data->L, -3); is_atom = lua_rawequal(driver_data->L, -1, -2); lua_pop(driver_data->L, 3); if (is_atom) { atom = (char*)lua_touserdata(driver_data->L, i); ErlDrvTermData spec[] = { ERL_DRV_ATOM, ATOM_OK, ERL_DRV_ATOM, ATOM_OK, ERL_DRV_ATOM, driver_mk_atom(atom), ERL_DRV_TUPLE, 2, ERL_DRV_TUPLE, 2 }; erl_drv_output_term(driver_data->drvport, spec, sizeof(spec) / sizeof(spec[0])); } else { ErlDrvTermData spec[] = { ERL_DRV_ATOM, ATOM_OK, ERL_DRV_ATOM, driver_mk_atom("false"), ERL_DRV_TUPLE, 2 }; erl_drv_output_term(driver_data->drvport, spec, sizeof(spec) / sizeof(spec[0])); } }
static ErlDrvData emonk_start(ErlDrvPort port, char *cmd) { uint rt_max, gc_max, gc_last, ctx; emonk_drv_t* drv = NULL; ErlDrvData ret = ERL_DRV_ERROR_GENERAL; emonk_settings_t settings; if(parse_settings(cmd, &settings) < 0) { ret = ERL_DRV_ERROR_BADARG; goto error; } drv = (emonk_drv_t*) driver_alloc(sizeof(emonk_drv_t)); if(drv == NULL) goto error; drv->port = port; drv->ok = driver_mk_atom("ok"); drv->error = driver_mk_atom("error"); drv->undefined = driver_mk_atom("undefined"); drv->bad_cmd = driver_mk_atom("bad_command"); drv->vm = init_vm(&settings); if(drv->vm == NULL) goto error; return (ErlDrvData) drv; error: if(drv != NULL) driver_free(drv); return ret; }
void gl_dispatch(int op, char *bp,ErlDrvTermData caller,WXEBinRef *bins[]){ if(caller != gl_active) { wxGLCanvas * current = glc[caller]; if(current) { gl_active = caller; current->SetCurrent();} else { ErlDrvTermData rt[] = // Error msg {ERL_DRV_ATOM, driver_mk_atom((char *) "_egl_error_"), ERL_DRV_INT, op, ERL_DRV_ATOM, driver_mk_atom((char *) "no_gl_context"), ERL_DRV_TUPLE,3}; driver_send_term(WXE_DRV_PORT,caller,rt,8); return ; } }; char * bs[3]; int bs_sz[3]; for(int i=0; i<3; i++) { if(bins[i]) { bs[i] = bins[i]->base; bs_sz[i] = bins[i]->size; } else bs[i] = NULL; } wxe_gl_dispatch(op, bp, WXE_DRV_PORT, caller, bs, bs_sz); }
void testcase_printf(TestCaseState_t *tcs, char *frmt, ...) { InternalTestCaseState_t *itcs = (InternalTestCaseState_t *) tcs; ErlDrvTermData msg[12]; va_list va; va_start(va, frmt); #if HAVE_VSNPRINTF vsnprintf(itcs->comment_buf, COMMENT_BUF_SZ, frmt, va); #else vsprintf(itcs->comment_buf, frmt, va); #endif va_end(va); msg[0] = ERL_DRV_ATOM; msg[1] = (ErlDrvTermData) driver_mk_atom("print"); msg[2] = ERL_DRV_PORT; msg[3] = itcs->port_id; msg[4] = ERL_DRV_ATOM; msg[5] = driver_mk_atom(itcs->visible.testcase_name); msg[6] = ERL_DRV_STRING; msg[7] = (ErlDrvTermData) itcs->comment_buf; msg[8] = (ErlDrvTermData) strlen(itcs->comment_buf); msg[9] = ERL_DRV_TUPLE; msg[10] = (ErlDrvTermData) 4; erl_drv_output_term(itcs->port_id, msg, 11); }
void erl_send_error(GEOSCommand *command, char *atom) { ErlDrvTermData spec[] = {ERL_DRV_ATOM, driver_mk_atom("error"), ERL_DRV_ATOM, driver_mk_atom(atom), ERL_DRV_TUPLE, 2}; driver_output_term(command->driver_data->port, spec, sizeof(spec) / sizeof(spec[0])); }
// Delete a record from the database static void del(bdb_drv_t *bdb_drv, ErlIOVec *ev) { ErlDrvBinary* data = ev->binv[1]; char *bytes = data->orig_bytes; char *key_bytes = bytes+1; DB *db = bdb_drv->db; DBT key; int status; bzero(&key, sizeof(DBT)); key.data = key_bytes; key.size = KEY_SIZE; status = db->del(db, NULL, &key, 0); db->sync(db, 0); if(status == 0) { // Delete went OK, return atom 'ok' ErlDrvTermData spec[] = {ERL_DRV_ATOM, driver_mk_atom("ok")}; driver_output_term(bdb_drv->port, spec, sizeof(spec) / sizeof(spec[0])); } else { // There was an error char *error_reason; switch(status) { case DB_NOTFOUND: error_reason = "not_found"; break; case DB_LOCK_DEADLOCK: error_reason = "deadlock"; break; case DB_SECONDARY_BAD: error_reason = "bad_secondary_index"; break; case EINVAL: error_reason = "bad_flag"; break; case EACCES: error_reason = "readonly"; break; case DB_RUNRECOVERY: error_reason = "run_recovery"; break; default: error_reason = "unknown"; } // Return tuple {error, Reason} ErlDrvTermData spec[] = {ERL_DRV_ATOM, driver_mk_atom("error"), ERL_DRV_ATOM, driver_mk_atom(error_reason), ERL_DRV_TUPLE, 2}; driver_output_term(bdb_drv->port, spec, sizeof(spec) / sizeof(spec[0])); } }
static ErlDrvData start(ErlDrvPort port, char *cmd) { spidermonkey_drv_t *retval = (spidermonkey_drv_t*) driver_alloc(sizeof(spidermonkey_drv_t)); retval->port = port; retval->shutdown = 0; retval->atom_ok = driver_mk_atom((char *) "ok"); retval->atom_error = driver_mk_atom((char *) "error"); retval->atom_unknown_cmd = driver_mk_atom((char *) "unknown_command"); return (ErlDrvData) retval; }
static void send_txn_tstat(ErlDrvPort port, ErlDrvTermData pid, DB_TXN_ACTIVE *tasp) { char *name = tasp->name ? tasp->name : "<null>"; int name_len = strlen(name); char tid_str[32]; char *status_str; switch (tasp->status) { case TXN_ABORTED: status_str = "aborted"; break; case TXN_COMMITTED: status_str = "committed"; break; case TXN_PREPARED: status_str = "prepared"; break; case TXN_RUNNING: status_str = "running"; break; default: status_str = "undefined"; break; } int tid_str_len = snprintf(tid_str, sizeof(tid_str), "%lu", (unsigned long) tasp->tid); ErlDrvTermData response[] = { ERL_DRV_ATOM, driver_mk_atom("txn"), STATS_TUPLE(tasp, txnid), /* Transaction ID */ STATS_TUPLE(tasp, parentid), /* Transaction ID of parent */ STATS_TUPLE(tasp, pid), /* Process owning txn ID - pid_t */ ERL_DRV_ATOM, driver_mk_atom("tid"),/* OSX has 32-bit ints in erlang, so return as */ ERL_DRV_STRING, (ErlDrvTermData) tid_str, tid_str_len, /* a string */ ERL_DRV_TUPLE, 2, STATS_LSN_TUPLE(tasp, lsn), /* LSN when transaction began */ STATS_LSN_TUPLE(tasp, read_lsn), /* Read LSN for MVCC */ STATS_TUPLE(tasp, mvcc_ref), /* MVCC reference count */ // Start of list ERL_DRV_ATOM, driver_mk_atom("status"), ERL_DRV_ATOM, driver_mk_atom(status_str), ERL_DRV_TUPLE, 2, ERL_DRV_ATOM, driver_mk_atom("name"), ERL_DRV_STRING, (ErlDrvTermData) name, name_len, ERL_DRV_TUPLE, 2, // End of list ERL_DRV_NIL, ERL_DRV_LIST, 9+1, ERL_DRV_TUPLE, 2 }; driver_send_term(port, pid, response, sizeof(response) / sizeof(response[0])); }
void send_pointer(GEOSCommand *command, char *name, void *pointer) { ErlDrvTermData spec[] = {ERL_DRV_ATOM, driver_mk_atom("ok"), ERL_DRV_ATOM, driver_mk_atom(name), ERL_DRV_INT, (ErlDrvTermData) pointer, ERL_DRV_TUPLE, 2, ERL_DRV_TUPLE, 2}; driver_output_term(command->driver_data->port, spec, sizeof(spec) / sizeof(spec[0])); }
// Driver Start static ErlDrvData start(ErlDrvPort port, char* cmd) { sqlite3_drv_t* retval = (sqlite3_drv_t*) driver_alloc(sizeof(sqlite3_drv_t)); struct sqlite3 *db = NULL; int status = 0; char *db_name; retval->log = fopen(LOG_PATH, "a+"); if (!retval->log) { fprintf(stderr, "Can't create log file\n"); } fprintf(retval->log, "--- Start erlang-sqlite3 driver\nCommand line: [%s]\n", cmd); db_name = strstr(cmd, " "); if (!db_name) { fprintf(retval->log, "ERROR: DB name should be passed at command line\n"); db_name = DB_PATH; } else { ++db_name; // move to first character after ' ' } // Create and open the database sqlite3_open(db_name, &db); status = sqlite3_errcode(db); if (status != SQLITE_OK) { fprintf(retval->log, "ERROR: Unable to open file: %s because %s\n\n", db_name, sqlite3_errmsg(db)); } else { fprintf(retval->log, "Opened file %s\n", db_name); } // Set the state for the driver retval->port = port; retval->db = db; retval->key = 42; // FIXME Any way to get canonical path to the DB? // We need to ensure equal keys for different paths to the same file retval->async_handle = 0; retval->prepared_stmts = NULL; retval->prepared_count = 0; retval->prepared_alloc = 0; retval->atom_blob = driver_mk_atom("blob"); retval->atom_error = driver_mk_atom("error"); retval->atom_columns = driver_mk_atom("columns"); retval->atom_rows = driver_mk_atom("rows"); retval->atom_null = driver_mk_atom("null"); retval->atom_rowid = driver_mk_atom("rowid"); retval->atom_ok = driver_mk_atom("ok"); retval->atom_done = driver_mk_atom("done"); retval->atom_unknown_cmd = driver_mk_atom("unknown_command"); fflush(retval->log); return (ErlDrvData) retval; }
static void return_error_tuple(bdb_drv_t* pdrv, char* err_msg) { ErlDrvTermData spec[] = { ERL_DRV_ATOM, driver_mk_atom("error"), ERL_DRV_ATOM, driver_mk_atom(err_msg), ERL_DRV_TUPLE, 2}; #if ((ERL_DRV_EXTENDED_MAJOR_VERSION == 1) || ((ERL_DRV_EXTENDED_MAJOR_VERSION == 2) && (ERL_DRV_EXTENDED_MINOR_VERSION == 0))) driver_output_term(pdrv->port, spec, sizeof(spec) / sizeof(spec[0])); #else ErlDrvTermData mkport = driver_mk_port(pdrv->port); erl_drv_output_term(mkport, spec, sizeof(spec) / sizeof(spec[0])); #endif }
void reformat(ErlDrvPort port, char* buf, int len) { yajl_handle hand; /* generator config */ yajl_gen_config conf = { 1, " " }; yajl_gen g; yajl_status stat; /* allow comments */ yajl_parser_config cfg = { 1, 1 }; g = yajl_gen_alloc(&conf, NULL); /* ok. open file. let's read and parse */ hand = yajl_alloc(&callbacks, &cfg, NULL, (void *) g); /* read file data, pass to parser */ stat = yajl_parse(hand, (unsigned char*) buf, len); if (stat != yajl_status_ok && stat != yajl_status_insufficient_data) { char* err = (char*) yajl_get_error(hand, 1, (unsigned char*) buf, len); int len = strlen(err); ErlDrvTermData msg[] = { ERL_DRV_ATOM, driver_mk_atom("error"), ERL_DRV_BUF2BINARY, (ErlDrvTermData) err, (ErlDrvUInt) len, ERL_DRV_TUPLE, 2 }; driver_send_term(port, driver_caller(port), msg, sizeof(msg) / sizeof(msg[0])); } else { const unsigned char* json; unsigned int len; yajl_gen_get_buf(g, &json, &len); ErlDrvTermData msg[] = { ERL_DRV_ATOM, driver_mk_atom("ok"), ERL_DRV_BUF2BINARY, (ErlDrvTermData) json, (ErlDrvUInt) len, ERL_DRV_TUPLE, 2 }; driver_send_term(port, driver_caller(port), msg, sizeof(msg) / sizeof(msg[0])); yajl_gen_clear(g); } yajl_gen_free(g); yajl_free(hand); }
static void process_unkown(bdb_drv_t *bdb_drv, ErlIOVec *ev) { // Return {error, unkown_command} ErlDrvTermData spec[] = {ERL_DRV_ATOM, driver_mk_atom("error"), ERL_DRV_ATOM, driver_mk_atom("uknown_command"), ERL_DRV_TUPLE, 2}; #if ((ERL_DRV_EXTENDED_MAJOR_VERSION == 1) || ((ERL_DRV_EXTENDED_MAJOR_VERSION == 2) && (ERL_DRV_EXTENDED_MINOR_VERSION == 0))) driver_output_term(bdb_drv->port, spec, sizeof(spec) / sizeof(spec[0])); #else ErlDrvTermData mkport = driver_mk_port(bdb_drv->port); erl_drv_output_term(mkport, spec, sizeof(spec) / sizeof(spec[0])); #endif }
void send_caller(ErlDrvData drv_data, char *func) { int res; ErlDrvPort port = (ErlDrvPort) drv_data; ErlDrvTermData msg[] = { ERL_DRV_ATOM, driver_mk_atom("caller"), ERL_DRV_PORT, driver_mk_port(port), ERL_DRV_ATOM, driver_mk_atom(func), ERL_DRV_PID, driver_caller(port), ERL_DRV_TUPLE, (ErlDrvTermData) 4 }; res = erl_drv_output_term(driver_mk_port(port), msg, sizeof(msg)/sizeof(ErlDrvTermData)); if (res <= 0) driver_failure_atom(port, "erl_drv_output_term failed"); }
static void async_cleanup_and_send_mutex_stats(PortData* d, DB_MUTEX_STAT *msp) { // Save the port and pid references -- we need copies independent from the PortData // structure. Once we release the port_lock after clearing the cmd, it's possible that // the port could go away without waiting on us to finish. This is acceptable, but we need // to be certain that there is no overlap of data between the two threads. driver_send_term // is safe to use from a thread, even if the port you're sending from has already expired. ErlDrvPort port = d->port; ErlDrvTermData pid = d->port_owner; bdberl_async_cleanup(d); ErlDrvTermData response[] = { ERL_DRV_ATOM, driver_mk_atom("ok"), // Start of list ST_STATS_TUPLE(msp, mutex_align), /* Mutex alignment */ ST_STATS_TUPLE(msp, mutex_tas_spins), /* Mutex test-and-set spins */ ST_STATS_TUPLE(msp, mutex_cnt), /* Mutex count */ ST_STATS_TUPLE(msp, mutex_free), /* Available mutexes */ ST_STATS_TUPLE(msp, mutex_inuse), /* Mutexes in use */ ST_STATS_TUPLE(msp, mutex_inuse_max), /* Maximum mutexes ever in use */ ST_STATS_TUPLE(msp, region_wait), /* Region lock granted after wait. */ ST_STATS_TUPLE(msp, region_nowait), /* Region lock granted without wait. */ ST_STATS_TUPLE(msp, regsize), /* Region size. */ // End of list ERL_DRV_NIL, ERL_DRV_LIST, 9+1, ERL_DRV_TUPLE, 2 }; driver_send_term(port, pid, response, sizeof(response) / sizeof(response[0])); }
static void handle_monitor(ErlDrvData drv_data, ErlDrvMonitor *monitor) { MyDrvData *data = (MyDrvData *) drv_data; OneMonitor *p,*o; for (p = data->first, o = NULL; p != NULL && driver_compare_monitors(&p->mon,monitor); o = p, p = p->next) ; if (!p) { fprintf(stderr,"Spooky Monitor executed!\r\n"); } else { ErlDrvTermData spec[] = { ERL_DRV_ATOM, driver_mk_atom("monitor_fired"), ERL_DRV_PORT, driver_mk_port(data->port), ERL_DRV_PID, p->pid, ERL_DRV_TUPLE, TERM_DATA(3) }; if (!o) { data->first = p->next; } else { o->next = p->next; } driver_free(p); driver_send_term(data->port, data->ipid, spec, sizeof(spec)/sizeof(ErlDrvTermData)); } return; }
void es_peepEvents2(ErlDrvPort port, ErlDrvTermData caller, char *bp) { SDL_Event events[256]; int numevents, res, i, sz; Uint32 mask; char *start; ErlDrvBinary * bin; ErlDrvTermData rt[8]; mask = * (Uint32 *) bp; bp += sizeof(Uint32); numevents = *bp++; SDL_PumpEvents(); res = SDL_PeepEvents(events, numevents, SDL_GETEVENT, mask); bin = driver_alloc_binary(res*MAX_EVENT_SIZE); bp = start = bin->orig_bytes; for (i = 0; i < res; i++) { bp = encode_event(&(events[i]), bp); } sz = bp-start; rt[0] = ERL_DRV_ATOM; rt[1]=driver_mk_atom((char *) "_esdl_result_"); rt[2] = ERL_DRV_BINARY; rt[3] = (ErlDrvTermData) bin; rt[4] = sz; rt[5] = 0; rt[6] = ERL_DRV_TUPLE; rt[7] = 2; driver_send_term(port,caller,rt,8); driver_free_binary(bin); }
void erl_luam_multipcall(lua_drv_t *driver_data, char *buf, int index) { long args, level, ret_results; ei_decode_long(buf, &index, &args); /* level := function's index - 1 */ level = lua_gettop(driver_data->L) - args - 1; if(lua_pcall(driver_data->L, args, LUA_MULTRET, 0) == 0) { ret_results = lua_gettop(driver_data->L) - level; ErlDrvTermData spec[] = { ERL_DRV_ATOM, ATOM_OK, ERL_DRV_INT, (ErlDrvTermData) ret_results, ERL_DRV_TUPLE, 2 }; erl_drv_output_term(driver_data->drvport,spec,sizeof(spec)/sizeof(spec[0])); } else { const char *err = lua_tostring(driver_data->L, -1); ErlDrvTermData spec[] = { ERL_DRV_ATOM, ATOM_THROW, ERL_DRV_ATOM, driver_mk_atom("lua_error"), ERL_DRV_STRING, (ErlDrvTermData) err, strlen(err), ERL_DRV_TUPLE, 2, ERL_DRV_TUPLE, 2 }; erl_drv_output_term(driver_data->drvport,spec,sizeof(spec)/sizeof(spec[0])); } }
int erl_tess_impl(char* buff, ErlDrvPort port, ErlDrvTermData caller) { ErlDrvBinary* bin; int i; int num_vertices; GLdouble *n; int AP; int a_max = 2; int i_max = 6; num_vertices = * (int *) buff; buff += 8; /* Align */ n = (double *) buff; buff += 8*3; egl_tess.alloc_max = a_max*num_vertices*3; bin = driver_alloc_binary(egl_tess.alloc_max*sizeof(GLdouble)); egl_tess.error = 0; egl_tess.tess_coords = (double *) bin->orig_bytes; memcpy(egl_tess.tess_coords,buff,num_vertices*3*sizeof(GLdouble)); egl_tess.index_max = i_max*3*num_vertices; egl_tess.tess_index_list = (int *) driver_alloc(sizeof(int) * egl_tess.index_max); egl_tess.tess_coords = (double *) bin->orig_bytes; egl_tess.index_n = 0; egl_tess.alloc_n = num_vertices*3; gluTessNormal(tess, n[0], n[1], n[2]); gluTessBeginPolygon(tess, 0); gluTessBeginContour(tess); for (i = 0; i < num_vertices; i++) { gluTessVertex(tess, egl_tess.tess_coords+3*i, egl_tess.tess_coords+3*i); } gluTessEndContour(tess); gluTessEndPolygon(tess); AP = 0; ErlDrvTermData *rt; rt = (ErlDrvTermData *) driver_alloc(sizeof(ErlDrvTermData) * (13+egl_tess.index_n*2)); rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); for(i=0; i < egl_tess.index_n; i++) { rt[AP++] = ERL_DRV_INT; rt[AP++] = (int) egl_tess.tess_index_list[i]; }; rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = egl_tess.index_n+1; rt[AP++] = ERL_DRV_BINARY; rt[AP++] = (ErlDrvTermData) bin; rt[AP++] = egl_tess.alloc_n*sizeof(GLdouble); rt[AP++] = 0; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; // Return tuple {list, Bin} rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; // Result tuple driver_send_term(port,caller,rt,AP); /* fprintf(stderr, "List %d: %d %d %d \r\n", */ /* res, */ /* n_pos, */ /* (tess_alloc_vertex-new_vertices)*sizeof(GLdouble), */ /* num_vertices*6*sizeof(GLdouble)); */ driver_free_binary(bin); driver_free(egl_tess.tess_index_list); driver_free(rt); return 0; }
int term_buf_null(term_buf* buf) { CHECK_REQUIRE(buf, 2); buf->terms[buf->used++] = ERL_DRV_ATOM; buf->terms[buf->used++] = driver_mk_atom("null"); return OK; }
void testcase_drv_run(ErlDrvData drv_data, char *buf, ErlDrvSizeT len) { InternalTestCaseState_t *itcs = (InternalTestCaseState_t *) drv_data; ErlDrvTermData result_atom; ErlDrvTermData msg[12]; itcs->visible.command = buf; itcs->visible.command_len = len; if (setjmp(itcs->done_jmp_buf) == 0) { testcase_run((TestCaseState_t *) itcs); itcs->result = TESTCASE_SUCCEEDED; } switch (itcs->result) { case TESTCASE_SUCCEEDED: result_atom = driver_mk_atom("succeeded"); break; case TESTCASE_SKIPPED: result_atom = driver_mk_atom("skipped"); break; case TESTCASE_FAILED: default: result_atom = driver_mk_atom("failed"); break; } msg[0] = ERL_DRV_ATOM; msg[1] = (ErlDrvTermData) result_atom; msg[2] = ERL_DRV_PORT; msg[3] = itcs->port_id; msg[4] = ERL_DRV_ATOM; msg[5] = driver_mk_atom(itcs->visible.testcase_name); msg[6] = ERL_DRV_STRING; msg[7] = (ErlDrvTermData) itcs->comment; msg[8] = (ErlDrvTermData) strlen(itcs->comment); msg[9] = ERL_DRV_TUPLE; msg[10] = (ErlDrvTermData) 4; erl_drv_output_term(itcs->port_id, msg, 11); }
void send_boolean(GEOSCommand *command, char boolean) { ErlDrvTermData atom; switch(boolean) { case 0: atom = driver_mk_atom("false"); break; case 1: atom = driver_mk_atom("true"); break; default: atom = driver_mk_atom("error"); break; } ErlDrvTermData spec[] = {ERL_DRV_ATOM, driver_mk_atom("ok"), ERL_DRV_ATOM, atom, ERL_DRV_TUPLE, 2}; driver_output_term(command->driver_data->port, spec, sizeof(spec) / sizeof(spec[0])); }
static void return_ok(redis_drv_t *redis_drv, int msgno) { ErlDrvTermData spec[] = { // ERL_DRV_ATOM, driver_mk_atom(ok_msgs[msgno]), ERL_DRV_ATOM, driver_mk_atom("ok") }; driver_output_term(redis_drv->port, spec, sizeof(spec) / sizeof(spec[0])); }
static void return_error(redis_drv_t *redis_drv, int errorno) { ErlDrvTermData spec[] = { // ERL_DRV_ATOM, driver_mk_atom(error_msgs[errorno]), ERL_DRV_ATOM, driver_mk_atom("error") }; driver_output_term(redis_drv->port, spec, sizeof(spec) / sizeof(spec[0])); }