Skip to content

Commit

Permalink
Add support for getsockopt(2)
Browse files Browse the repository at this point in the history
  • Loading branch information
msantos committed May 17, 2013
1 parent 6cdc207 commit 277fb24
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 0 deletions.
15 changes: 15 additions & 0 deletions README.md
Expand Up @@ -196,6 +196,21 @@ procket works with any version of Erlang after R14A.

See setsockopt(2).

getsockopt(Socket, Level, Optname, Optval) -> {ok, Buf} | {error, posix}

Types Socket = integer()
Level = integer()
Optname = integer()
Optval = binary()
Buf = binary()

See getsockopt(2). Similar to inet:getopts/2 but can be used
with file descriptors.

Retrieve a socket option for a file descriptor. Use an empty
binary to indicate no option value is supplied or will be
returned.

ioctl(FD, Request, Arg) -> {ok, Result} | {error, posix()}

Types FD = integer()
Expand Down
43 changes: 43 additions & 0 deletions c_src/procket.c
Expand Up @@ -535,6 +535,48 @@ nif_setsockopt(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
return atom_ok;
}

/* 0: int socket descriptor, 1: int level,
* 2: int optname, 3: void *optval
*/
static ERL_NIF_TERM
nif_getsockopt(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
int s = -1;
int level = 0;
int optname = 0;
ErlNifBinary optval = {0};
socklen_t optlen = 0;


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

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

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

if (!enif_inspect_binary(env, argv[3], &optval))
return enif_make_badarg(env);

/* Make the binary mutable */
if (!enif_realloc_binary(&optval, optval.size))
return error_tuple(env, ENOMEM);

optlen = optval.size;

if (getsockopt(s, level, optname,
(optval.size == 0 ? NULL : optval.data), &optlen) < 0)
return error_tuple(env, errno);

PROCKET_REALLOC(optval, optlen);

return enif_make_tuple2(env,
atom_ok,
enif_make_binary(env, &optval));
}


// int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
static ERL_NIF_TERM
Expand Down Expand Up @@ -745,6 +787,7 @@ static ErlNifFunc nif_funcs[] = {
{"connect", 2, nif_connect},
{"listen", 2, nif_listen},
{"getsockname", 2, nif_getsockname},
{"getsockopt", 4, nif_getsockopt},
{"ioctl", 3, nif_ioctl},
{"socket_nif", 3, nif_socket},
{"recvfrom", 4, nif_recvfrom},
Expand Down
4 changes: 4 additions & 0 deletions src/procket.erl
Expand Up @@ -47,6 +47,7 @@
bind/2,
ioctl/3,
setsockopt/4,
getsockopt/4,
getsockname/2,

alloc/1,
Expand Down Expand Up @@ -157,6 +158,9 @@ writev(_,_) ->
setsockopt(_,_,_,_) ->
erlang:error(not_implemented).

getsockopt(_,_,_,_) ->
erlang:error(not_implemented).

getsockname(_,_) ->
erlang:error(not_implemented).

Expand Down

0 comments on commit 277fb24

Please sign in to comment.