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