diff options
Diffstat (limited to 'lib/kernel')
-rw-r--r-- | lib/kernel/doc/src/gen_sctp.xml | 8 | ||||
-rw-r--r-- | lib/kernel/doc/src/gen_tcp.xml | 6 | ||||
-rw-r--r-- | lib/kernel/doc/src/gen_udp.xml | 6 | ||||
-rw-r--r-- | lib/kernel/doc/src/inet.xml | 7 | ||||
-rw-r--r-- | lib/kernel/src/file.erl | 2 | ||||
-rw-r--r-- | lib/kernel/src/gen_sctp.erl | 5 | ||||
-rw-r--r-- | lib/kernel/src/gen_udp.erl | 5 | ||||
-rw-r--r-- | lib/kernel/src/inet.erl | 4 | ||||
-rw-r--r-- | lib/kernel/test/bif_SUITE.erl | 94 | ||||
-rw-r--r-- | lib/kernel/test/gen_tcp_misc_SUITE.erl | 35 |
10 files changed, 77 insertions, 95 deletions
diff --git a/lib/kernel/doc/src/gen_sctp.xml b/lib/kernel/doc/src/gen_sctp.xml index cf1cfb6ec9..e327a4f907 100644 --- a/lib/kernel/doc/src/gen_sctp.xml +++ b/lib/kernel/doc/src/gen_sctp.xml @@ -123,7 +123,7 @@ <p>Completely closes the socket and all associations on it. The unsent data is flushed as in <c>eof/2</c>. The <c>close/1</c> call is blocking or otherwise depending of the value of - the <seealso marker="#option-linger">linger</seealso> socket + the <seealso marker="inet#option-linger">linger</seealso> socket <seealso marker="#options">option</seealso>. If <c>close</c> does not linger or linger timeout expires, the call returns and the data is flushed in the background.</p> @@ -309,8 +309,8 @@ <seealso marker="#option-active">passive</seealso> mode, with <anno>SockType</anno> <c>seqpacket</c>, and with reasonably large - <seealso marker="#option-sndbuf">kernel</seealso> and driver - <seealso marker="#option-buffer">buffers.</seealso></p> + <seealso marker="inet#option-sndbuf">kernel</seealso> and driver + <seealso marker="inet#option-buffer">buffers.</seealso></p> </desc> </func> <func> @@ -574,7 +574,7 @@ <tag><c>{sctp_module, module()}</c></tag> <item> <p> - Override which callback module used. Defaults to + Override which callback module is used. Defaults to <c>inet_sctp</c> for IPv4 and <c>inet6_sctp</c> for IPv6. </p> </item> diff --git a/lib/kernel/doc/src/gen_tcp.xml b/lib/kernel/doc/src/gen_tcp.xml index 869e305690..11a0843c10 100644 --- a/lib/kernel/doc/src/gen_tcp.xml +++ b/lib/kernel/doc/src/gen_tcp.xml @@ -132,7 +132,7 @@ do_recv(Sock, Bs) -> <tag><c>{tcp_module, module()}</c></tag> <item> <p> - Override which callback module used. Defaults to + Override which callback module is used. Defaults to <c>inet_tcp</c> for IPv4 and <c>inet6_tcp</c> for IPv6. </p> </item> @@ -225,7 +225,7 @@ do_recv(Sock, Bs) -> <tag><c>{tcp_module, module()}</c></tag> <item> <p> - Override which callback module used. Defaults to + Override which callback module is used. Defaults to <c>inet_tcp</c> for IPv4 and <c>inet6_tcp</c> for IPv6. </p> </item> @@ -324,7 +324,7 @@ do_recv(Sock, Bs) -> <c><anno>Socket</anno></c>. The controlling process is the process which receives messages from the socket. If called by any other process than the current controlling process, - <c>{error, eperm}</c> is returned.</p> + <c>{error, not_owner}</c> is returned.</p> </desc> </func> <func> diff --git a/lib/kernel/doc/src/gen_udp.xml b/lib/kernel/doc/src/gen_udp.xml index 77e6182884..726dc30546 100644 --- a/lib/kernel/doc/src/gen_udp.xml +++ b/lib/kernel/doc/src/gen_udp.xml @@ -97,7 +97,7 @@ <tag><c>{udp_module, module()}</c></tag> <item> <p> - Override which callback module used. Defaults to + Override which callback module is used. Defaults to <c>inet_udp</c> for IPv4 and <c>inet6_udp</c> for IPv6. </p> </item> @@ -189,7 +189,9 @@ <desc> <p>Assigns a new controlling process <c><anno>Pid</anno></c> to <c><anno>Socket</anno></c>. The controlling process is the process which - receives messages from the socket.</p> + receives messages from the socket. If called by any other + process than the current controlling process, + <c>{error, not_owner}</c> is returned.</p> </desc> </func> <func> diff --git a/lib/kernel/doc/src/inet.xml b/lib/kernel/doc/src/inet.xml index 522a27dcfa..096ddfd847 100644 --- a/lib/kernel/doc/src/inet.xml +++ b/lib/kernel/doc/src/inet.xml @@ -459,6 +459,7 @@ fe80::204:acff:fe17:bf38 <tag><c>{broadcast, Boolean}</c>(UDP sockets)</tag> <item> <p>Enable/disable permission to send broadcasts.</p> + <marker id="option-buffer"></marker> </item> <tag><c>{buffer, Size}</c></tag> @@ -523,8 +524,8 @@ fe80::204:acff:fe17:bf38 <tag><c>{high_watermark, Size}</c></tag> <item> <p> - Sender is forced busy if sent and equeued data - readched the highwater mark. + Sender is forced busy if sent and enqueued data + reaches the highwater mark. <br /> Default: 8192 kB. </p> </item> @@ -536,6 +537,7 @@ fe80::204:acff:fe17:bf38 the other end does not respond, the connection is considered broken and an error message will be sent to the controlling process. Default disabled.</p> + <marker id="option-linger"></marker> </item> <tag><c>{linger, {true|false, Seconds}}</c></tag> @@ -705,6 +707,7 @@ fe80::204:acff:fe17:bf38 returns <c>{error,timeout}</c>. The recommended setting is <c>true</c> which will automatically close the socket. Default is <c>false</c> due to backward compatibility.</p> + <marker id="option-sndbuf"></marker> </item> <tag><c>{sndbuf, Size}</c></tag> diff --git a/lib/kernel/src/file.erl b/lib/kernel/src/file.erl index d8033ee192..cdb984c333 100644 --- a/lib/kernel/src/file.erl +++ b/lib/kernel/src/file.erl @@ -1258,7 +1258,7 @@ sendfile_fallback_int(File, Sock, Bytes, ChunkSize, BytesSent) when Bytes > BytesSent; Bytes == 0 -> Size = if Bytes == 0 -> ChunkSize; - (Bytes - BytesSent + ChunkSize) > 0 -> + (Bytes - BytesSent) < ChunkSize -> Bytes - BytesSent; true -> ChunkSize diff --git a/lib/kernel/src/gen_sctp.erl b/lib/kernel/src/gen_sctp.erl index d8954f0cf7..8fa963ec78 100644 --- a/lib/kernel/src/gen_sctp.erl +++ b/lib/kernel/src/gen_sctp.erl @@ -425,9 +425,10 @@ error_string(X) -> erlang:error(badarg, [X]). --spec controlling_process(Socket, Pid) -> ok when +-spec controlling_process(Socket, Pid) -> ok | {error, Reason} when Socket :: sctp_socket(), - Pid :: pid(). + Pid :: pid(), + Reason :: closed | not_owner | inet:posix(). controlling_process(S, Pid) when is_port(S), is_pid(Pid) -> inet:udp_controlling_process(S, Pid); diff --git a/lib/kernel/src/gen_udp.erl b/lib/kernel/src/gen_udp.erl index 8688799ae9..914854c65c 100644 --- a/lib/kernel/src/gen_udp.erl +++ b/lib/kernel/src/gen_udp.erl @@ -185,9 +185,10 @@ connect(S, Address, Port) when is_port(S) -> Error end. --spec controlling_process(Socket, Pid) -> ok when +-spec controlling_process(Socket, Pid) -> ok | {error, Reason} when Socket :: socket(), - Pid :: pid(). + Pid :: pid(), + Reason :: closed | not_owner | inet:posix(). controlling_process(S, NewOwner) -> inet:udp_controlling_process(S, NewOwner). diff --git a/lib/kernel/src/inet.erl b/lib/kernel/src/inet.erl index abaf4486dc..0bb5444dbb 100644 --- a/lib/kernel/src/inet.erl +++ b/lib/kernel/src/inet.erl @@ -1246,6 +1246,8 @@ udp_close(S) when is_port(S) -> %% Set controlling process for TCP socket. tcp_controlling_process(S, NewOwner) when is_port(S), is_pid(NewOwner) -> case erlang:port_info(S, connected) of + {connected, NewOwner} -> + ok; {connected, Pid} when Pid =/= self() -> {error, not_owner}; undefined -> @@ -1297,6 +1299,8 @@ tcp_sync_input(S, Owner, Flag) -> %% Set controlling process for UDP or SCTP socket. udp_controlling_process(S, NewOwner) when is_port(S), is_pid(NewOwner) -> case erlang:port_info(S, connected) of + {connected, NewOwner} -> + ok; {connected, Pid} when Pid =/= self() -> {error, not_owner}; _ -> diff --git a/lib/kernel/test/bif_SUITE.erl b/lib/kernel/test/bif_SUITE.erl index 6276270d20..a2826f34df 100644 --- a/lib/kernel/test/bif_SUITE.erl +++ b/lib/kernel/test/bif_SUITE.erl @@ -260,23 +260,15 @@ spawn_opt2(Config) when is_list(Config) -> ?line P1 = spawn_opt(fun() -> Parent ! {self(), fetch_proc_vals(self())} end, - case heap_type() of - separate -> - [{fullsweep_after, 0},{min_heap_size, 1000}]; - shared -> - [] - end - ++ [link, {priority, max}]), + [{fullsweep_after, 0},{min_heap_size, 1000}, + link, {priority, max}]), ?line receive {P1, PV1} -> ?line Node = node(P1), ?line check_proc_vals(true, max, 0, 1000, PV1) end, ?line P2 = spawn_opt(fun() -> Parent ! {self(), fetch_proc_vals(self())} end, - case heap_type() of - separate -> [{min_heap_size, 10}]; - shared -> [] - end), + [{min_heap_size, 10}]), ?line receive {P2, PV2} -> ?line Node = node(P2), @@ -295,13 +287,8 @@ spawn_opt3(Config) when is_list(Config) -> fun() -> Parent ! {self(), fetch_proc_vals(self())} end, - case heap_type() of - separate -> - [{fullsweep_after,0}, {min_heap_size,1000}]; - shared -> - [] - end - ++ [link, {priority, max}]), + [{fullsweep_after,0}, {min_heap_size,1000}, + link, {priority, max}]), ?line receive {P1, PV1} -> ?line Node = node(P1), @@ -309,10 +296,7 @@ spawn_opt3(Config) when is_list(Config) -> end, ?line P2 = spawn_opt(Node, fun() -> Parent ! {self(), fetch_proc_vals(self())} end, - case heap_type() of - separate -> [{min_heap_size, 10}]; - shared -> [] - end), + [{min_heap_size, 10}]), ?line receive {P2, PV2} -> ?line Node = node(P2), @@ -333,13 +317,8 @@ spawn_opt4(Config) when is_list(Config) -> [fun() -> Parent ! {self(), fetch_proc_vals(self())} end], - case heap_type() of - separate -> - [{fullsweep_after,0}, {min_heap_size,1000}]; - shared -> - [] - end - ++ [link, {priority, max}]), + [{fullsweep_after,0}, {min_heap_size,1000}, + link, {priority, max}]), ?line receive {P1, PV1} -> ?line Node = node(P1), @@ -350,10 +329,7 @@ spawn_opt4(Config) when is_list(Config) -> [fun() -> Parent ! {self(), fetch_proc_vals(self())} end], - case heap_type() of - separate -> [{min_heap_size, 10}]; - shared -> [] - end), + [{min_heap_size, 10}]), ?line receive {P2, PV2} -> ?line Node = node(P2), @@ -374,13 +350,8 @@ spawn_opt5(Config) when is_list(Config) -> [fun() -> Parent ! {self(), fetch_proc_vals(self())} end], - case heap_type() of - separate -> - [{fullsweep_after,0}, {min_heap_size,1000}]; - shared -> - [] - end - ++ [link, {priority, max}]), + [{fullsweep_after,0}, {min_heap_size,1000}, + link, {priority, max}]), ?line receive {P1, PV1} -> ?line Node = node(P1), @@ -392,10 +363,7 @@ spawn_opt5(Config) when is_list(Config) -> [fun() -> Parent ! {self(), fetch_proc_vals(self())} end], - case heap_type() of - separate -> [{min_heap_size, 10}]; - shared -> [] - end), + [{min_heap_size, 10}]), ?line receive {P2, PV2} -> ?line Node = node(P2), @@ -532,34 +500,19 @@ spawn_failures(Config) when is_list(Config) -> check_proc_vals(Link, Priority, FullsweepAfter, MinHeapSize, {Ls, P, FA, HS}) -> ?line Link = lists:member(self(), Ls), ?line Priority = P, - ?line case heap_type() of - separate -> - ?line FullsweepAfter = FA, - ?line true = (HS >= MinHeapSize); - shared -> - ?line ok - end, + FullsweepAfter = FA, + true = (HS >= MinHeapSize), ?line ok. fetch_proc_vals(Pid) -> ?line PI = process_info(Pid), ?line {value,{links, Ls}} = lists:keysearch(links, 1, PI), ?line {value,{priority,P}} = lists:keysearch(priority, 1, PI), - ?line {FA, HS} - = case heap_type() of - separate -> - ?line {value, - {garbage_collection, - Gs}} = lists:keysearch(garbage_collection, 1, PI), - ?line {value, - {fullsweep_after, - Fa}} = lists:keysearch(fullsweep_after, 1, Gs), - ?line {value, - {heap_size,Hs}} = lists:keysearch(heap_size, 1, PI), - ?line {Fa, Hs}; - shared -> - {undefined, undefined} - end, + {value,{garbage_collection,Gs}} = + lists:keysearch(garbage_collection, 1, PI), + {value,{fullsweep_after,FA}} = + lists:keysearch(fullsweep_after, 1, Gs), + {value,{heap_size,HS}} = lists:keysearch(heap_size, 1, PI), ?line {Ls, P, FA, HS}. % This testcase should probably be moved somewhere else @@ -650,12 +603,3 @@ stop_node(Node) -> run_fun(Fun) -> Fun(). - -heap_type() -> - case catch erlang:system_info(heap_type) of - shared -> shared; - unified -> shared; - _ -> separate - end. - - diff --git a/lib/kernel/test/gen_tcp_misc_SUITE.erl b/lib/kernel/test/gen_tcp_misc_SUITE.erl index c74a258af9..1592399996 100644 --- a/lib/kernel/test/gen_tcp_misc_SUITE.erl +++ b/lib/kernel/test/gen_tcp_misc_SUITE.erl @@ -24,7 +24,8 @@ -export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, init_per_group/2,end_per_group/2, - controlling_process/1, no_accept/1, close_with_pending_output/1, + controlling_process/1, controlling_process_self/1, + no_accept/1, close_with_pending_output/1, data_before_close/1, iter_max_socks/1, get_status/1, passive_sockets/1, accept_closed_by_other_process/1, init_per_testcase/2, end_per_testcase/2, @@ -58,7 +59,7 @@ end_per_testcase(_Func, Config) -> suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> - [controlling_process, no_accept, + [controlling_process, controlling_process_self, no_accept, close_with_pending_output, data_before_close, iter_max_socks, passive_sockets, accept_closed_by_other_process, otp_3924, closed_socket, @@ -307,6 +308,32 @@ not_owner(S) -> ok end. +controlling_process_self(doc) -> + ["Open a listen port and assign the controlling process to " + "it self, then exit and make sure the port is closed properly."]; +controlling_process_self(Config) when is_list(Config) -> + S = self(), + process_flag(trap_exit,true), + spawn_link(fun() -> + {ok,Sock} = gen_tcp:listen(0,[]), + S ! {socket, Sock}, + ok = gen_tcp:controlling_process(Sock,self()), + S ! done + end), + receive + done -> + receive + {socket,Sock} -> + process_flag(trap_exit,false), + %% Make sure the port is invalid after process crash + {error,einval} = inet:port(Sock) + end; + Msg when element(1,Msg) /= socket -> + process_flag(trap_exit,false), + exit({unknown_msg,Msg}) + end. + + no_accept(doc) -> ["Open a listen port and connect to it, then close the listen port ", "without doing any accept. The connected socket should receive ", @@ -2044,7 +2071,7 @@ send_timeout_active(Config) when is_list(Config) -> ?line {error,timeout} = Loop(fun() -> receive - {tcp, Sock, _Data} -> + {tcp, _Sock, _Data} -> inet:setopts(A, [{active, once}]), Res = gen_tcp:send(A,lists:duplicate(1000, $a)), %erlang:display(Res), @@ -2536,7 +2563,7 @@ otp_8102_do(LSocket, PortNum, {Bin,PType}) -> otp_9389(doc) -> ["Verify packet_size handles long HTTP header lines"]; otp_9389(suite) -> []; otp_9389(Config) when is_list(Config) -> - ?line {ok, LS} = gen_tcp:listen(0, []), + ?line {ok, LS} = gen_tcp:listen(0, [{active,false}]), ?line {ok, {_, PortNum}} = inet:sockname(LS), io:format("Listening on ~w with port number ~p\n", [LS, PortNum]), OrigLinkHdr = "/" ++ string:chars($S, 8192), |