aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/kernel/src/inet.erl78
1 files changed, 68 insertions, 10 deletions
diff --git a/lib/kernel/src/inet.erl b/lib/kernel/src/inet.erl
index e118382bfe..d2137065b6 100644
--- a/lib/kernel/src/inet.erl
+++ b/lib/kernel/src/inet.erl
@@ -200,7 +200,14 @@ send(Socket, Packet) ->
Options :: [socket_setopt()].
setopts(Socket, Opts) ->
- prim_inet:setopts(Socket, Opts).
+ SocketOpts =
+ [case Opt of
+ {netns,NS} ->
+ {netns,filename2binary(NS)};
+ _ ->
+ Opt
+ end || Opt <- Opts],
+ prim_inet:setopts(Socket, SocketOpts).
-spec getopts(Socket, Options) ->
{'ok', OptionValues} | {'error', posix()} when
@@ -209,7 +216,18 @@ setopts(Socket, Opts) ->
OptionValues :: [socket_setopt()].
getopts(Socket, Opts) ->
- prim_inet:getopts(Socket, Opts).
+ case prim_inet:getopts(Socket, Opts) of
+ {ok,OptionValues} ->
+ {ok,
+ [case OptionValue of
+ {netns,Bin} ->
+ {netns,binary2filename(Bin)};
+ _ ->
+ OptionValue
+ end || OptionValue <- OptionValues]};
+ Other ->
+ Other
+ end.
-spec getifaddrs(Socket :: socket()) ->
{'ok', [string()]} | {'error', posix()}.
@@ -635,9 +653,10 @@ con_opt([Opt | Opts], R, As) ->
inet -> con_opt(Opts, R, As);
inet6 -> con_opt(Opts, R, As);
{netns,NS} ->
- case prim_inet:is_sockopt_val(netns, NS) of
+ BinNS = filename2binary(NS),
+ case prim_inet:is_sockopt_val(netns, BinNS) of
true ->
- con_opt(Opts, R#connect_opts { fd = [Opt] }, As);
+ con_opt(Opts, R#connect_opts { fd = [{netns,BinNS}] }, As);
false ->
{error, badarg}
end;
@@ -700,9 +719,10 @@ list_opt([Opt | Opts], R, As) ->
inet -> list_opt(Opts, R, As);
inet6 -> list_opt(Opts, R, As);
{netns,NS} ->
- case prim_inet:is_sockopt_val(netns, NS) of
+ BinNS = filename2binary(NS),
+ case prim_inet:is_sockopt_val(netns, BinNS) of
true ->
- list_opt(Opts, R#listen_opts { fd = [Opt] }, As);
+ list_opt(Opts, R#listen_opts { fd = [{netns,BinNS}] }, As);
false ->
{error, badarg}
end;
@@ -753,9 +773,10 @@ udp_opt([Opt | Opts], R, As) ->
inet -> udp_opt(Opts, R, As);
inet6 -> udp_opt(Opts, R, As);
{netns,NS} ->
- case prim_inet:is_sockopt_val(netns, NS) of
+ BinNS = filename2binary(NS),
+ case prim_inet:is_sockopt_val(netns, BinNS) of
true ->
- list_opt(Opts, R#udp_opts { fd = [Opt] }, As);
+ list_opt(Opts, R#udp_opts { fd = [{netns,BinNS}] }, As);
false ->
{error, badarg}
end;
@@ -829,9 +850,13 @@ sctp_opt([Opt|Opts], Mod, R, As) ->
inet -> sctp_opt (Opts, Mod, R, As); % Done with
inet6 -> sctp_opt (Opts, Mod, R, As); % Done with
{netns,NS} ->
- case prim_inet:is_sockopt_val(netns, NS) of
+ BinNS = filename2binary(NS),
+ case prim_inet:is_sockopt_val(netns, BinNS) of
true ->
- sctp_opt(Opts, Mod, R#sctp_opts { fd = [Opt] }, As);
+ sctp_opt(
+ Opts, Mod,
+ R#sctp_opts { fd = [{netns,BinNS}] },
+ As);
false ->
{error, badarg}
end;
@@ -879,6 +904,39 @@ add_opt(Name, Val, Opts, As) ->
end.
+%% Passthrough all unknown - catch type errors later
+filename2binary(List) when is_list(List) ->
+ OutEncoding = file:native_name_encoding(),
+ try unicode:characters_to_binary(List, unicode, OutEncoding) of
+ Bin when is_binary(Bin) ->
+ Bin;
+ _ ->
+ List
+ catch
+ error:badarg ->
+ List
+ end;
+filename2binary(Bin) ->
+ Bin.
+
+binary2filename(Bin) ->
+ InEncoding = file:native_name_encoding(),
+ case unicode:characters_to_list(Bin, InEncoding) of
+ Filename when is_list(Filename) ->
+ Filename;
+ _ ->
+ %% For getopt/setopt of netns this should only happen if
+ %% a binary with wrong encoding was used when setting the
+ %% option, hence the user shall eat his/her own medicine.
+ %%
+ %% I.e passthrough here too for now.
+ %% Future usecases will most probably not want this,
+ %% rather Unicode error or warning
+ %% depending on emulator flag instead.
+ Bin
+ end.
+
+
translate_ip(any, inet) -> {0,0,0,0};
translate_ip(loopback, inet) -> {127,0,0,1};
translate_ip(any, inet6) -> {0,0,0,0,0,0,0,0};