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); erl_drv_send_term(driver_mk_port(data->port), data->ipid, spec, sizeof(spec)/sizeof(ErlDrvTermData)); } return; }
void output(ErlDrvData drv_data, char *buf, ErlDrvSizeT len) { int res; ErlDrvPort port = (ErlDrvPort) drv_data; ErlDrvTermData msg[] = { ERL_DRV_PORT, driver_mk_port(port), ERL_DRV_ATOM, driver_mk_atom("caller"), ERL_DRV_PID, driver_caller(port), ERL_DRV_TUPLE, (ErlDrvTermData) 3 }; 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 int get_grnam (pwd_drv_t *drv, char *cmd) { struct group *grp = getgrnam (cmd); if (!grp) { fprintf (drv->log, "getgrnam returns NULL for %s\n", cmd); fflush (drv->log); return send_error (drv, "error", "unknown_name"); } size_t result_count = 0; ErlDrvTermData *result = make_group (drv, grp, &result_count); if (!result) { return send_error (drv, "error", "Couldn't allocate memory"); } int r = send_wrapped (driver_mk_port(drv->port), result, result_count); driver_free (result); return r; }
static int get_pwuid (pwd_drv_t *drv, char *cmd) { __uid_t uid = atoi (cmd); struct passwd *pwd = getpwuid (uid); if (!pwd) { fprintf (drv->log, "getpwuid returns NULL for %s\n", cmd); fflush (drv->log); return send_error (drv, "error", "unknown_uid"); } size_t result_count = 0; ErlDrvTermData *result = make_passwd (drv, pwd, &result_count); if (!result) { return send_error (drv, "error", "Couldn't allocate memory"); } int r = send_wrapped (driver_mk_port(drv->port), result, result_count); driver_free (result); return r; }
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] = driver_mk_port(itcs->port); 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; driver_output_term(itcs->port, msg, 11); }
static int prepare(sqlite3_drv_t *drv, char *command, int command_size) { int result; const char *rest; sqlite3_stmt *statement; ErlDrvTermData spec[6]; #ifdef DEBUG fprintf(drv->log, "Preparing statement: %.*s\n", command_size, command); fflush(drv->log); #endif result = sqlite3_prepare_v2(drv->db, command, command_size, &statement, &rest); if (result != SQLITE_OK) { return output_db_error(drv); } else if (statement == NULL) { return output_error(drv, SQLITE_MISUSE, "empty statement"); } if (drv->prepared_count >= drv->prepared_alloc) { drv->prepared_alloc = (drv->prepared_alloc != 0) ? 2*drv->prepared_alloc : 4; drv->prepared_stmts = driver_realloc(drv->prepared_stmts, drv->prepared_alloc * sizeof(sqlite3_stmt *)); } drv->prepared_stmts[drv->prepared_count] = statement; drv->prepared_count++; spec[0] = ERL_DRV_PORT; spec[1] = driver_mk_port(drv->port); spec[2] = ERL_DRV_UINT; spec[3] = drv->prepared_count - 1; spec[4] = ERL_DRV_TUPLE; spec[5] = 2; return driver_output_term(drv->port, spec, sizeof(spec) / sizeof(spec[0])); }
static int reply_ok_binary(descriptor_t *desc, char *ptr, int beg_offset, int length) { ErlDrvTermData msg[24]; int i = 0; int res; i = LOAD_PORT(msg, i, driver_mk_port(desc->port)); i = LOAD_ATOM(msg, i, am_ok); i = LOAD_BINARY(msg, i, edtk_alloced_ptr2ErlDrvBinary(ptr), beg_offset, length); i = LOAD_TUPLE(msg, i, 3); edtk_debug("%s: i = %d, ptr = 0x%lx, start = %d, end = %d", __FUNCTION__, i, ptr, beg_offset, length); res = driver_output_term(desc->port, msg, i); /* driver_output_term() incrs refc, and we're done, so decr refc */ /* ** We _know_ that "ptr" points to memory allocated by ** edtk_driver_alloc_wrapper(), so edtk_alloced_ptr2ErlDrvBinary() ** is safe in this case. If it weren't safe, then the binary ** must be returned by an xtra_return, which means we ** reply_ok_binary()) are never called! */ driver_free_binary(edtk_alloced_ptr2ErlDrvBinary(ptr)); edtk_debug("%s: res = %d", __FUNCTION__, res); return res; }
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]); }
/* ** Generate a fair async key prom an ErlDrvPort ** The port data gives a fair distribution grom port pointer ** to unsigned integer - to be used in key for driver_async below. */ unsigned int driver_async_port_key(ErlDrvPort port) { ErlDrvTermData td = driver_mk_port(port); if (td == (ErlDrvTermData) NIL) { return 0; } return (unsigned int) (UWord) internal_port_data(td); }
static ErlDrvData md4drv_start(ErlDrvPort port, char *buf) { t_md4drv *md4 = (t_md4drv*) driver_alloc(sizeof(t_md4drv)); if (md4 == NULL) return (ErlDrvData) -1; md4->port = port; md4->dport = driver_mk_port(port); return (ErlDrvData) md4; }
static ErlDrvData iconvdrv_start(ErlDrvPort port, char *buf) { t_iconvdrv *iconv = (t_iconvdrv*) driver_alloc(sizeof(t_iconvdrv)); if (iconv == NULL) return (ErlDrvData) -1; iconv->port = port; iconv->dport = driver_mk_port(port); return (ErlDrvData) iconv; }
static int get_pwall (pwd_drv_t *drv) { size_t pwd_count = 0; setpwent (); while (getpwent ()) pwd_count++; endpwent (); size_t term_count = passwd_term_count (); size_t result_count = pwd_count * term_count; ErlDrvTermData *result = (ErlDrvTermData *) driver_alloc (sizeof (ErlDrvTermData) * (result_count + 3)); if (!result) { fprintf (drv->log, "Couldn't allocate memory for result\n"); fflush (drv->log); return send_error (drv, "error", "Couldn't allocate memory for result"); } char **names = (char **) driver_alloc (sizeof (char *) * pwd_count); char **pwds = (char **) driver_alloc (sizeof (char *) * pwd_count); setpwent (); size_t result_idx = 0; struct passwd *pwd = getpwent (); while (pwd) { fill_passwd (&result[result_idx * term_count], pwd, &names[result_idx], &pwds[result_idx]); result_idx++; pwd = getpwent (); } endpwent (); result[result_count++] = ERL_DRV_NIL; result[result_count++] = ERL_DRV_LIST; result[result_count++] = pwd_count + 1; int r = send_wrapped (driver_mk_port(drv->port), result, result_count); size_t i = 0; for (; i < pwd_count; ++i) { driver_free (pwds[i]); driver_free (names[i]); } driver_free (pwds); driver_free (names); driver_free (result); return r; }
static inline int output_done(sqlite3_drv_t *drv) { // Return {Port, ok} ErlDrvTermData spec[] = { ERL_DRV_PORT, driver_mk_port(drv->port), ERL_DRV_ATOM, drv->atom_done, ERL_DRV_TUPLE, 2 }; return driver_output_term(drv->port, spec, sizeof(spec) / sizeof(spec[0])); }
static void av_exit(H264Decoder *d) { ErlDrvTermData reply[] = { ERL_DRV_ATOM, driver_mk_atom("av_decoder_closed"), ERL_DRV_PORT, driver_mk_port(d->port), ERL_DRV_TUPLE, 2 }; driver_output_term(d->port, reply, sizeof(reply) / sizeof(reply[0])); driver_exit(d->port, 0); }
// Unknown Command static int unknown(sqlite3_drv_t *drv, char *command, int command_size) { // Return {Port, error, unknown_command} ErlDrvTermData spec[] = { ERL_DRV_PORT, driver_mk_port(drv->port), ERL_DRV_ATOM, drv->atom_error, ERL_DRV_INT, (ErlDrvTermData) ((ErlDrvSInt) -1), ERL_DRV_ATOM, drv->atom_unknown_cmd, ERL_DRV_TUPLE, 4 }; return driver_output_term(drv->port, spec, sizeof(spec) / sizeof(spec[0])); }
static void return_ok(bdb_drv_t* pdrv) { ErlDrvTermData spec[] = {ERL_DRV_ATOM, driver_mk_atom("ok")}; #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 }
static ErlDrvData inpevt_start(ErlDrvPort port, char *command) { IEContext *ctx = 0; ctx = (IEContext*) driver_alloc(sizeof(IEContext)); ctx->mDescriptor = -1; ctx->mPort = port; ctx->mDport = driver_mk_port(port); ctx->mDevice[0] = 0; // set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY); set_port_control_flags(port, 0); return (ErlDrvData) ctx; }
static inline int output_error( sqlite3_drv_t *drv, int error_code, const char *error) { int term_count = 2, term_allocated = 13; ErlDrvTermData *dataset = driver_alloc(sizeof(ErlDrvTermData) * term_allocated); dataset[0] = ERL_DRV_PORT; dataset[1] = driver_mk_port(drv->port); return_error(drv, error_code, error, &dataset, &term_count, &term_allocated, NULL); term_count += 2; dataset[11] = ERL_DRV_TUPLE; dataset[12] = 2; driver_output_term(drv->port, dataset, term_count); return 0; }
/* send {P, ok} to caller */ static ErlDrvSSizeT driver_send_ok(t_iconvdrv *iv) { int i = 0; ErlDrvTermData to, spec[10]; to = driver_caller(iv->port); i = LOAD_PORT(spec, i, iv->dport); i = LOAD_ATOM(spec, i, am_ok); i = LOAD_TUPLE(spec, i, 2); return erl_drv_send_term(driver_mk_port(iv->port), to, spec, i); }
static ErlDrvData start(ErlDrvPort port, char* cmd) { dnssd_drv_t* retval = (dnssd_drv_t*) driver_alloc(sizeof(dnssd_drv_t)); retval->sd_ref = NULL; retval->erl_port = port; retval->term_port = driver_mk_port(port); retval->term_ok = driver_mk_atom("ok"); retval->term_error = driver_mk_atom("error"); retval->term_enumerate = driver_mk_atom("enumerate"); retval->term_browse = driver_mk_atom("browse"); retval->term_resolve = driver_mk_atom("resolve"); retval->term_register = driver_mk_atom("register"); return (ErlDrvData) retval; }
static void av_decoder_decoded(ErlDrvData drv_data, ErlDrvThreadData thread_data) { H264Decoder *decoder = (H264Decoder *)drv_data; H264Frame *frame = (H264Frame *)thread_data; // fprintf(stderr, "Decoding finished: %p %ld\r\n", frame->yuv, frame->yuv ? frame->yuv->orig_size : -1); if(frame->yuv) { // av_log(NULL,AV_LOG_WARNING,"\nPORTyuv:: %i\n",decoder->port); ErlDrvTermData reply[] = { ERL_DRV_ATOM, driver_mk_atom("yuv"), ERL_DRV_PORT, driver_mk_port(decoder->port), ERL_DRV_BINARY, (ErlDrvTermData)frame->yuv, (ErlDrvTermData)frame->yuv->orig_size, 0, ERL_DRV_TUPLE, 3 }; driver_output_term(decoder->port, reply, sizeof(reply) / sizeof(reply[0])); driver_free_binary(frame->yuv); } else if(frame->sample){ // av_log(NULL,AV_LOG_WARNING,"\nPORTsample:: %i\n",decoder->port); ErlDrvTermData reply[] = { ERL_DRV_ATOM, driver_mk_atom("sample"), ERL_DRV_PORT, driver_mk_port(decoder->port), ERL_DRV_BINARY, (ErlDrvTermData)frame->sample, (ErlDrvTermData)frame->sample->orig_size, 0, ERL_DRV_TUPLE, 3 }; driver_output_term(decoder->port, reply, sizeof(reply) / sizeof(reply[0])); driver_free_binary(frame->sample); } else { // av_log(decoder->dec,AV_LOG_ERROR,"NOT YUV"); av_log(NULL,AV_LOG_WARNING,"\nPORTelse:: %i\n",decoder->port); ErlDrvTermData reply[] = { ERL_DRV_ATOM, driver_mk_atom("yuv"), ERL_DRV_PORT, driver_mk_port(decoder->port), ERL_DRV_TUPLE, 2 }; driver_output_term(decoder->port, reply, sizeof(reply) / sizeof(reply[0])); } driver_free(frame); }
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 }
static void zmqdrv_socket_error(zmq_drv_t *drv, ErlDrvTermData pid, uint32_t idx, int err) { // Return {zmq, Socket::integer(), {error, Reason::atom()}} ErlDrvTermData spec[] = {ERL_DRV_ATOM, am_zmq, ERL_DRV_PORT, driver_mk_port(drv->port), ERL_DRV_UINT, idx, ERL_DRV_TUPLE, 2, ERL_DRV_ATOM, am_error, ERL_DRV_ATOM, error_atom(err), ERL_DRV_TUPLE, 2, ERL_DRV_TUPLE, 3}; driver_send_term(drv->port, pid, spec, sizeof(spec)/sizeof(spec[0])); }
static ErlDrvData start(ErlDrvPort port, char *command) { async_blast_data_t *abd; abd = driver_alloc(sizeof(async_blast_data_t)); if (!abd) return ERL_DRV_ERROR_GENERAL; abd->port = port; abd->port_id = driver_mk_port(port); abd->counter = 0; return (ErlDrvData) abd; }
/* send {P, error, Error} to caller */ static ErlDrvSSizeT driver_send_error(t_iconvdrv *iv, ErlDrvTermData *am) { int i = 0; ErlDrvTermData to, spec[8]; to = driver_caller(iv->port); i = LOAD_PORT(spec, i, iv->dport); i = LOAD_ATOM(spec, i, am_error); i = LOAD_ATOM(spec, i, *am); i = LOAD_TUPLE(spec, i, 3); return erl_drv_send_term(driver_mk_port(iv->port), to, spec, i); }
/* send {P, value, Bin} to caller */ static ErlDrvSSizeT driver_send_bin(t_iconvdrv *iv, ErlDrvBinary *bin, ErlDrvSizeT len) { int i = 0; ErlDrvTermData to, spec[10]; to = driver_caller(iv->port); i = LOAD_PORT(spec, i, iv->dport); i = LOAD_ATOM(spec, i, am_value); i = LOAD_BINARY(spec, i, bin, 0, len); i = LOAD_TUPLE(spec, i, 3); return erl_drv_send_term(driver_mk_port(iv->port), to, spec, i); }
static void fail_term(ErlDrvTermData* msg, int len, int line) { int status = erl_drv_output_term(driver_mk_port(erlang_port), msg, len); if (status == 1) { char buf[1024]; sprintf(buf, "%s:%d: unexpected success", __FILE__, line); driver_failure_atom(erlang_port, buf); } else if (status == 0) { char buf[1024]; sprintf(buf, "%s:%d: unexpected port error", __FILE__, line); driver_failure_atom(erlang_port, buf); } }
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 }
static int reply_ok(descriptor_t *desc) { ErlDrvTermData msg[24]; int i = 0; int res; i = LOAD_PORT(msg, i, driver_mk_port(desc->port)); i = LOAD_ATOM(msg, i, am_ok); i = LOAD_TUPLE(msg, i, 2); edtk_debug("reply_ok: i = %d", i); res = driver_output_term(desc->port, msg, i); edtk_debug("reply_ok: res = %d", res); return res; }
void gen_http_drv_ready_output(ErlDrvData handle, ErlDrvEvent event) { HTTP* d = (HTTP*) handle; if(d->mode == REQUEST_MODE && d->state == CONNECTING_STATE) { accept_connection(d); return; } SysIOVec* vec; int vlen = 0; size_t written; vec = driver_peekq(d->port, &vlen); if(!vec || !vlen) { deactivate_write(d); return; } written = writev(d->socket, (const struct iovec *)vec, vlen > IOV_MAX ? IOV_MAX : vlen); if(vlen > IOV_MAX) { fprintf(stderr, "Buffer overloaded: %d, %d\r\n", vlen, (int)(driver_sizeq(d->port) - written)); } if(written == -1) { if((errno != EWOULDBLOCK) && (errno != EINTR) && (errno != EAGAIN)) { // fprintf(stderr, "Error in writev: %s, %d bytes left\r\n", strerror(errno), (int)driver_sizeq(d->port)); tcp_exit(d); return; } } else { ErlDrvSizeT rest = driver_deq(d->port, written); if(rest == 0) { ErlDrvTermData reply[] = { ERL_DRV_ATOM, atom_http, ERL_DRV_PORT, driver_mk_port(d->port), ERL_DRV_ATOM, atom_empty, ERL_DRV_TUPLE, 3 }; pid_list_send(d->exhausted, d->port, reply, sizeof(reply) / sizeof(reply[0])); pid_list_free(&d->exhausted); set_busy_port(d->port, 0); } // fprintf(stderr, "Network write: %d (%d)\r\n", (int)written, (int)rest); } }