File 4421-Add-compressed_one-to-file-Modes.patch of Package erlang

From d2e88f0e4ec68b428babfb3857cb13b6e3044f52 Mon Sep 17 00:00:00 2001
From: Simon Cornish <7t9jna402@sneakemail.com>
Date: Mon, 3 Oct 2022 10:59:16 -0700
Subject: [PATCH 1/2] Add compressed_one to file Modes

compressed_one will read one member of a gzipped compressed file
---
 lib/kernel/doc/src/file.xml            |  6 ++++++
 lib/kernel/src/file.erl                |  2 +-
 lib/kernel/src/raw_file_io.erl         |  1 +
 lib/kernel/src/raw_file_io_inflate.erl | 13 ++++++++++---
 4 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/lib/kernel/doc/src/file.xml b/lib/kernel/doc/src/file.xml
index aa1201d381..463ba4d037 100644
--- a/lib/kernel/doc/src/file.xml
+++ b/lib/kernel/doc/src/file.xml
@@ -867,6 +867,12 @@ f.txt:  {person, "kalle", 25}.
 	      does probably not match the number of bytes that can be
 	      read from a compressed file.</p>
           </item>
+          <tag><c>compressed_one</c></tag>
+          <item>
+            <p>Read one member of a gzip compressed file.
+	      Option <c>compressed_one</c> can only be combined
+	      with <c>read</c>.</p>
+          </item>
           <tag><c>{encoding, Encoding}</c></tag>
           <item>
             <p>Makes the file perform automatic translation of characters to
diff --git a/lib/kernel/src/file.erl b/lib/kernel/src/file.erl
index 57d3add4cb..8dbfb6fa61 100644
--- a/lib/kernel/src/file.erl
+++ b/lib/kernel/src/file.erl
@@ -95,7 +95,7 @@
                       Size :: non_neg_integer(),
                       Delay :: non_neg_integer()}
 		   | 'delayed_write' | {'read_ahead', Size :: pos_integer()}
-		   | 'read_ahead' | 'compressed'
+		   | 'read_ahead' | 'compressed' | 'compressed_one'
 		   | {'encoding', unicode:encoding()}
 		   | sync.
 -type deep_list() :: [char() | atom() | deep_list()].
diff --git a/lib/kernel/src/raw_file_io.erl b/lib/kernel/src/raw_file_io.erl
index a153adeff0..718381dc17 100644
--- a/lib/kernel/src/raw_file_io.erl
+++ b/lib/kernel/src/raw_file_io.erl
@@ -56,6 +56,7 @@ match_list(list) -> true;
 match_list(_Other) -> false.
 
 match_compressed(compressed) -> true;
+match_compressed(compressed_one) -> true;
 match_compressed(_Other) -> false.
 
 match_delayed({delayed_write, _Size, _Timeout}) -> true;
diff --git a/lib/kernel/src/raw_file_io_inflate.erl b/lib/kernel/src/raw_file_io_inflate.erl
index a0c32b1b5e..01e0af9a61 100644
--- a/lib/kernel/src/raw_file_io_inflate.erl
+++ b/lib/kernel/src/raw_file_io_inflate.erl
@@ -32,12 +32,19 @@
 callback_mode() -> state_functions.
 
 init({Owner, Secret, [compressed]}) ->
-    Monitor = monitor(process, Owner),
-    %% We're using the undocumented inflateInit/3 to open the stream in
     %% 'reset mode', which resets the inflate state at the end of every stream,
     %% allowing us to read concatenated gzip files.
+    init(Owner, Secret, reset);
+init({Owner, Secret, [compressed_one]}) ->
+    %% 'cut mode', which stops the inflate after one member
+    %% allowing us to read gzipped tar files
+    init(Owner, Secret, cut).
+
+init(Owner, Secret, Mode) ->
+    Monitor = monitor(process, Owner),
+    %% We're using the undocumented inflateInit/3 to set the mode
     Z = zlib:open(),
-    ok = zlib:inflateInit(Z, ?GZIP_WBITS, reset),
+    ok = zlib:inflateInit(Z, ?GZIP_WBITS, Mode),
     Data =
         #{ owner => Owner,
            monitor => Monitor,
-- 
2.35.3

openSUSE Build Service is sponsored by