Example #1
0
static ERL_NIF_TERM open_nif(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
    posix_errno_t posix_errno;
    efile_data_t *d;

    ErlNifPid controlling_process;
    enum efile_modes_t modes;
    ERL_NIF_TERM result;
    efile_path_t path;

    if(argc != 2 || !enif_is_list(env, argv[1])) {
        return enif_make_badarg(env);
    }

    modes = efile_translate_modelist(env, argv[1]);

    if((posix_errno = efile_marshal_path(env, argv[0], &path))) {
        return posix_error_to_tuple(env, posix_errno);
    } else if((posix_errno = efile_open(&path, modes, efile_resource_type, &d))) {
        return posix_error_to_tuple(env, posix_errno);
    }

    result = enif_make_resource(env, d);
    enif_release_resource(d);

    enif_self(env, &controlling_process);

    if(enif_monitor_process(env, d, &controlling_process, &d->monitor)) {
        return posix_error_to_tuple(env, EINVAL);
    }

    return enif_make_tuple2(env, am_ok, result);
}
Example #2
0
static ERL_NIF_TERM send_list_seq(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    ErlNifPid to;
    ERL_NIF_TERM msg;
    ErlNifEnv* msg_env;
    int i, res;
    
    if (!enif_get_int(env, argv[0], &i)) {
	return enif_make_badarg(env);
    }
    if (argv[1] == atom_self) {
	enif_self(env, &to);
    }
    else if (!enif_get_local_pid(env, argv[1], &to)) {
	return enif_make_badarg(env);
    }
    msg_env = enif_alloc_env();
    msg = enif_make_list(msg_env,0);
    for ( ; i>0 ; i--) {
	msg = enif_make_list_cell(msg_env, enif_make_int(msg_env, i), msg);
    }
    res = enif_send(env, &to, msg_env, msg);
    enif_free_env(msg_env);
    return enif_make_tuple2(env, atom_ok, enif_make_int(env,res));
}
static ERL_NIF_TERM
send_to_self(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    state_t* state = (state_t*) enif_priv_data(env);
    ErlNifPid* pid = (ErlNifPid*) enif_alloc(sizeof(ErlNifPid));

    enif_self(env, pid);

    queue_push(state->queue, pid);

    return state->atom_ok;
}
Example #4
0
static ERL_NIF_TERM open_nif(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
    posix_errno_t posix_errno;
    efile_data_t *d;

    ErlNifPid controlling_process;
    enum efile_modes_t modes;
    ERL_NIF_TERM result;
    efile_path_t path;

    ASSERT(argc == 2);
    if(!enif_is_list(env, argv[1])) {
        return enif_make_badarg(env);
    }

    modes = efile_translate_modelist(env, argv[1]);

    if((posix_errno = efile_marshal_path(env, argv[0], &path))) {
        return posix_error_to_tuple(env, posix_errno);
    } else if((posix_errno = efile_open(&path, modes, efile_resource_type, &d))) {
        return posix_error_to_tuple(env, posix_errno);
    }

    enif_self(env, &controlling_process);

    if(enif_monitor_process(env, d, &controlling_process, &d->monitor)) {
        /* We need to close the file manually as we haven't registered a
         * destructor. */
        posix_errno_t ignored;

        erts_atomic32_set_acqb(&d->state, EFILE_STATE_CLOSED);
        efile_close(d, &ignored);

        return posix_error_to_tuple(env, EINVAL);
    }

    /* Note that we do not call enif_release_resource at this point. While it's
     * normally safe to leave resource management to the GC, efile_close is a
     * blocking operation which must not be done in the GC callback, and we
     * can't defer it as the resource is gone as soon as it returns.
     *
     * We instead keep the resource alive until efile_close is called, after
     * which it's safe to leave things to the GC. If the controlling process
     * were to die before the user had a chance to close their file, the above
     * monitor will tell the erts_prim_file process to close it for them. */
    result = enif_make_resource(env, d);

    return enif_make_tuple2(env, am_ok, result);
}
Example #5
0
ERL_NIF_TERM nif_thread_call(ErlNifEnv* env, ERL_NIF_TERM (*f)(ErlNifEnv*, nif_thread_arg*), int a, ...)
{
	va_list ap;
	int i;

	nif_thread_arg* args = (nif_thread_arg*)enif_alloc(a * sizeof(nif_thread_arg));

	va_start(ap, a);
	for (i = 0; i < a; i++)
		args[i] = va_arg(ap, void*);
	va_end(ap);

	ErlNifPid* pid = (ErlNifPid*)enif_alloc(sizeof(ErlNifPid));
	nif_thread_message* msg = nif_thread_message_alloc((void*)f, args, enif_self(env, pid));

	return nif_thread_send((nif_thread_state*)enif_priv_data(env), msg);
}
Example #6
0
static ERL_NIF_TERM
send(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    ErlNifEnv* cp_env = enif_alloc_env();
    ErlNifPid dst;
    ERL_NIF_TERM msg;
    ERL_NIF_TERM ret;
    
    if(argc == 1) {
        if(!enif_self(env, &dst)) {
            ret = enif_make_badarg(env);
            goto done;
        }
        msg = argv[0];
    } else if(argc == 2) {
        if(!enif_get_local_pid(env, argv[0], &dst)) {
            ret = enif_make_badarg(env);
            goto done;
        }
        msg = argv[1];
    } else {
        ret = enif_make_badarg(env);
        goto done;
    }

    msg = enif_make_copy(cp_env, msg);

    if(!enif_send(env, &dst, cp_env, msg)) {
        ret = enif_make_badarg(env);
        goto done;
    }
    
    ret = enif_make_atom(env, "ok");

done:
    enif_free_env(cp_env);
    return ret;
}
Example #7
0
static ERL_NIF_TERM dirty_call_while_terminated_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    ErlNifPid self;
    ERL_NIF_TERM result, self_term;
    ErlNifPid to;
    ErlNifEnv* menv;
    int res;

    if (!enif_get_local_pid(env, argv[0], &to))
	return enif_make_badarg(env);

    if (!enif_self(env, &self))
	return enif_make_badarg(env);

    self_term = enif_make_pid(env, &self);

    menv = enif_alloc_env();
    result = enif_make_tuple2(menv, enif_make_atom(menv, "dirty_alive"), self_term);
    res = enif_send(env, &to, menv, result);
    enif_free_env(menv);
    if (!res)
	return enif_make_badarg(env);

    /* Wait until we have been killed */
    while (enif_is_process_alive(env, &self))
	;

    result = enif_make_tuple2(env, enif_make_atom(env, "dirty_dead"), self_term);
    res = enif_send(env, &to, NULL, result);

#ifdef __WIN32__
    Sleep(1000);
#else
    sleep(1);
#endif

    return enif_make_atom(env, "ok");
}
Example #8
0
static ERL_NIF_TERM trace(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    int state_arity;
    ErlNifPid self, to;
    ERL_NIF_TERM *tuple, msg;
    ASSERT(argc == 5);

    tuple = enif_alloc(sizeof(ERL_NIF_TERM)*(argc+1));
    memcpy(tuple+1,argv,sizeof(ERL_NIF_TERM)*argc);

    if (enif_self(env, &self)) {
        tuple[0] = enif_make_pid(env, &self);
    } else {
        tuple[0] = enif_make_atom(env, "undefined");
    }

    msg = enif_make_tuple_from_array(env, tuple, argc + 1);
    enif_get_local_pid(env, argv[1], &to);
    enif_send(env, &to, NULL, msg);
    enif_free(tuple);

    return atom_ok;
}
Example #9
0
File: alsa.c Project: DEGAUSSE/alsa
static ERL_NIF_TERM
alsa_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
  int sample_rate, channels;
  int selected_device = -1;
  
  enif_get_int(env, argv[0], &sample_rate);
  enif_get_int(env, argv[1], &channels);
  if(argc > 2) {
    enif_get_int(env, argv[2], &selected_device);
  }

  // selectedDevice = dump_audio_info(selectedDevice);

  AudioCapture *capture = (AudioCapture *)enif_alloc_resource(alsa_resource, sizeof(AudioCapture));
  bzero(capture, sizeof(AudioCapture));

  capture->sample_rate = sample_rate;
  capture->channels = channels;
  capture->frame_size = capture->channels*2*1024;
  capture->selected_device = selected_device;

  
  enif_self(env, &capture->owner_pid);
  capture->env = enif_alloc_env();
  
  fprintf(stderr, "Starting alsa %d\r\n", capture->sample_rate);
  
  capture->thread_started = 1;
  enif_thread_create("alsa_thread", &capture->tid, capture_thread, capture, NULL);
  
  ERL_NIF_TERM port = enif_make_resource(env, capture);
  capture->port = enif_make_copy(capture->env, port);

  enif_release_resource(capture);
  return port;
}
Example #10
0
static ERL_NIF_TERM
nif_pcap_open_live(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
    ErlNifBinary device = {0};
    int snaplen = 0;
    int promisc = 0;
    int to_ms = 0;
    char errbuf[PCAP_ERRBUF_SIZE] = {0};

    EWPCAP_STATE *ep = NULL;
    ERL_NIF_TERM res = {0};
    ERL_NIF_TERM ref = {0};


    if (!enif_inspect_iolist_as_binary(env, argv[0], &device))
        return enif_make_badarg(env);

    if (!enif_get_int(env, argv[1], &snaplen))
        return enif_make_badarg(env);

    if (!enif_get_int(env, argv[2], &promisc))
        return enif_make_badarg(env);

    if (!enif_get_int(env, argv[3], &to_ms))
        return enif_make_badarg(env);

    /* NULL terminate the device name */
    if (device.size > 0 && !enif_realloc_binary(&device, device.size+1))
        return enif_make_tuple2(env, atom_error, atom_enomem);

    device.data[device.size-1] = '\0';

    ep = enif_alloc_resource(EWPCAP_RESOURCE, sizeof(EWPCAP_STATE));

    if (ep == NULL)
        return enif_make_tuple2(env, atom_error, atom_enomem);


    /* "any" is a Linux only virtual dev */
    ep->p = pcap_open_live((device.size == 0 ? "any" : (char *)device.data),
                           snaplen, promisc, to_ms, errbuf);

    if (ep->p == NULL)
        return enif_make_tuple2(env,
                                atom_error,
                                enif_make_string(env, errbuf, ERL_NIF_LATIN1));

    ep->datalink = pcap_datalink(ep->p);
    (void)enif_self(env, &ep->pid);

    ep->term_env = enif_alloc_env();
    if (ep->term_env == NULL) {
        pcap_close(ep->p);
        return enif_make_tuple2(env, atom_error, atom_enomem);
    }

    ep->ref = enif_make_ref(ep->term_env);
    ref = enif_make_copy(env, ep->ref);

    res = enif_make_resource(env, ep);
    enif_release_resource(ep);

    return enif_make_tuple2(env,
                            atom_ok,
                            enif_make_tuple3(env,
                                    atom_ewpcap_resource,
                                    ref,
                                    res));
}
Example #11
0
    static ERL_NIF_TERM
nif_pcap_open_live(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
    ErlNifBinary device = {0};
    int snaplen = 0;
    int promisc = 0;
    int to_ms = 0;
    int buffer_size = 0;
    int rfmon = 0;
    char errbuf[PCAP_ERRBUF_SIZE] = {0};

    EWPCAP_STATE *ep = NULL;
    ERL_NIF_TERM res = {0};
    ERL_NIF_TERM ref = {0};


    if (!enif_inspect_iolist_as_binary(env, argv[0], &device))
        return enif_make_badarg(env);

    if (!enif_get_int(env, argv[1], &snaplen))
        return enif_make_badarg(env);

    if (!enif_get_int(env, argv[2], &promisc))
        return enif_make_badarg(env);

    if (!enif_get_int(env, argv[3], &to_ms))
        return enif_make_badarg(env);

    if (!enif_get_int(env, argv[4], &buffer_size))
        return enif_make_badarg(env);

    if (!enif_get_int(env, argv[5], &rfmon))
        return enif_make_badarg(env);

    /* NULL terminate the device name */
    if (device.size > 0) {
        if (!enif_realloc_binary(&device, device.size+1))
            return enif_make_tuple2(env, atom_error, atom_enomem);

        device.data[device.size-1] = '\0';
    }

    ep = enif_alloc_resource(EWPCAP_RESOURCE, sizeof(EWPCAP_STATE));

    if (ep == NULL)
        return enif_make_tuple2(env, atom_error, atom_enomem);

    /* "any" is a Linux only virtual dev */
    ep->p = pcap_create((device.size == 0 ? "any" : (char *)device.data),
            errbuf);

    if (ep->p == NULL)
        return enif_make_tuple2(env,
                atom_error,
                enif_make_string(env, errbuf, ERL_NIF_LATIN1));

    /* Set the snaplen */
    (void)pcap_set_snaplen(ep->p, snaplen);

    /* Set promiscuous mode */
    (void)pcap_set_promisc(ep->p, promisc);

    /* Set timeout */
    (void)pcap_set_timeout(ep->p, to_ms);

    /* Set buffer size */
    if (buffer_size > 0)
        (void)pcap_set_buffer_size(ep->p, buffer_size);

    /* Set monitor mode */
    if (pcap_can_set_rfmon(ep->p) == 1)
        (void)pcap_set_rfmon(ep->p, rfmon);

    /* Return failure on error and warnings */
    if (pcap_activate(ep->p) != 0) {
        pcap_close(ep->p);
        return enif_make_tuple2(env,
                atom_error,
                enif_make_string(env, pcap_geterr(ep->p), ERL_NIF_LATIN1));
    }

    ep->datalink = pcap_datalink(ep->p);
    (void)enif_self(env, &ep->pid);

    ep->term_env = enif_alloc_env();
    if (ep->term_env == NULL) {
        pcap_close(ep->p);
        return enif_make_tuple2(env, atom_error, atom_enomem);
    }

    ep->ref = enif_make_ref(ep->term_env);
    ref = enif_make_copy(env, ep->ref);

    res = enif_make_resource(env, ep);
    enif_release_resource(ep);

    return enif_make_tuple2(env,
            atom_ok,
            enif_make_tuple3(env,
                atom_ewpcap_resource,
                ref,
                res));
}
Example #12
0
static ERL_NIF_TERM make_term_caller_pid(struct make_term_info* mti, int n)
{
    ErlNifPid pid;    
    return enif_make_pid(mti->dst_env, enif_self(mti->caller_env, &pid));    		
}