From 2f608cd791956604eabf8f7d7d98bf1d753c5774 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
Date: Thu, 5 Dec 2019 17:21:29 +0100
Subject: [PATCH] Preserve write permission and apply umask
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Documentation read:
Copies each directory tree of %from_to to its corresponding value
preserving timestamps and permissions.
but the actual permissions were not preserved.
The behavior was that directories were created with 0755 permissions
and files with 0444. If the original file had any executable bit set,
all executable bits (0111) were set. Write permissions (0222) were set
only if the target file could not been overwritten (probably as
a measure to allow later renaming a temporary installation location on
operating systems that prevents from overwriting opened files).
This behavior usually did the right thing. Especially when installing
files by a superuser into a location accessible for everyone (e.g.
/usr/local).
But if the file is installed by a user for himself, he always lost
a permission for writing into that file. That's especially troublesome
when some postprocessing is needed. See
<
https://rt.cpan.org/Ticket/Display.html?id=40976> for an example.
This patch documents the behavior, but copies all executable
bits. And then clamps all permissions by umask, if umask is supported.
CPAN RT#40976
Signed-off-by: Petr PÃsaÅ <ppisar@redhat.com>
---
lib/ExtUtils/Install.pm | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/lib/ExtUtils/Install.pm b/lib/ExtUtils/Install.pm
index 047c007..29f7486 100644
--- a/lib/ExtUtils/Install.pm
+++ b/lib/ExtUtils/Install.pm
@@ -586,7 +586,12 @@ sub _chdir {
Copies each directory tree of %from_to to its corresponding value
-preserving timestamps and permissions.
+preserving timestamps.
+
+Directories are created with 0755 permissions. Files are created with read
+permissions for everyone, executable permissions for everyone if the file has
+at least one executable bit set, and write permissions are preserved. Then
+umask is applied to the permissions.
There are two keys with a special meaning in the hash: "read" and
"write". These contain packlist files. After the copying is done,
@@ -717,6 +722,7 @@ sub install { #XXX OS-SPECIFIC
my $tmpfile = install_rooted_file($pack{"read"});
$packlist->read($tmpfile) if (-f $tmpfile);
my $cwd = cwd();
+ my $umask = umask();
my @found_files;
my %check_dirs;
require File::Find;
@@ -825,7 +831,8 @@ sub install { #XXX OS-SPECIFIC
utime($atime,$mtime + Is_VMS,$targetfile) unless $dry_run>1;
- $mode = 0444 | ( $mode & 0111 ? 0111 : 0 );
+ $mode = 0444 | ( $mode & 0222 ) | ( $mode & 0111 ? 0111 : 0 );
+ $mode &= ~$umask if defined $umask;
$mode = $mode | 0222
if $realtarget ne $targetfile;
_chmod( $mode, $targetfile, $verbose );
--
2.21.0