File 6931-stdlib-allow-file-permissions-in-erl_tar-add-3-4-opt.patch of Package erlang

From 0f339568d4f105e2cee79317fd9ded1eb722c557 Mon Sep 17 00:00:00 2001
From: Stefan Grundmann <sg2342@googlemail.com>
Date: Sat, 10 Jan 2026 05:15:46 +0000
Subject: [PATCH] stdlib: allow file permissions in erl_tar:add/3,4 options

Fixes #10523
---
 lib/stdlib/src/erl_tar.erl    | 10 ++++++++--
 lib/stdlib/src/erl_tar.hrl    |  2 ++
 lib/stdlib/test/tar_SUITE.erl | 22 ++++++++++++++++------
 3 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/lib/stdlib/doc/src/erl_tar.xml b/lib/stdlib/doc/src/erl_tar.xml
index c760a0da20..0018551ca8 100644
--- a/lib/stdlib/doc/src/erl_tar.xml
+++ b/lib/stdlib/doc/src/erl_tar.xml
@@ -207,6 +207,11 @@
               <seemfa marker="kernel:file#read_file_info/1">
               <c>file:read_file_info/1</c></seemfa>.</p>
           </item>
+          <tag><c>{mode,non_neg_integer()}</c></tag>
+          <item>
+            <p>Sets the file permissions.
+              See also <c>file:read_file_info/1</c>.</p>
+          </item>
         </taglist>
       </desc>
     </func>
diff --git a/lib/stdlib/src/erl_tar.erl b/lib/stdlib/src/erl_tar.erl
index c760a0da20..0018551ca8 100644
--- a/lib/stdlib/src/erl_tar.erl
+++ b/lib/stdlib/src/erl_tar.erl
@@ -839,6 +841,8 @@ add_opts([{mtime,Value}|T], AllOptions, Opts) ->
     add_opts(T, AllOptions, Opts#add_opts{mtime=Value});
 add_opts([{ctime,Value}|T], AllOptions, Opts) ->
     add_opts(T, AllOptions, Opts#add_opts{ctime=Value});
+add_opts([{mode,Value}|T], AllOptions, Opts) ->
+    add_opts(T, AllOptions, Opts#add_opts{mode=Value});
 add_opts([{uid,Value}|T], AllOptions, Opts) ->
     add_opts(T, AllOptions, Opts#add_opts{uid=Value});
 add_opts([{gid,Value}|T], AllOptions, Opts) ->
@@ -859,6 +863,8 @@ do_apply_file_info_opts([{mtime,Value}|T], FileInfo) ->
     do_apply_file_info_opts(T, FileInfo#file_info{mtime=Value});
 do_apply_file_info_opts([{ctime,Value}|T], FileInfo) ->
     do_apply_file_info_opts(T, FileInfo#file_info{ctime=Value});
+do_apply_file_info_opts([{mode,Value}|T], FileInfo) ->
+    do_apply_file_info_opts(T, FileInfo#file_info{mode=Value});
 do_apply_file_info_opts([{uid,Value}|T], FileInfo) ->
     do_apply_file_info_opts(T, FileInfo#file_info{uid=Value});
 do_apply_file_info_opts([{gid,Value}|T], FileInfo) ->
@@ -916,7 +922,7 @@ add1(Reader, Bin, NameInArchive, Opts) when is_binary(Bin) ->
                 ctime = add_opts_time(Opts#add_opts.ctime, Now),
                 uid = Opts#add_opts.uid,
                 gid = Opts#add_opts.gid,
-                mode = 8#100644},
+                mode = Opts#add_opts.mode},
     {ok, Reader2} = add_header(Reader, Header, Opts),
     Padding = skip_padding(byte_size(Bin)),
     Data = [Bin, <<0:Padding/unit:8>>],
diff --git a/lib/stdlib/src/erl_tar.hrl b/lib/stdlib/src/erl_tar.hrl
index 9cfc534c43..38bd6834d0 100644
--- a/lib/stdlib/src/erl_tar.hrl
+++ b/lib/stdlib/src/erl_tar.hrl
@@ -27,6 +27,7 @@
          atime = undefined,
          mtime = undefined,
          ctime = undefined,
+         mode = 8#100644,
          uid = 0,
          gid = 0}).
 -type add_opts() :: #add_opts{}.
@@ -47,6 +48,7 @@
                    {atime, non_neg_integer()} |
                    {mtime, non_neg_integer()} |
                    {ctime, non_neg_integer()} |
+                   {mode, non_neg_integer()} |
                    {uid, non_neg_integer()} |
                    {gid, non_neg_integer()}.
 
diff --git a/lib/stdlib/test/tar_SUITE.erl b/lib/stdlib/test/tar_SUITE.erl
index 9941dfd690..397e8ad01a 100644
--- a/lib/stdlib/test/tar_SUITE.erl
+++ b/lib/stdlib/test/tar_SUITE.erl
@@ -1041,7 +1041,8 @@ apply_file_info_opts(Config) when is_list(Config) ->
     ok = file:make_dir("empty_directory"),
     ok = file:write_file("file", "contents"),
 
-    Opts = [{atime, 0}, {mtime, 0}, {ctime, 0}, {uid, 0}, {gid, 0}],
+    Mode = 8#707,
+    Opts = [{atime, 0}, {mtime, 0}, {ctime, 0}, {uid, 0}, {gid, 0}, {mode, Mode}],
     TarFile = "reproducible.tar",
     {ok, Tar} = erl_tar:open(TarFile, [write]),
     ok = erl_tar:add(Tar, "file", Opts),
@@ -1052,14 +1053,23 @@ apply_file_info_opts(Config) when is_list(Config) ->
     ok = file:make_dir("extracted"),
     erl_tar:extract(TarFile, [{cwd, "extracted"}]),
 
-    {ok, #file_info{mtime=0}} =
+    {ok, #file_info{mtime=0} = Fi1} =
         file:read_file_info("extracted/empty_directory", [{time, posix}]),
-    {ok, #file_info{mtime=0}} =
+    {ok, #file_info{mtime=0} = Fi2} =
         file:read_file_info("extracted/file", [{time, posix}]),
-    {ok, #file_info{mtime=0}} =
+    {ok, #file_info{mtime=0} = Fi3} =
         file:read_file_info("extracted/memory_file", [{time, posix}]),
 
-    ok.
+    %% On Unix platforms 'mode' works
+    case os:type() of
+        {unix,_} ->
+            Mode = Fi1#file_info.mode band Mode,
+            Mode = Fi2#file_info.mode band Mode,
+            Mode = Fi3#file_info.mode band Mode,
+            ok;
+        _ ->
+            ok
+    end.
 
 table_absolute_names(Config) ->
     PrivDir = proplists:get_value(priv_dir, Config),
@@ -1181,4 +1191,4 @@ uid_config(Config) ->
     [{longuid, length(Octal) > 7}|Config].
 
 long_uid(Config) ->
-    proplists:get_value(longuid, Config).
\ No newline at end of file
+    proplists:get_value(longuid, Config).
-- 
2.51.0

openSUSE Build Service is sponsored by