Skip to content

Commit

Permalink
Changes for the R13B04 nif interface.
Browse files Browse the repository at this point in the history
Also an excuse to do some clean up.
  • Loading branch information
msantos committed Mar 8, 2010
1 parent 795e6c7 commit ea8f4ff
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 84 deletions.
93 changes: 16 additions & 77 deletions c_src/procket.c
Expand Up @@ -36,43 +36,21 @@
#define BACKLOG 5

static ERL_NIF_TERM error_tuple(ErlNifEnv *env, char *atom, char *err);
static int my_enif_get_string(ErlNifEnv *env, ERL_NIF_TERM list, char *buf, size_t buflen);
static ERL_NIF_TERM error_message(ErlNifEnv *env, char *atom, char *err, char *msg);


static int
load(ErlNifEnv *env, void **priv, ERL_NIF_TERM load_info)
{
return (0);
}


static int
reload(ErlNifEnv *env, void **priv, ERL_NIF_TERM load_info)
{
return load(env, priv, load_info);
}


static ERL_NIF_TERM
sock_open(ErlNifEnv *env, ERL_NIF_TERM path)
sock_open(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
char sock_path[UNIX_PATH_MAX];
int sock_fd = -1;

struct sockaddr_un sa = { 0 };
int flags = 0;


(void)memset(&sock_path, '\0', sizeof(sock_path));
if (!my_enif_get_string(env, path, sock_path, sizeof(sock_path)))
return enif_make_badarg(env);

if (strlen(sock_path) == 0)
if (enif_get_string(env, argv[0], sa.sun_path, sizeof(sa.sun_path), ERL_NIF_LATIN1) < 1)
return enif_make_badarg(env);

sa.sun_family = PF_LOCAL;
(void)memcpy(sa.sun_path, sock_path, sizeof(sa.sun_path)-1);

errno = 0;
sock_fd = socket(PF_LOCAL, SOCK_STREAM, 0);
Expand All @@ -98,7 +76,7 @@ sock_open(ErlNifEnv *env, ERL_NIF_TERM path)


static ERL_NIF_TERM
poll(ErlNifEnv *env, ERL_NIF_TERM socket)
poll(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
int sock_fd = -1; /* listening socket */
int fd = -1; /* connected socket */
Expand All @@ -107,7 +85,7 @@ poll(ErlNifEnv *env, ERL_NIF_TERM socket)
socklen_t socklen = 0;


if (!enif_get_int(env, socket, &sock_fd))
if (!enif_get_int(env, argv[0], &sock_fd))
return enif_make_badarg(env);

errno = 0;
Expand All @@ -129,25 +107,25 @@ poll(ErlNifEnv *env, ERL_NIF_TERM socket)
}


/* 0: path to socket
* 1: file descriptor
*/
static ERL_NIF_TERM
sock_close(ErlNifEnv *env, ERL_NIF_TERM path, ERL_NIF_TERM fd)
sock_close(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
char sock_path[UNIX_PATH_MAX];
struct sockaddr_un sa = { 0 };
int sockfd = -1;


(void)memset(&sock_path, '\0', sizeof(sock_path));
if (!my_enif_get_string(env, path, sock_path, sizeof(sock_path)))
if (enif_get_string(env, argv[0], sa.sun_path, sizeof(sa.sun_path), ERL_NIF_LATIN1) < 1)
return enif_make_badarg(env);

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

if (strlen(sock_path) != 0) {
errno = 0;
if (unlink(sock_path) < 0)
return error_message(env, "error", "unlink", strerror(errno));
}
errno = 0;
if (unlink(sa.sun_path) < 0)
return error_message(env, "error", "unlink", strerror(errno));

(void)close(sockfd);

Expand All @@ -171,55 +149,16 @@ error_message(ErlNifEnv *env, char *atom, char *err, char *msg)
enif_make_atom(env, atom),
enif_make_tuple(env, 2,
enif_make_atom(env, err),
enif_make_string(env, msg)));
enif_make_string(env, msg, ERL_NIF_LATIN1)));
}


/* from:
* http://d.hatena.ne.jp/vostok92/20091201/1259680319
*
* Copies at most one less than buflen from buf and null
* terminates the string.
*
* Should probably indicate that a truncation has taken place, but
* the convention of the enif_get_* interfaces seems to be to return
* true/false.
*
* The alternative is to return failure if a string is too large
* for the buffer. This seems to allow for more predictable
* behaviour.
*
*/
static int
my_enif_get_string(ErlNifEnv *env, ERL_NIF_TERM list, char *buf, size_t buflen)
{
ERL_NIF_TERM head, tail;
int val;
int n = 1;


while (enif_get_list_cell(env, list, &head, &tail)) {
if (!enif_get_int(env, head, &val))
return (0);

if (n++ >= buflen)
return (0);

*buf = (char)val;
buf++;
list = tail;
}
*buf = '\0';

return (1);
}

static ErlNifFunc nif_funcs[] = {
{"open", 1, sock_open},
{"poll", 1, poll},
{"close", 2, sock_close}
};

ERL_NIF_INIT(procket, nif_funcs, load, reload, NULL, NULL)
ERL_NIF_INIT(procket, nif_funcs, NULL, NULL, NULL, NULL)


5 changes: 0 additions & 5 deletions c_src/procket.h
Expand Up @@ -49,11 +49,6 @@


#define PROCKET_VERSION "0.01"

#ifndef UNIX_PATH_MAX
#define UNIX_PATH_MAX sizeof(((struct sockaddr_un *)0)->sun_path)
#endif

#define MAXBUFLEN 4096 /* Largest message accepted on stdin */

#define IS_ERR(x) do { \
Expand Down
3 changes: 1 addition & 2 deletions src/procket.erl
Expand Up @@ -41,8 +41,7 @@ init() ->
on_load().

on_load() ->
ok = erlang:load_nif("priv/procket", []),
true.
ok = erlang:load_nif("priv/procket", []).

open(_) ->
erlang:error(not_implemented).
Expand Down

0 comments on commit ea8f4ff

Please sign in to comment.