Example #1
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]));
  }
}
Example #2
0
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]));
  }
}
Example #3
0
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);
}
Example #4
0
static void
reply_boolean(lua_drv_t *driver_data, int res) {
    ErlDrvTermData spec[] = {
        ERL_DRV_ATOM,   ATOM_OK,
        ERL_DRV_ATOM, driver_mk_atom(res ? "true" : "false"),
        ERL_DRV_TUPLE,  2
    };
    erl_drv_output_term(driver_data->drvport, spec, sizeof(spec) / sizeof(spec[0]));
}
Example #5
0
static void
reply_throw(lua_drv_t *driver_data, const char *err)
{
  ErlDrvTermData spec[] = {
        ERL_DRV_ATOM,   ATOM_THROW,
        ERL_DRV_STRING, (ErlDrvTermData) err, strlen(err),
        ERL_DRV_TUPLE,  2
  };
  erl_drv_output_term(driver_data->drvport, 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

}
Example #7
0
void
erl_lua_gettop(lua_drv_t *driver_data, char *buf, int index)
{
  int size;

  size = lua_gettop(driver_data->L);

  ErlDrvTermData spec[] = {
        ERL_DRV_ATOM,   ATOM_OK,
        ERL_DRV_INT, (ErlDrvTermData) size,
        ERL_DRV_TUPLE,  2
  };
  erl_drv_output_term(driver_data->drvport, spec, sizeof(spec) / sizeof(spec[0]));
}
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

}
Example #9
0
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

}
Example #11
0
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");
}
Example #12
0
void
erl_lua_next(lua_drv_t *driver_data, char *buf, int index)
{
  long i;
  int ret;

  ei_decode_long(buf, &index, &i);

  ret = lua_next(driver_data->L, i);

  ErlDrvTermData spec[] = {
        ERL_DRV_ATOM,   ATOM_OK,
        ERL_DRV_INT, (ErlDrvTermData) ret,
        ERL_DRV_TUPLE,  2
  };
  erl_drv_output_term(driver_data->drvport, spec, sizeof(spec) / sizeof(spec[0]));
}
Example #13
0
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);
}
Example #14
0
static int
send_wrapped(ErlDrvTermData port, ErlDrvTermData* term, int n)
{
    ErlDrvTermData *wrapped = (ErlDrvTermData *) driver_alloc (sizeof(ErlDrvTermData) * (n + 6));
    wrapped[0] = ERL_DRV_ATOM;
    wrapped[1] = driver_mk_atom ("pwd");
    wrapped[2] = ERL_DRV_PORT;
    wrapped[3] = port;
    memcpy(wrapped + 4, term, n * sizeof(ErlDrvTermData));
    wrapped[n+4] = ERL_DRV_TUPLE;
    wrapped[n+5] = 3;

    int result = erl_drv_output_term (port, wrapped, n + 6);

    driver_free(wrapped);

    return result;
}
Example #15
0
void
erl_lua_tolstring(lua_drv_t *driver_data, char *buf, int index)
{
  size_t len;
  long i;
  const char *str;

  ei_decode_long(buf, &index, &i);

  str = lua_tolstring(driver_data->L, i, &len);

  ErlDrvTermData spec[] = {
        ERL_DRV_ATOM,   ATOM_OK,
        ERL_DRV_BUF2BINARY, (ErlDrvTermData) str, len,
        ERL_DRV_TUPLE,  2
  };
  erl_drv_output_term(driver_data->drvport, spec, sizeof(spec) / sizeof(spec[0]));
}
static void return_ok_empty_list(bdb_drv_t* pdrv) {

    ErlDrvTermData empty_spec[] = {

                            ERL_DRV_ATOM, driver_mk_atom("ok"),

                            ERL_DRV_NIL,

                            ERL_DRV_LIST, 1, 

                            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, empty_spec, sizeof(empty_spec) / sizeof(empty_spec[0]));
#else
    ErlDrvTermData mkport = driver_mk_port(pdrv->port);
    erl_drv_output_term(mkport, empty_spec, sizeof(empty_spec) / sizeof(empty_spec[0]));
#endif

}
Example #17
0
void
erl_lua_objlen(lua_drv_t *driver_data, char *buf, int index)
{
  long i;
  size_t size;

  ei_decode_long(buf, &index, &i);

#if LUA_VERSION_NUM > 501
  size = lua_rawlen(driver_data->L, i);
#else
  size = lua_objlen(driver_data->L, i);
#endif

  ErlDrvTermData spec[] = {
        ERL_DRV_ATOM,   ATOM_OK,
        ERL_DRV_INT, (ErlDrvTermData) size,
        ERL_DRV_TUPLE,  2
  };
  erl_drv_output_term(driver_data->drvport, spec, sizeof(spec) / sizeof(spec[0]));
}
Example #18
0
void
erl_lua_tonumber(lua_drv_t *driver_data, char *buf, int index)
{
  long i;
  double res;
  int encode_i = 0;
  int size;
  char *eibuf;

  ei_decode_long(buf, &index, &i);

  res = lua_tonumber(driver_data->L, i);

  ei_encode_version(NULL, &encode_i);
  if ((long long) res == res) {
    ei_encode_longlong(NULL, &encode_i, (long long) res);
    size = encode_i;
    encode_i = 0;
    eibuf = malloc(sizeof(char) * (size + 1));

    ei_encode_version(eibuf, &encode_i);
    ei_encode_longlong(eibuf, &encode_i, res);
  } else {
    ei_encode_double(NULL, &encode_i, res);
    size = encode_i;
    encode_i = 0;
    eibuf = malloc(sizeof(char) * (size + 1));

    ei_encode_version(eibuf, &encode_i);
    ei_encode_double(eibuf, &encode_i, res);
  }

  ErlDrvTermData spec[] = {
        ERL_DRV_ATOM,   ATOM_OK,
        ERL_DRV_BUF2BINARY, (ErlDrvTermData) eibuf, size,
        ERL_DRV_TUPLE,  2
  };
  erl_drv_output_term(driver_data->drvport, spec, sizeof(spec) / sizeof(spec[0]));
  free(eibuf);
}
Example #19
0
static void output(ErlDrvData drv_data,
		   char *buf, ErlDrvSizeT len)
{
    consume_timeslice_data_t *ctsd = (consume_timeslice_data_t *) drv_data;
    int res;

    if (ctsd->consume_timeslice) {
	int res = erl_drv_consume_timeslice(ctsd->port, 50);
	if (res < 0) {
	    driver_failure_atom(ctsd->port, "erl_drv_consume_timeslice() failed");
	    return;
	}
    }

    res = erl_drv_output_term(ctsd->tport,
			      ctsd->cmd_msg,
			      sizeof(ctsd->cmd_msg)/sizeof(ErlDrvTermData));
    if (res <= 0) {
	driver_failure_atom(ctsd->port, "erl_drv_output_term() failed");
	return;
    }
}
Example #20
0
static ErlDrvSSizeT syslogdrv_control(ErlDrvData handle, unsigned int command,
                                      char *buf, ErlDrvSizeT len,
                                      char **rbuf, ErlDrvSizeT rlen)
{
    syslogdrv_t* d = (syslogdrv_t*)handle;
    int index = 0, version, arity, type, size;

    if (command != SYSLOGDRV_OPEN) {
        return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG;
    }

    if (ei_decode_version(buf, &index, &version)) {
        return encode_error(*rbuf, "badver");
    }
    if (ei_decode_tuple_header(buf, &index, &arity) || arity != 4) {
        return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG;
    }
    if (ei_get_type(buf, &index, &type, &size)) {
        return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG;
    }
    if (type == ERL_STRING_EXT) {
        long logopt, facility, len;
        ErlDrvBinary* ref = 0;

        syslogdrv_t* nd = (syslogdrv_t*)driver_alloc(sizeof(syslogdrv_t));
        if (nd == NULL) {
            return encode_error(*rbuf, "enomem");
        }
        nd->ident = driver_alloc(size+1);
        if (nd->ident == NULL) {
            return encode_error(*rbuf, "enomem");
        }
        if (ei_decode_string(buf, &index, nd->ident)) {
            driver_free(nd->ident);
            driver_free(nd);
            return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG;
        }
        if (ei_decode_long(buf, &index, &logopt) ||
            ei_decode_long(buf, &index, &facility)) {
            driver_free(nd->ident);
            driver_free(nd);
            return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG;
        }
        if (ei_get_type(buf, &index, &type, &size)) {
            driver_free(nd->ident);
            driver_free(nd);
            return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG;
        }
        if (type != ERL_BINARY_EXT) {
            driver_free(nd->ident);
            driver_free(nd);
            return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG;
        }
        ref = driver_alloc_binary(size);
        if (ref == NULL) {
            return encode_error(*rbuf, "enomem");
        }
        if (ei_decode_binary(buf, &index, ref->orig_bytes, &len)) {
            driver_free_binary(ref);
            driver_free(nd->ident);
            driver_free(nd);
            return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG;
        }
        nd->logopt = (int)logopt;
        nd->facility = (int)facility;
        nd->open = 1;
        {
            ErlDrvTermData refdata = TERM_DATA(ref->orig_bytes);
            ErlDrvPort port = d->port;
            ErlDrvTermData pid = driver_caller(port);
            ErlDrvData data = (ErlDrvData)nd;
            nd->port = driver_create_port(port, pid, DRV_NAME, data);
            if (nd->port == (ErlDrvPort)-1) {
                driver_free_binary(ref);
                driver_free(nd->ident);
                driver_free(nd);
                return (ErlDrvSSizeT)ERL_DRV_ERROR_GENERAL;
            }
            set_port_control_flags(nd->port, PORT_CONTROL_FLAG_BINARY);
            ErlDrvTermData term[] = {
                ERL_DRV_EXT2TERM, refdata, ref->orig_size,
                ERL_DRV_ATOM, driver_mk_atom("ok"),
                ERL_DRV_PORT, driver_mk_port(nd->port),
                ERL_DRV_TUPLE, 2,
                ERL_DRV_TUPLE, 2,
            };
            erl_drv_output_term(driver_mk_port(port), term, sizeof term/sizeof *term);
        }
        driver_free_binary(ref);
        return 0;
    } else {
        return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG;
    }
}
static void process_count( bdb_drv_t* pdrv, ErlIOVec *ev) {

    DB_BTREE_STAT* btree_stats;
    DB_HASH_STAT* hash_stats;

    int ret, count;

    count = 0;

    if (pdrv->pcfg == NULL) {
        return_error_tuple(pdrv, "Database not opened!");
        return;
    }

    if (pdrv->pcfg->pdb == NULL) {
        return_error_tuple(pdrv, "Database not opened!");
        return;
    }



    while (1) {

        if (pdrv->pcfg->db_type == DB_BTREE) {

            ret = pdrv->pcfg->pdb->stat(pdrv->pcfg->pdb, NULL, &btree_stats, DB_FAST_STAT);

            if (ret != 0) {

                if (count > 2) {
                    return_error_tuple(pdrv, db_strerror(ret));
                    break;
                } else {
                    count = count + 1;
                    usleep(1000);
                }

            } else {

                ErlDrvTermData spec[] = {ERL_DRV_ATOM, driver_mk_atom("ok"),

                    ERL_DRV_INT, btree_stats->bt_nkeys,

                    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


                free(btree_stats);

                break;
            }


        } else {

            ret = pdrv->pcfg->pdb->stat(pdrv->pcfg->pdb, NULL, &hash_stats, 0);

            if (ret != 0) {

                if (count > 2) {
                    return_error_tuple(pdrv, db_strerror(ret));
                    break;
                } else {
                    count = count + 1;
                    usleep(1000);
                }

            } else {

                ErlDrvTermData spec[] = {ERL_DRV_ATOM, driver_mk_atom("ok"),

                    ERL_DRV_INT, hash_stats->hash_nkeys,

                    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


                free(hash_stats);

                break;
            }


        }

    }

    return;

}
static void bulk_get_hash (u_int32_t offset, u_int32_t count, bdb_drv_t *pdrv) {

    int ret;
    size_t retklen, retdlen;
    void *retkey, *retdata;
    void* p;

    DB*  pdb;
    DBC* pdbc = NULL;
    DBT  key, data;
   
    db_recno_t curr         = 1;
    db_recno_t limit        = 1;
    db_recno_t actual_count = 0;

    ErlDrvTermData *spec;
 
    u_int32_t spec_items, idx;

    curr  = offset;
    limit = offset + count;

    pdb = pdrv->pcfg->pdb;

    memset(&key, 0, sizeof(key));
    memset(&data, 0, sizeof(data));

    data.data  = pdrv->pcfg->buffer;
    data.ulen  = pdrv->pcfg->bulk_get_buffer_size_bytes;
    data.flags = DB_DBT_USERMEM;

    if ((ret = pdb->cursor(pdb, NULL, &pdbc, 0)) != 0) {
        return_error_tuple(pdrv, db_strerror(ret));
        return;
    }

    //Fast forward to the correct index
    idx = 1;

    while ((ret = pdbc->c_get(pdbc, &key, &data, DB_NEXT)) == 0) {

        idx++;

        if (idx >= offset) { break; }
    }

    if ((ret != DB_NOTFOUND) && (ret != 0)) {
        return_error_tuple(pdrv, db_strerror(ret));

    } else if (ret == DB_NOTFOUND) {
        return_ok_empty_list(pdrv);

    } else {

            if ((ret = pdbc->c_get(pdbc, &key, &data, DB_MULTIPLE_KEY | DB_CURRENT)) != 0) {

                if (ret == DB_NOTFOUND) {
                return_ok_empty_list(pdrv);
                } else {
                    return_error_tuple(pdrv, db_strerror(ret));
                }

            } else {

                //First count the number of recs...
                for (DB_MULTIPLE_INIT(p, &data); curr < limit; curr++) {

                    DB_MULTIPLE_KEY_NEXT(p, &data, retkey, retklen, retdata, retdlen);

                    if (p == NULL) {
                        break;
                    } else {
                        actual_count++;
                    }
        
                }

                spec_items = (8 * actual_count) + 7;

                spec = malloc(sizeof(ErlDrvTermData) * spec_items);

                if (spec == NULL) {
                    return_error_tuple(pdrv, "Could not allocate memory for operation!");
                } else {

                    spec[0] = ERL_DRV_ATOM;
                    spec[1] = driver_mk_atom("ok");

                    //Now pipe the data...
                    p    = NULL;
                    curr = 0;

                    for (DB_MULTIPLE_INIT(p, &data); curr < actual_count; curr++) {

                        DB_MULTIPLE_KEY_NEXT(p, &data, retkey, retklen, retdata, retdlen);

                        if (p == NULL) {
                            break;
                        } else {

                            idx = 2 + (curr * 8);

                            spec[idx + 0] = ERL_DRV_STRING;
                            spec[idx + 1] = (ErlDrvTermData)retkey;
                            spec[idx + 2] = retklen;

                            spec[idx + 3] = ERL_DRV_STRING;
                            spec[idx + 4] = (ErlDrvTermData)retdata;
                            spec[idx + 5] = retdlen;

                            spec[idx + 6] = ERL_DRV_TUPLE;
                            spec[idx + 7] = 2;
     
                       }

                    }

                    spec[spec_items - 5] = ERL_DRV_NIL;

                    spec[spec_items - 4] = ERL_DRV_LIST;
                    spec[spec_items - 3] = actual_count + 1;

                    spec[spec_items - 2] = ERL_DRV_TUPLE;
                    spec[spec_items - 1] = 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, spec_items);
#else
                    ErlDrvTermData mkport = driver_mk_port(pdrv->port);
                    erl_drv_output_term(mkport, spec, spec_items);
#endif

                    free(spec);

                }


        }

    }


    pdbc->c_close(pdbc);

    return;

 }
static void get (u_int32_t key_size, void* praw_key, bdb_drv_t *pdrv) {

    DB* pdb = pdrv->pcfg->pdb;

    DBT key;
    DBT data;

    int ret, count;

    memset(&key, 0, sizeof(DBT));
    memset(&data, 0, sizeof(DBT));

    key.data   = praw_key,
    key.size   = key_size,
    data.flags = DB_DBT_MALLOC;

    count = 0;

    while (1) {

        ret = pdb->get(pdb, 0, &key, &data, 0);

        if        (ret == 0) {

            ErlDrvTermData spec[] = {   
                                    ERL_DRV_ATOM, driver_mk_atom("ok"),

                                    ERL_DRV_STRING, (ErlDrvTermData) data.data, data.size,
                 
                                    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

            free(data.data);

            break;
        } else if (ret == DB_LOCK_DEADLOCK) {
            if (count < 5) {
                count = count + 1;
                usleep(1000);
            } else {
                return_error_tuple(pdrv, db_strerror(ret));
                break;
            }

        } else {

            if (ret != DB_NOTFOUND) {
                return_error_tuple(pdrv, db_strerror(ret));
            } else {
                return_error_tuple(pdrv, "not_found");
            }

            break;
        }

    }

    return;

}
Example #24
0
static void output_term(ErlDrvTermData* msg, int len)
{
    if (erl_drv_output_term(driver_mk_port(erlang_port), msg, len) <= 0) {
	driver_failure_atom(erlang_port, "erl_drv_output_term_failed");
    }
}
Example #25
0
static void send_term_drv_run(ErlDrvData port, char *buf, ErlDrvSizeT count)
{
    char buf7[1024];
    ErlDrvTermData spec[1024];
    ErlDrvTermData* msg = spec;
    ErlDrvBinary* bins[15];
    int bin_ix = 0;
    ErlDrvSInt64 s64[15];
    int s64_ix = 0;
    ErlDrvUInt64 u64[15];
    int u64_ix = 0;
    int i = 0;

    for (i=0; i<count; i++) switch (buf[i]) {
    case 0:
	msg[0] = ERL_DRV_NIL;
	msg += 1;
	break;

    case 1: 			/* Most term types inside a tuple. */
	{
	    double f = 3.1416;

	    msg[0] = ERL_DRV_ATOM;
	    msg[1] = driver_mk_atom("blurf");
	    msg[2] = ERL_DRV_INT;
	    msg[3] = (ErlDrvTermData) 42;
	    msg[4] = ERL_DRV_NIL;
	    msg[5] = ERL_DRV_INT;
	    msg[6] = (ErlDrvTermData) -42;
	    msg[7] = ERL_DRV_TUPLE;
	    msg[8] = (ErlDrvTermData) 0;
	    msg[9] = ERL_DRV_PORT;
	    msg[10] = driver_mk_port(erlang_port);
	    msg[11] = ERL_DRV_STRING_CONS;
	    msg[12] = (ErlDrvTermData) "abc";
	    msg[13] = (ErlDrvTermData) 3;
	    msg[14] = ERL_DRV_LIST;
	    msg[15] = (ErlDrvTermData) 3;
	    msg[16] = ERL_DRV_STRING;
	    msg[17] = (ErlDrvTermData) "kalle";
	    msg[18] = (ErlDrvTermData) 5;
	    msg[19] = ERL_DRV_FLOAT;
	    msg[20] = (ErlDrvTermData) &f;
	    msg[21] = ERL_DRV_PID;
	    msg[22] = driver_connected(erlang_port);
	    msg[23] = ERL_DRV_MAP;
	    msg[24] = (ErlDrvTermData) 0;
	    msg[25] = ERL_DRV_TUPLE;
	    msg[26] = (ErlDrvTermData) 8;
	    msg += 27;
	}
	break;

    case 2:			/* Deep stack */
	{
	    int i;
	    
	    for (i = 0; i < 400; i += 2) {
		msg[i] = ERL_DRV_INT;
		msg[i+1] = (ErlDrvTermData) (i / 2);
	    }
	    msg[i] = ERL_DRV_NIL;
	    msg[i+1] = ERL_DRV_LIST;
	    msg[i+2] = (ErlDrvTermData) 201;
	    msg += i+3;
	}
	break;

    case 3:			/* Binaries */
	{
	    ErlDrvBinary* bin;
	    int i;

	    bin = bins[bin_ix++] = driver_alloc_binary(256);
	    for (i = 0; i < 256; i++) {
		bin->orig_bytes[i] = i;
	    }
	    msg[0] = ERL_DRV_BINARY;
	    msg[1] = (ErlDrvTermData) bin;
	    msg[2] = (ErlDrvTermData) 256;
	    msg[3] = (ErlDrvTermData) 0;
	    msg[4] = ERL_DRV_BINARY;
	    msg[5] = (ErlDrvTermData) bin;
	    msg[6] = (ErlDrvTermData) 256-23-17;
	    msg[7] = (ErlDrvTermData) 23;
	    msg[8] = ERL_DRV_TUPLE;
	    msg[9] = (ErlDrvTermData) 2;
	    msg += 10;
	}
	break;

    case 4:			/* Pids */
	msg[0] = ERL_DRV_PID;
	msg[1] = driver_connected(erlang_port);
	msg[2] = ERL_DRV_PID;
	msg[3] = driver_caller(erlang_port);
	msg[4] = ERL_DRV_TUPLE;
	msg[5] = (ErlDrvTermData) 2;
	msg += 6;
	break;

    case 5:
	msg += make_ext_term_list(msg, 0);
	break;

    case 6:
	msg[0] = ERL_DRV_INT;
	msg[1] = ~((ErlDrvTermData) 0);
	msg[2] = ERL_DRV_UINT;
	msg[3] = ~((ErlDrvTermData) 0);
	msg[4] = ERL_DRV_TUPLE;
	msg[5] = (ErlDrvTermData) 2;
	msg += 6;
	break;

    case 7: {
	int len = 0;
	memset(buf7, 17, sizeof(buf7));
	/* empty heap binary */
	msg[len++] = ERL_DRV_BUF2BINARY;
	msg[len++] = (ErlDrvTermData) NULL; /* NULL is ok if size == 0 */
	msg[len++] = (ErlDrvTermData) 0;
	/* empty heap binary again */
	msg[len++] = ERL_DRV_BUF2BINARY;
	msg[len++] = (ErlDrvTermData) buf7; /* ptr is ok if size == 0 */
	msg[len++] = (ErlDrvTermData) 0;
	/* heap binary */
	msg[len++] = ERL_DRV_BUF2BINARY;
	msg[len++] = (ErlDrvTermData) buf7;
	msg[len++] = (ErlDrvTermData) 17;
	/* off heap binary */
	msg[len++] = ERL_DRV_BUF2BINARY;
	msg[len++] = (ErlDrvTermData) buf7;
	msg[len++] = (ErlDrvTermData) sizeof(buf7);

	msg[len++] = ERL_DRV_TUPLE;
	msg[len++] = (ErlDrvTermData) 4;

	msg += len;
	break;
    }

    case 8:
	msg[0] = ERL_DRV_NIL;
	msg += 1;
	break;

    case 9:
	msg[0] = ERL_DRV_ATOM;
	msg[1] = (ErlDrvTermData) driver_mk_atom("");
	msg += 2;
	break;

    case 10:
	msg[0] = ERL_DRV_ATOM;
	msg[1] = (ErlDrvTermData) driver_mk_atom("an_atom");
	msg += 2;
	break;

    case 11:
	msg[0] = ERL_DRV_INT;
	msg[1] = (ErlDrvTermData) -4711;
	msg += 2;
	break;
	  
    case 12:  
	msg[0] = ERL_DRV_UINT;
	msg[1] = (ErlDrvTermData) 4711;
	msg += 2;
	  
	break;
    case 13:  
	msg[0] = ERL_DRV_PORT;
	msg[1] = driver_mk_port(erlang_port);
	msg += 2;
	break;

    case 14: {
	ErlDrvBinary *dbin = bins[bin_ix++] = driver_alloc_binary(0);
	msg[0] = ERL_DRV_BINARY;
	msg[1] = (ErlDrvTermData) dbin;
	msg[2] = (ErlDrvTermData) 0;
	msg[3] = (ErlDrvTermData) 0;
	msg += 4;
	break;
	}

    case 15: {
	static const char buf[] = "hejsan";
	ErlDrvBinary *dbin = bins[bin_ix++] = driver_alloc_binary(sizeof(buf)-1);
	if (dbin)
	    memcpy((void *) dbin->orig_bytes, (void *) buf, sizeof(buf)-1);
	msg[0] = ERL_DRV_BINARY;
	msg[1] = (ErlDrvTermData) dbin;
	msg[2] = (ErlDrvTermData) (dbin ? sizeof(buf)-1 : 0);
	msg[3] = (ErlDrvTermData) 0;
	msg += 4;
	break;
	}

    case 16:
	msg[0] = ERL_DRV_BUF2BINARY;
	msg[1] = (ErlDrvTermData) NULL;
	msg[2] = (ErlDrvTermData) 0;
	msg += 3;
	break;
	
    case 17: {
	static const char buf[] = "";
	msg[0] = ERL_DRV_BUF2BINARY;
	msg[1] = (ErlDrvTermData) buf;
	msg[2] = (ErlDrvTermData) sizeof(buf)-1;
	msg += 3;
	break;
	}

    case 18: {
	static const char buf[] = "hoppsan";
	msg[0] = ERL_DRV_BUF2BINARY;
	msg[1] = (ErlDrvTermData) buf;
	msg[2] = (ErlDrvTermData) sizeof(buf)-1;
	msg += 3;
	break;
    }

    case 19: 
	msg[0] = ERL_DRV_STRING;
	msg[1] = (ErlDrvTermData) buf;
	msg[2] = (ErlDrvTermData) 0;
	msg += 3;
	break;

    case 20: {
	static const char buf[] = "";
	msg[0] = ERL_DRV_STRING;
	msg[1] = (ErlDrvTermData) buf;
	msg[2] = (ErlDrvTermData) sizeof(buf)-1;
	msg += 3;
	break;
    }
	
    case 21: {
	static const char buf[] = "hippsan";
	msg[0] = ERL_DRV_STRING;
	msg[1] = (ErlDrvTermData) buf;
	msg[2] = (ErlDrvTermData) sizeof(buf)-1;
	msg += 3;
	break;
	}

    case 22:
	msg[0] = ERL_DRV_TUPLE;
	msg[1] = (ErlDrvTermData) 0;
	msg += 2;
	break;

    case 23:
	msg[0] = ERL_DRV_NIL;
	msg[1] = ERL_DRV_LIST;
	msg[2] = (ErlDrvTermData) 1;
	msg += 3;
	break;
	
    case 24:
	msg[0] = ERL_DRV_PID;
	msg[1] = driver_connected(erlang_port);
	msg += 2;
	break;
	
    case 25:
	msg[0] = ERL_DRV_NIL;
	msg[1] = ERL_DRV_STRING_CONS;
	msg[2] = (ErlDrvTermData) "";
	msg[3] = (ErlDrvTermData) 0;
	msg += 4;
	break;

    case 26: {
	static double my_float = 0.0;
	msg[0] = ERL_DRV_FLOAT;
	msg[1] = (ErlDrvTermData) &my_float; 
	msg += 2;
	break;
    }

    case 27: {
	static char buf[] = {131, 106}; /* [] */
	msg[0] = ERL_DRV_EXT2TERM;
	msg[1] = (ErlDrvTermData) buf;
	msg[2] = (ErlDrvTermData) sizeof(buf);
	msg += 3;
	break;
    }

    case 28: {
	ErlDrvUInt64* x = &u64[u64_ix++];
	*x = ~((ErlDrvUInt64) 0);
	msg[0] = ERL_DRV_UINT64;
	msg[1] = (ErlDrvTermData) x;
	msg += 2;
	break;
    }

    case 29: {
	ErlDrvUInt64* x = &u64[u64_ix++];
	*x = ((ErlDrvUInt64) 4711) << 32;
	msg[0] = ERL_DRV_UINT64;
	msg[1] = (ErlDrvTermData) x;
	msg += 2;
	break;
    }

    case 30: {
	ErlDrvUInt64* x = &u64[u64_ix++];
	*x = 4711;
	msg[0] = ERL_DRV_UINT64;
	msg[1] = (ErlDrvTermData) x;
	msg += 2;
	break;
    }

    case 31: {
	ErlDrvUInt64* x = &u64[u64_ix++];
	*x = 0;
	msg[0] = ERL_DRV_UINT64;
	msg[1] = (ErlDrvTermData) x;
	msg += 2;
	break;
    }

    case 32: {
	ErlDrvSInt64* x = &s64[s64_ix++];
	*x = ((((ErlDrvUInt64) 0x7fffffff) << 32) | ((ErlDrvUInt64) 0xffffffff));
	msg[0] = ERL_DRV_INT64;
	msg[1] = (ErlDrvTermData) x;
	msg += 2;
	break;
    }

    case 33: {
	ErlDrvSInt64* x = &s64[s64_ix++];
	*x = (ErlDrvSInt64) (((ErlDrvUInt64) 4711) << 32);
	msg[0] = ERL_DRV_INT64;
	msg[1] = (ErlDrvTermData) x;
	msg += 2;
	break;
    }

    case 34: {
	ErlDrvSInt64* x = &s64[s64_ix++];
	*x = 4711;
	msg[0] = ERL_DRV_INT64;
	msg[1] = (ErlDrvTermData) x;
	msg += 2;
	break;
    }

    case 35: {
	ErlDrvSInt64* x = &s64[s64_ix++];
	*x = 0;
	msg[0] = ERL_DRV_INT64;
	msg[1] = (ErlDrvTermData) x;
	msg += 2;
	break;
    }

    case 36: {
	ErlDrvSInt64* x = &s64[s64_ix++];
	*x = -1;
	msg[0] = ERL_DRV_INT64;
	msg[1] = (ErlDrvTermData) x;
	msg += 2;
	break;
    }

    case 37: {
	ErlDrvSInt64* x = &s64[s64_ix++];
	*x = -4711;
	msg[0] = ERL_DRV_INT64;
	msg[1] = (ErlDrvTermData) x;
	msg += 2;
	break;
    }

    case 38: {
	ErlDrvSInt64* x = &s64[s64_ix++];
	*x = ((ErlDrvSInt64) ((ErlDrvUInt64) 4711) << 32)*-1;
	msg[0] = ERL_DRV_INT64;
	msg[1] = (ErlDrvTermData) x;
	msg += 2;
	break;
    }

    case 39: {
	ErlDrvSInt64* x = &s64[s64_ix++];
	*x = ((ErlDrvSInt64) 1) << 63;
	msg[0] = ERL_DRV_INT64;
	msg[1] = (ErlDrvTermData) x;
	msg += 2;
	break;
    }

    case 40: {
	msg[0] = ERL_DRV_MAP;
	msg[1] = (ErlDrvTermData) 0;
	msg += 2;
	break;
    }

    case 41:    /* Most term types inside a map */
    case 42: {
	double f = 3.1416;

	if (buf[i] == 41) {
	    *msg++ = ERL_DRV_ATOM;
	    *msg++ = driver_mk_atom("blurf");
	}
	*msg++ = ERL_DRV_INT;
	*msg++ = (ErlDrvTermData)42;
	*msg++ = ERL_DRV_NIL;
	*msg++ = ERL_DRV_INT;
	*msg++ = (ErlDrvTermData)-42;
	*msg++ = ERL_DRV_TUPLE;
	*msg++ = (ErlDrvTermData)0;
	*msg++ = ERL_DRV_PORT;
	*msg++ = driver_mk_port(erlang_port);
	*msg++ = ERL_DRV_STRING_CONS;
	*msg++ = (ErlDrvTermData)"abc";
	*msg++ = (ErlDrvTermData)3;
	*msg++ = ERL_DRV_LIST;
	*msg++ = (ErlDrvTermData)3;
	*msg++ = ERL_DRV_STRING;
	*msg++ = (ErlDrvTermData)"kalle";
	*msg++ = (ErlDrvTermData)5;
	*msg++ = ERL_DRV_FLOAT;
	*msg++ = (ErlDrvTermData)&f;
	*msg++ = ERL_DRV_PID;
	*msg++ = driver_connected(erlang_port);
	*msg++ = ERL_DRV_MAP;
	*msg++ = (ErlDrvTermData)0;
	if (buf[i] == 42) {
	    *msg++ = ERL_DRV_ATOM;
	    *msg++ = driver_mk_atom("blurf");
	}
	*msg++ = ERL_DRV_MAP;
	*msg++ = (ErlDrvTermData)4;
	break;
    }

    case 127:			/* Error cases */
	{
	    long refc;
	    ErlDrvBinary* bin = bins[bin_ix++] = driver_alloc_binary(256);

	    FAIL_TERM(msg, 0);

	    msg[0] = ERL_DRV_LIST;
	    msg[1] = (ErlDrvTermData) 0;
	    FAIL_TERM(msg, 2);

	    /* Not an atom */
	    msg[0] = ERL_DRV_ATOM;
	    msg[1] = (ErlDrvTermData) driver_connected(erlang_port);
	    FAIL_TERM(msg, 2);
	    msg[0] = ERL_DRV_ATOM;
	    msg[1] = driver_term_nil;
	    FAIL_TERM(msg, 2);

	    /* Not a pid */
	    msg[0] = ERL_DRV_PID;
	    msg[1] = (ErlDrvTermData) driver_mk_atom("blurf");
	    FAIL_TERM(msg, 2);
	    msg[0] = ERL_DRV_PID;
	    msg[1] = driver_term_nil;
	    FAIL_TERM(msg, 2);

	    /* Not a port */
	    msg[0] = ERL_DRV_PORT;
	    msg[1] = (ErlDrvTermData) driver_mk_atom("blurf");
	    FAIL_TERM(msg, 2);
	    msg[0] = ERL_DRV_PORT;
	    msg[1] = driver_term_nil;
	    FAIL_TERM(msg, 2);

	    /* Missing parameter on stack */
	    msg[0] = ERL_DRV_STRING_CONS;
	    msg[1] = (ErlDrvTermData) "abc";
	    msg[2] = (ErlDrvTermData) 3;
	    FAIL_TERM(msg, 3);

	    /*
	     * The first binary reference is correct, the second is incorrect.
	     * There should not be any "binary leak".
	     */
	    msg[0] = ERL_DRV_BINARY;
	    msg[1] = (ErlDrvTermData) bin;
	    msg[2] = (ErlDrvTermData) 256;
	    msg[3] = (ErlDrvTermData) 0;
	    msg[4] = ERL_DRV_BINARY;
	    msg[5] = (ErlDrvTermData) bin;
	    msg[6] = (ErlDrvTermData) 257;
	    msg[7] = (ErlDrvTermData) 0;
	    msg[8] = ERL_DRV_TUPLE;
	    msg[9] = (ErlDrvTermData) 2;
	    FAIL_TERM(msg, 10);

	    msg[0] = ERL_DRV_BINARY;
	    msg[1] = (ErlDrvTermData) bin;
	    msg[2] = (ErlDrvTermData) 256;
	    msg[3] = (ErlDrvTermData) 0;
	    msg[4] = ERL_DRV_BINARY;
	    msg[5] = (ErlDrvTermData) bin;
	    msg[6] = (ErlDrvTermData) 256;
	    msg[7] = (ErlDrvTermData) 50;
	    msg[8] = ERL_DRV_TUPLE;
	    msg[9] = (ErlDrvTermData) 2;
	    FAIL_TERM(msg, 10);
	    
	    /*
	     * We have succefully built two binaries. We expect the ref count
	     * to be 1 (SMP) or 3 (non-SMP).
	     */
	    refc = driver_binary_get_refc(bin);
	    if (refc > 3) {
		char sbuf[128];
		sprintf(sbuf, "bad_refc:%ld", refc);
		driver_failure_atom(erlang_port, sbuf);
	    }
	    driver_free_binary(bin);


	    FAIL_TERM(msg, make_ext_term_list(msg, 1));


	    /*
	     * Check that we fail for missing args.
	     *
	     * We setup valid terms but pass a too small size. We
	     * want valid terms since we want to verify that the
	     * failure really is due to the small size. 
	     */
	    msg[0] = ERL_DRV_ATOM;
	    msg[1] = (ErlDrvTermData) driver_mk_atom("an_atom");
	    FAIL_TERM(msg, 1);

	    msg[0] = ERL_DRV_INT;
	    msg[1] = (ErlDrvTermData) -4711;
	    FAIL_TERM(msg, 1);
	    
	    msg[0] = ERL_DRV_UINT;
	    msg[1] = (ErlDrvTermData) 4711;
	    FAIL_TERM(msg, 1);
	    
	    msg[0] = ERL_DRV_PORT;
	    msg[1] = driver_mk_port(erlang_port);
	    FAIL_TERM(msg, 1);
	    
	    {
		char buf[] = "hejsan";
		ErlDrvBinary *dbin = driver_alloc_binary(sizeof(buf)-1);
		if (!dbin)
		    driver_failure_posix(erlang_port, ENOMEM);
		else {
		    memcpy((void *) dbin->orig_bytes, (void *) buf, sizeof(buf)-1);
		    msg[0] = ERL_DRV_BINARY;
		    msg[1] = (ErlDrvTermData) dbin;
		    msg[2] = (ErlDrvTermData) sizeof(buf)-1;
		    msg[3] = (ErlDrvTermData) 0;
		    FAIL_TERM(msg, 1);
		    FAIL_TERM(msg, 2);
		    FAIL_TERM(msg, 3);
		    driver_free_binary(dbin);
		}
	    }

	    {
		char buf[] = "hoppsan";
		msg[0] = ERL_DRV_BUF2BINARY;
		msg[1] = (ErlDrvTermData) buf;
		msg[2] = (ErlDrvTermData) sizeof(buf)-1;
		FAIL_TERM(msg, 1);
		FAIL_TERM(msg, 2);
	    }

	    {
		char buf[] = "hippsan";
		msg[0] = ERL_DRV_STRING;
		msg[1] = (ErlDrvTermData) buf;
		msg[2] = (ErlDrvTermData) sizeof(buf)-1;
		FAIL_TERM(msg, 1);
		FAIL_TERM(msg, 2);
	    }
	    
	    msg[0] = ERL_DRV_TUPLE;
	    msg[1] = (ErlDrvTermData) 0;
	    FAIL_TERM(msg, 1);
	    
	    msg[0] = ERL_DRV_NIL;
	    msg[1] = ERL_DRV_LIST;
	    msg[2] = (ErlDrvTermData) 1;
	    FAIL_TERM(msg, 2);
	    
	    msg[0] = ERL_DRV_PID;
	    msg[1] = driver_connected(erlang_port);
	    FAIL_TERM(msg, 1);
	    
	    msg[0] = ERL_DRV_NIL;
	    msg[1] = ERL_DRV_STRING_CONS;
	    msg[2] = (ErlDrvTermData) "";
	    msg[3] = (ErlDrvTermData) 0;
	    FAIL_TERM(msg, 2);
	    FAIL_TERM(msg, 3);

	    {
		double my_float = 0.0;
		msg[0] = ERL_DRV_FLOAT;
		msg[1] = (ErlDrvTermData) &my_float; 
		FAIL_TERM(msg, 1);
	    }

	    {
		char buf[] = {131, 106}; /* [] */
		msg[0] = ERL_DRV_EXT2TERM;
		msg[1] = (ErlDrvTermData) buf;
		msg[2] = (ErlDrvTermData) sizeof(buf);
		FAIL_TERM(msg, 1);
		FAIL_TERM(msg, 2);
	    }

	    msg[0] = ERL_DRV_MAP;
	    msg[1] = (ErlDrvTermData) 0;
	    FAIL_TERM(msg, 1);

	    /* map with duplicate key */
	    msg[0] = ERL_DRV_ATOM;
	    msg[1] = driver_mk_atom("key");
	    msg[2] = ERL_DRV_NIL;
	    msg[3] = ERL_DRV_ATOM;
	    msg[4] = driver_mk_atom("key");
	    msg[5] = ERL_DRV_INT;
	    msg[6] = (ErlDrvTermData) -4711;
	    msg[7] = ERL_DRV_MAP;
	    msg[8] = 2;
	    FAIL_TERM(msg, 9);

	    /* Signal end of test case */
	    msg[0] = ERL_DRV_NIL;
	    erl_drv_output_term(driver_mk_port(erlang_port), msg, 1);
	    return;
	}
	break;

    default:
	driver_failure_atom(erlang_port, "bad_request");
	break;
    }
    if (count > 1) {
	*msg++ = ERL_DRV_NIL;
	*msg++ = ERL_DRV_LIST;
	*msg++ = count + 1;
    }
    output_term(spec, msg-spec);
    if ((bin_ix|s64_ix|u64_ix) > 15) abort();
    while (bin_ix) {
	driver_free_binary(bins[--bin_ix]);
    }
}
Example #26
0
static void
reply_ok(lua_drv_t *driver_data)
{
  ErlDrvTermData spec[] = {ERL_DRV_ATOM, ATOM_OK};
  erl_drv_output_term(driver_data->drvport, spec, sizeof(spec) / sizeof(spec[0]));
}
Example #27
0
static void echo_drv_output(ErlDrvData drv_data, char *buf, ErlDrvSizeT len) {
    EchoDrvData* data_p = (EchoDrvData *) drv_data;
    ErlDrvPort port = data_p->erlang_port;

    switch (buf[0]) {
    case ECHO_DRV_OUTPUT:
    {
        driver_output(port, buf+1, len-1);
        break;
    }
    case ECHO_DRV_OUTPUT2:
    {
         driver_output2(port, "a", 1, buf+1, len-1);
         break;
    }
    case ECHO_DRV_OUTPUT_BINARY:
    {
        ErlDrvBinary *bin = driver_alloc_binary(len-1);
        memcpy(&bin->orig_bytes, buf+1, len-1);
        driver_output_binary(port, "a", 1, bin, 1, len - 2);
        driver_free_binary(bin);
        break;
    }
    case ECHO_DRV_OUTPUTV:
    {
        ErlIOVec iov;
        ErlDrvSizeT sz;
        driver_enq(port, buf + 1, len - 1);
        sz = driver_peekqv(port, &iov);
        driver_outputv(port, "a", 1, &iov, 0);
        driver_deq(port, sz);
        break;
    }
    case ECHO_DRV_SET_TIMER:
    {
        driver_set_timer(port, 10);
        break;
    }
    case ECHO_DRV_FAILURE_EOF:
    {
        driver_failure_eof(port);
        break;
    }
    case ECHO_DRV_FAILURE_ATOM:
    {
        driver_failure_atom(port, buf+1);
        break;
    }
    case ECHO_DRV_FAILURE_POSIX:
    {
        driver_failure_posix(port, EAGAIN);
        break;
    }
    case ECHO_DRV_FAILURE:
    {
        driver_failure(port, buf[1]);
        break;
    }
    case ECHO_DRV_OUTPUT_TERM:
    case ECHO_DRV_DRIVER_OUTPUT_TERM:
    case ECHO_DRV_SEND_TERM:
    case ECHO_DRV_DRIVER_SEND_TERM:
    {
        ErlDrvTermData term[] = {
            ERL_DRV_ATOM, driver_mk_atom("echo"),
            ERL_DRV_PORT, driver_mk_port(port),
            ERL_DRV_BUF2BINARY, (ErlDrvTermData)(buf+1),
                                (ErlDrvTermData)(len - 1),
            ERL_DRV_TUPLE, 3};
        switch (buf[0]) {
        case ECHO_DRV_OUTPUT_TERM:
            erl_drv_output_term(driver_mk_port(port), term, sizeof(term) / sizeof(ErlDrvTermData));
            break;
        case ECHO_DRV_DRIVER_OUTPUT_TERM:
            driver_output_term(port, term, sizeof(term) / sizeof(ErlDrvTermData));
            break;
        case ECHO_DRV_SEND_TERM:
            driver_send_term(port, data_p->caller,
                             term, sizeof(term) / sizeof(ErlDrvTermData));
            break;
        case ECHO_DRV_DRIVER_SEND_TERM:
            erl_drv_send_term(driver_mk_port(port), data_p->caller,
                              term, sizeof(term) / sizeof(ErlDrvTermData));
            break;
        }
        break;
    }
    case ECHO_DRV_SAVE_CALLER:
        data_p->caller = driver_caller(port);
        break;
    default:
        break;
    }
}