diff options
author | Serge Aleynikov <[email protected]> | 2015-12-30 13:29:34 -0500 |
---|---|---|
committer | Serge Aleynikov <[email protected]> | 2016-01-12 11:18:12 -0500 |
commit | e293ad1b08b2f937555a102e6f3b4336574773c8 (patch) | |
tree | b2eb8a92e8386e9d9589503929b2cf8afac13068 /lib/kernel/src/inet_tcp.erl | |
parent | 1237669f7c59714f0c27d3df748241dfd655c0be (diff) | |
download | otp-e293ad1b08b2f937555a102e6f3b4336574773c8.tar.gz otp-e293ad1b08b2f937555a102e6f3b4336574773c8.tar.bz2 otp-e293ad1b08b2f937555a102e6f3b4336574773c8.zip |
Assign externally open fd to gen_tcp (UDS support)
When a AF_LOCAL file descriptor is created externally (e.g. Unix
Domain Socket) and passed to `gen_tcp:listen(0, [{fd, FD}])`, the
implementation incorrectly assigned the address family to be equal
to `inet`, which in the inet_drv driver translated to AF_INET instead
of AF_LOCAL (or AF_UNIX), and an `einval` error code was returned.
This patch fixes this problem such that the file descriptors of the
`local` address family are supported in the inet:fdopen/5,
gen_tcp:connect/3, gen_tcp:listen/2, gen_udp:open/2 calls
Diffstat (limited to 'lib/kernel/src/inet_tcp.erl')
-rw-r--r-- | lib/kernel/src/inet_tcp.erl | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/lib/kernel/src/inet_tcp.erl b/lib/kernel/src/inet_tcp.erl index f551af9709..ad0a6159fe 100644 --- a/lib/kernel/src/inet_tcp.erl +++ b/lib/kernel/src/inet_tcp.erl @@ -108,9 +108,10 @@ do_connect({A,B,C,D}, Port, Opts, Time) when ?ip(A,B,C,D), ?port(Port) -> {ok, #connect_opts{fd=Fd, ifaddr=BAddr={Ab,Bb,Cb,Db}, port=BPort, + family=Family, opts=SockOpts}} when ?ip(Ab,Bb,Cb,Db), ?port(BPort) -> - case inet:open(Fd,BAddr,BPort,SockOpts,tcp,inet,stream,?MODULE) of + case inet:open(Fd,BAddr,BPort,SockOpts,tcp,Family,stream,?MODULE) of {ok, S} -> case prim_inet:connect(S, {A,B,C,D}, Port, Time) of ok -> {ok,S}; @@ -130,9 +131,10 @@ listen(Port, Opts) -> {ok, #listen_opts{fd=Fd, ifaddr=BAddr={A,B,C,D}, port=BPort, + family=Family, opts=SockOpts}=R} when ?ip(A,B,C,D), ?port(BPort) -> - case inet:open(Fd,BAddr,BPort,SockOpts,tcp,inet,stream,?MODULE) of + case inet:open(Fd,BAddr,BPort,SockOpts,tcp,Family,stream,?MODULE) of {ok, S} -> case prim_inet:listen(S, R#listen_opts.backlog) of ok -> {ok, S}; @@ -165,4 +167,7 @@ accept(L,Timeout) -> %% Create a port/socket from a file descriptor %% fdopen(Fd, Opts) -> - inet:fdopen(Fd, Opts, tcp, inet, stream, ?MODULE). + fdopen(Fd, inet:getfamily(Opts), Opts). + +fdopen(Fd, Family, Opts) -> + inet:fdopen(Fd, Opts, tcp, Family, stream, ?MODULE). |