diff options
author | Micael Karlberg <[email protected]> | 2018-08-01 19:42:32 +0200 |
---|---|---|
committer | Micael Karlberg <[email protected]> | 2018-09-18 14:50:18 +0200 |
commit | 90a150771faa3cf01e82919b0c17854de9987783 (patch) | |
tree | 5ad6c69f9ec4e569bba3da11df10d379faaba537 /erts/emulator/nifs/common/socket_util.c | |
parent | 25c38eff5c1e8d4dc6325afa62031874e23262dc (diff) | |
download | otp-90a150771faa3cf01e82919b0c17854de9987783.tar.gz otp-90a150771faa3cf01e82919b0c17854de9987783.tar.bz2 otp-90a150771faa3cf01e82919b0c17854de9987783.zip |
[socket-nif] Processing of more cmsg headers
Added processing or more cmsg headers (for more options).
Now (also) supports: socket:timestamp.
Also various fixes and cleanups.
For some reason calling getopt(Sock, 0, {13, int}) (or similar)
fails with badarg even though the nif-function (nif_getopt) actually
returns a valid value (for instance: {ok, 0}).
OTP-14831
Diffstat (limited to 'erts/emulator/nifs/common/socket_util.c')
-rw-r--r-- | erts/emulator/nifs/common/socket_util.c | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/erts/emulator/nifs/common/socket_util.c b/erts/emulator/nifs/common/socket_util.c index 232e8200df..59cd1a3408 100644 --- a/erts/emulator/nifs/common/socket_util.c +++ b/erts/emulator/nifs/common/socket_util.c @@ -227,6 +227,11 @@ char* esock_encode_sockaddr(ErlNifEnv* env, { char* xres; + UDBG( ("SUTIL", "esock_encode_sockaddr -> entry with" + "\r\n family: %d" + "\r\n addrLen: %d" + "\r\n", sockAddrP->sa.sa_family, addrLen) ); + switch (sockAddrP->sa.sa_family) { case AF_INET: xres = esock_encode_sockaddr_in4(env, &sockAddrP->in4, addrLen, eSockAddr); @@ -860,6 +865,74 @@ char* esock_encode_ip6_address(ErlNifEnv* env, +/* +++ esock_encode_timeval +++ + * + * Encode a timeval struct into its erlang form, a map with two fields: + * + * sec + * usec + * + */ +extern +char* esock_encode_timeval(ErlNifEnv* env, + struct timeval* timeP, + ERL_NIF_TERM* eTime) +{ + ERL_NIF_TERM keys[] = {esock_atom_sec, esock_atom_usec}; + ERL_NIF_TERM vals[] = {MKL(env, timeP->tv_sec), MKL(env, timeP->tv_usec)}; + + unsigned int numKeys = sizeof(keys) / sizeof(ERL_NIF_TERM); + unsigned int numVals = sizeof(vals) / sizeof(ERL_NIF_TERM); + + ESOCK_ASSERT( (numKeys == numVals) ); + + if (!MKMA(env, keys, vals, numKeys, eTime)) + return ESOCK_STR_EINVAL; + + return NULL; +} + + + +/* +++ esock_decode_timeval +++ + * + * Decode a timeval in its erlang form (a map) into its native form, + * a timeval struct. + * + */ +extern +char* esock_decode_timeval(ErlNifEnv* env, + ERL_NIF_TERM eTime, + struct timeval* timeP) +{ + ERL_NIF_TERM eSec, eUSec; + size_t sz; + + // It must be a map + if (!IS_MAP(env, eTime)) + return ESOCK_STR_EINVAL; + + // It must have atleast two attributes + if (!enif_get_map_size(env, eTime, &sz) || (sz < 2)) + return ESOCK_STR_EINVAL; + + if (!GET_MAP_VAL(env, eTime, esock_atom_sec, &eSec)) + return ESOCK_STR_EINVAL; + + if (!GET_MAP_VAL(env, eTime, esock_atom_usec, &eUSec)) + return ESOCK_STR_EINVAL; + + if (!GET_LONG(env, eSec, &timeP->tv_sec)) + return ESOCK_STR_EINVAL; + + if (!GET_LONG(env, eUSec, &timeP->tv_usec)) + return ESOCK_STR_EINVAL; + + return NULL; +} + + + /* +++ esock_decode_domain +++ * * Decode the Erlang form of the 'domain' type, that is: |