aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorLukas Larsson <[email protected]>2011-11-16 16:09:32 +0100
committerLukas Larsson <[email protected]>2011-12-01 14:10:05 +0100
commit06e77d9baa4c631bc329aa1fafb29ee55f66d906 (patch)
tree789f80ea2b36bd51fa315ddd9224dda8c645937d /lib
parentc68746bda431c5a068e6bb4a93bfe5ae77ce2d9a (diff)
downloadotp-06e77d9baa4c631bc329aa1fafb29ee55f66d906.tar.gz
otp-06e77d9baa4c631bc329aa1fafb29ee55f66d906.tar.bz2
otp-06e77d9baa4c631bc329aa1fafb29ee55f66d906.zip
sendfile caller now has to be the controlling_process
This is needed because otherwise there could be scenarios when the efile driver blocks a fd and then crashes without the inet driver ever finding out. Now when the process crashes the port will close and we can cleanup in the inet driver.
Diffstat (limited to 'lib')
-rw-r--r--lib/kernel/src/gen_tcp.erl6
-rw-r--r--lib/kernel/src/inet.erl15
2 files changed, 18 insertions, 3 deletions
diff --git a/lib/kernel/src/gen_tcp.erl b/lib/kernel/src/gen_tcp.erl
index 9dd70ce5cc..2eaa44b966 100644
--- a/lib/kernel/src/gen_tcp.erl
+++ b/lib/kernel/src/gen_tcp.erl
@@ -412,16 +412,16 @@ mod([], Address) ->
sendfile(#file_descriptor{ module = Mod } = Fd, Sock, Offset, Bytes,
ChunkSize, Headers, Trailers, Nodiskio, MNowait, Sync)
when is_port(Sock) ->
- ok = prim_inet:ignorefd(Sock,true),
+ ok = inet:lock_socket(Sock,true),
{ok, SockFd} = prim_inet:getfd(Sock),
case Mod:sendfile(Fd, SockFd, Offset, Bytes, ChunkSize, Headers, Trailers,
Nodiskio, MNowait, Sync) of
{error, enotsup} ->
- ok = prim_inet:ignorefd(Sock,false),
+ ok = inet:lock_socket(Sock,false),
sendfile_fallback(Fd, Sock, Offset, Bytes, ChunkSize,
Headers, Trailers);
Else ->
- ok = prim_inet:ignorefd(Sock,false),
+ ok = inet:lock_socket(Sock,false),
Else
end;
sendfile(_,_,_,_,_,_,_,_,_,_) ->
diff --git a/lib/kernel/src/inet.erl b/lib/kernel/src/inet.erl
index b60c68e3a1..49f64a9236 100644
--- a/lib/kernel/src/inet.erl
+++ b/lib/kernel/src/inet.erl
@@ -40,6 +40,10 @@
-export([tcp_controlling_process/2, udp_controlling_process/2,
tcp_close/1, udp_close/1]).
+
+%% used by sendfile
+-export([lock_socket/2]).
+
%% used by socks5
-export([setsockname/2, setpeername/2]).
@@ -1353,3 +1357,14 @@ stop_timer(Timer) ->
end;
T -> T
end.
+
+
+lock_socket(S,Val) ->
+ case erlang:port_info(S, connected) of
+ {connected, Pid} when Pid =/= self() ->
+ {error, not_owner};
+ undefined ->
+ {error, einval};
+ _ ->
+ prim_inet:ignorefd(S,Val)
+ end.