Skip to content

Commit

Permalink
Add writev() support
Browse files Browse the repository at this point in the history
Signed-off-by: Gregory Haskins <ghaskins@novell.com>
  • Loading branch information
Gregory Haskins committed May 31, 2011
1 parent 28c55bd commit eb432ee
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 1 deletion.
42 changes: 42 additions & 0 deletions c_src/procket.c
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,47 @@ nif_write(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
return atom_ok;
}

#define IOVMAX 256

/* 0: fd, 1: list of buffers */
static ERL_NIF_TERM
nif_writev(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
ERL_NIF_TERM head = {0};
ERL_NIF_TERM tail = {0};
struct iovec iovs[IOVMAX];
int fd = -1;
unsigned iovcnt;

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

tail = argv[1];

if (!enif_get_list_length(env, tail, &iovcnt))
return enif_make_badarg(env);

if (!iovcnt || iovcnt > IOVMAX)
return enif_make_badarg(env);

iovcnt = 0;

while (enif_get_list_cell(env, tail, &head, &tail)) {
struct iovec *iov = &iovs[iovcnt++];
ErlNifBinary buf = {0};

if (!enif_inspect_binary(env, head, &buf))
return enif_make_badarg(env);

iov->iov_base = buf.data;
iov->iov_len = buf.size;
}

if (writev(fd, iovs, iovcnt) == -1)
return error_tuple(env, errno);

return atom_ok;
}

/* 0: socket descriptor, 1: struct sockaddr */
static ERL_NIF_TERM
Expand Down Expand Up @@ -903,6 +944,7 @@ static ErlNifFunc nif_funcs[] = {

{"read", 2, nif_read},
{"write", 2, nif_write},
{"writev", 2, nif_writev},

{"alloc", 1, nif_alloc},
{"memcpy", 2, nif_memcpy},
Expand Down
4 changes: 3 additions & 1 deletion src/procket.erl
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
close/1,
recv/2,recvfrom/2,recvfrom/4,
sendto/2, sendto/3,sendto/4,
read/2, write/2,
read/2, write/2, writev/2,
bind/2,
ioctl/3,
setsockopt/4,
Expand Down Expand Up @@ -145,6 +145,8 @@ sendto(_,_,_,_) ->

write(_,_) ->
erlang:error(not_implemented).
writev(_,_) ->
erlang:error(not_implemented).

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

0 comments on commit eb432ee

Please sign in to comment.