Permalink
Browse files

Add support for getsockopt(2)

  • Loading branch information...
1 parent 6cdc207 commit 277fb24c87b2869e504c4b5907cb9c1770592473 @msantos committed May 17, 2013
Showing with 62 additions and 0 deletions.
  1. +15 −0 README.md
  2. +43 −0 c_src/procket.c
  3. +4 −0 src/procket.erl
@@ -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()
View
@@ -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
@@ -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},
View
@@ -47,6 +47,7 @@
bind/2,
ioctl/3,
setsockopt/4,
+ getsockopt/4,
getsockname/2,
alloc/1,
@@ -157,6 +158,9 @@ writev(_,_) ->
setsockopt(_,_,_,_) ->
erlang:error(not_implemented).
+getsockopt(_,_,_,_) ->
+ erlang:error(not_implemented).
+
getsockname(_,_) ->
erlang:error(not_implemented).

0 comments on commit 277fb24

Please sign in to comment.