Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:25
erlang
4782-enet-Add-net-getservbyname.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 4782-enet-Add-net-getservbyname.patch of Package erlang
From 7f86a1e5c57ac47a368b092d766465fc44f07a96 Mon Sep 17 00:00:00 2001 From: Micael Karlberg <bmk@erlang.org> Date: Mon, 15 Apr 2024 16:55:18 +0200 Subject: [PATCH 02/18] [enet] Add net:getservbyname --- erts/emulator/nifs/common/prim_net_nif.c | 111 ++++++++++++++++++++++- lib/kernel/src/net.erl | 47 +++++++++- 2 files changed, 150 insertions(+), 8 deletions(-) diff --git a/erts/emulator/nifs/common/prim_net_nif.c b/erts/emulator/nifs/common/prim_net_nif.c index 8655c561e3..ed088aaed6 100644 --- a/erts/emulator/nifs/common/prim_net_nif.c +++ b/erts/emulator/nifs/common/prim_net_nif.c @@ -203,9 +203,23 @@ ERL_NIF_INIT(prim_net, net_funcs, on_load, NULL, NULL, NULL) #ifdef __WIN32__ -#define net_gethostname(__buf__, __bufSz__) gethostname((__buf__), (__bufSz__)) + +#define net_gethostname(__buf__, __bufSz__) \ + gethostname((__buf__), (__bufSz__)) +#define net_getservbyname(__name__, __proto__) \ + getservbyname((__name__), (__proto__)) +#define net_ntohs(x) \ + ntohs((x)) + #else -#define net_gethostname(__buf__, __bufSz__) gethostname((__buf__), (__bufSz__)) + +#define net_gethostname(__buf__, __bufSz__) \ + gethostname((__buf__), (__bufSz__)) +#define net_getservbyname(__name__, __proto__) \ + getservbyname((__name__), (__proto__)) +#define net_ntohs(x) \ + ntohs((x)) + #endif // __WIN32__ @@ -266,7 +280,7 @@ static NetData data; * ---------------------------------------------------------------------- */ -/* THIS IS JUST TEMPORARY */ +/* THIS IS JUST TEMPORARY...maybe */ extern char* erl_errno_id(int error); /* All the nif "callback" functions for the net API has @@ -292,6 +306,7 @@ extern char* erl_errno_id(int error); ENET_NIF_FUNC_DEF(get_if_entry); \ ENET_NIF_FUNC_DEF(get_interface_info); \ ENET_NIF_FUNC_DEF(get_ip_address_table); \ + ENET_NIF_FUNC_DEF(getservbyname); \ ENET_NIF_FUNC_DEF(if_name2index); \ ENET_NIF_FUNC_DEF(if_index2name); \ ENET_NIF_FUNC_DEF(if_names); @@ -467,7 +482,11 @@ static void make_ip_address_row(ErlNifEnv* env, ERL_NIF_TERM eReasmSize, ERL_NIF_TERM* iar); -#endif +#endif // defined(__WIN32__) + +static ERL_NIF_TERM enet_getservbyname(ErlNifEnv* env, + ERL_NIF_TERM ename, + ERL_NIF_TERM eproto); #if defined(HAVE_IF_NAMETOINDEX) static ERL_NIF_TERM enet_if_name2index(ErlNifEnv* env, @@ -791,6 +810,7 @@ static ErlNifResourceTypeInit netInit = { * nif_get_if_entry/1 * nif_get_interface_info/1 * nif_get_ip_address_table/1 + * nif_getservbyname/2 * nif_if_name2index/1 * nif_if_index2name/1 * nif_if_names/0 @@ -3932,6 +3952,86 @@ void make_ip_address_row(ErlNifEnv* env, +/* ---------------------------------------------------------------------- + * nif_getservbyname + * + * Description: + * Get service by name. + * This is a lookup function that translates a service name to its + * registered port number. + * + * Arguments: + * Name - The name of the service. + * Protocol - The name of the service. + * + * Returns: + * {ok, PortNumber :: port_number()} | {error, Reason :: term()} + */ + +static +ERL_NIF_TERM nif_getservbyname(ErlNifEnv* env, + int argc, + const ERL_NIF_TERM argv[]) +{ + ERL_NIF_TERM result, ename, eproto; + BOOLEAN_T dbg = FALSE; + + NDBG( ("NET", "nif_get_ip_address_table -> entry (%d)\r\n", argc) ); + + if (argc != 2) + return enif_make_badarg(env); + + ename = argv[0]; + eproto = argv[1]; + + NDBG2( dbg, + ("NET", + "nif_getservbyname -> args: " + "\r\n ename: %T" + "\r\n eproto: %T" + "\r\n", ename, eproto) ); + + result = enet_getservbyname(env, ename, eproto); + + NDBG2( dbg, + ("NET", + "nif_getservbyname -> done when result: " + "\r\n %T\r\n", result) ); + + return result; +} + + +static +ERL_NIF_TERM enet_getservbyname(ErlNifEnv* env, + ERL_NIF_TERM ename, + ERL_NIF_TERM eproto) +{ + char name[256]; + char proto[256]; + struct servent* srv; + short port; + + if (0 >= GET_STR(env, ename, name, sizeof(name))) + return esock_make_error(env, esock_atom_einval); + + if (0 >= GET_STR(env, eproto, proto, sizeof(proto))) + return esock_make_error(env, esock_atom_einval); + + if ( strcmp(proto, "any") == 0 ) + srv = net_getservbyname(name, NULL); + else + srv = net_getservbyname(name, proto); + + if (srv == NULL) + return esock_make_error(env, esock_atom_einval); + + port = net_ntohs(srv->s_port); + + return esock_make_ok2(env, MKI(env, port)); +} + + /* ---------------------------------------------------------------------- * nif_if_name2index @@ -4697,6 +4797,7 @@ ErlNifFunc net_funcs[] = {"nif_get_if_entry", 1, nif_get_if_entry, ERL_NIF_DIRTY_JOB_IO_BOUND}, {"nif_get_interface_info", 1, nif_get_interface_info, ERL_NIF_DIRTY_JOB_IO_BOUND}, {"nif_get_ip_address_table", 1, nif_get_ip_address_table, ERL_NIF_DIRTY_JOB_IO_BOUND}, + {"nif_getservbyname", 2, nif_getservbyname, ERL_NIF_DIRTY_JOB_IO_BOUND}, /* Network interface (name and/or index) functions */ {"nif_if_name2index", 1, nif_if_name2index, 0}, diff --git a/lib/kernel/src/net.erl b/lib/kernel/src/net.erl index e642b89d5a..f51f4fb51a 100644 --- a/lib/kernel/src/net.erl +++ b/lib/kernel/src/net.erl @@ -34,9 +34,10 @@ This module provides an API for the network interface. -export([ gethostname/0, - getnameinfo/1, getnameinfo/2, - getaddrinfo/1, getaddrinfo/2, - getifaddrs/0, getifaddrs/1, getifaddrs/2, + getnameinfo/1, getnameinfo/2, + getaddrinfo/1, getaddrinfo/2, + getifaddrs/0, getifaddrs/1, getifaddrs/2, + getservbyname/1, getservbyname/2, if_name2index/1, if_index2name/1, @@ -320,6 +321,7 @@ getaddrinfo(Host, Service) (not ((Service =:= undefined) andalso (Host =:= undefined))) -> prim_net:getaddrinfo(Host, Service). + %% =========================================================================== %% %% getifaddrs - Get interface addresses @@ -893,6 +895,45 @@ iat_broadaddr({A1, A2, A3, A4}, {M1, M2, M3, M4}) -> addr => {BA1, BA2, BA3, BA4}, port => 0}. + +%% =========================================================================== +%% +%% getservbyname - Get service by name +%% +%% Get the port number for the named service. +%% + +-doc(#{equiv => getservbyname(Name, any)}). +-doc(#{since => <<"OTP FOOBAR">>}). +-spec getservbyname(Name) -> + {ok, PortNumber} | {error, Reason} when + Name :: atom() | string(), + PortNumber :: socket:port_number(), + Reason :: term(). +getservbyname(Name) -> + getservbyname(Name, any). + +-doc """ +Get service by name. + +This function is used to get the port number of the specified protocol +for the named service. +""". +-doc(#{since => <<"OTP FOOBAR">>}). +-spec getservbyname(Name, Protocol) -> + {ok, PortNumber} | {error, Reason} when + Name :: atom() | string(), + PortNumber :: socket:port_number(), + Protocol :: any | socket:protocol(), + Reason :: term(). +getservbyname(Name, Protocol) + when is_atom(Name) -> + getservbyname(atom_to_list(Name), Protocol); +getservbyname(Name, Protocol) + when is_list(Name) andalso is_atom(Protocol) -> + prim_net:getservbyname(Name, atom_to_list(Protocol)). + + %% =========================================================================== %% %% if_name2index - Mappings between network interface names and indexes: -- 2.35.3
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor