File 2057-Fix-fumble-of-already-buffered-data-when-recv-a-spec.patch of Package erlang
From 8b668f93df9f0d883b192663a8405595382f0e0f Mon Sep 17 00:00:00 2001
From: Raimo Niskanen <raimo@erlang.org>
Date: Tue, 28 Apr 2020 15:15:26 +0200
Subject: [PATCH 1/2] Fix fumble of already buffered data when recv a specified
number of bytes.
---
lib/kernel/src/gen_tcp_socket.erl | 40 ++++++++++++++++++++++++++-------------
1 file changed, 27 insertions(+), 13 deletions(-)
diff --git a/lib/kernel/src/gen_tcp_socket.erl b/lib/kernel/src/gen_tcp_socket.erl
index 86dce24cb5..bb7350dd22 100644
--- a/lib/kernel/src/gen_tcp_socket.erl
+++ b/lib/kernel/src/gen_tcp_socket.erl
@@ -1227,9 +1227,7 @@ handle_event(
{call, From}, {recv, Length, Timeout}, State, {P, D}) ->
case State of
'connected' ->
- handle_recv(
- P, recv_start(D, From, Length),
- [{{timeout, recv}, Timeout, recv}]);
+ handle_recv_start(P, D, From, Length, Timeout);
#recv{} ->
%% Receive in progress
{keep_state_and_data,
@@ -1352,6 +1350,32 @@ handle_connected(P, D, ActionsR) ->
handle_recv(P, recv_start(D), ActionsR)
end.
+handle_recv_start(
+ P, #{packet := Packet, buffer := Buffer} = D, From, Length, Timeout)
+ when Packet =:= raw, 0 < Length;
+ Packet =:= 0, 0 < Length ->
+ Size = iolist_size(Buffer),
+ if
+ Length =< Size ->
+ {Data, NewBuffer} =
+ split_binary(condense_buffer(Buffer), Length),
+ handle_recv_deliver(
+ P,
+ D#{recv_length => Length, % Redundant
+ recv_from => From,
+ buffer := NewBuffer},
+ [], Data);
+ true ->
+ N = Length - Size,
+ handle_recv(
+ P, D#{recv_length => N, recv_from => From},
+ [{{timeout, recv}, Timeout, recv}])
+ end;
+handle_recv_start(P, D, From, _Length, Timeout) ->
+ handle_recv(
+ P, D#{recv_length => 0, recv_from => From},
+ [{{timeout, recv}, Timeout, recv}]).
+
handle_recv(P, #{packet := Packet, recv_length := Length} = D, ActionsR) ->
if
0 < Length ->
@@ -1661,16 +1685,6 @@ cleanup_recv_reply(
end}.
%% Initialize packet recv state
-recv_start(#{packet := Packet} = D, From, Length) ->
- %%
- D#{recv_length =>
- case Packet of
- raw -> Length;
- 0 -> Length;
- _ -> 0
- end,
- recv_from => From}.
-
recv_start(D) ->
D#{recv_length => 0}.
--
2.16.4