From f6e622ea274c86fba6c310ba36bb67a86187c808 Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Wed, 22 Jan 2020 14:52:39 +0100 Subject: [PATCH] TT#71952 tt2-process: Set the output file permissions when creating the file This avoids lots of chmod calls. We do not need the symlink handling, as we will generate now the files with the correct permissions, and will respect the symlinks on mv, as before, and are not doing the explicit chmod anymore. Change-Id: I9ab75dda79e8b346eb1f41c36b450d6fabb10f11 --- helper/tt2-process | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/helper/tt2-process b/helper/tt2-process index 2cd98783..b391a00a 100755 --- a/helper/tt2-process +++ b/helper/tt2-process @@ -6,11 +6,13 @@ use warnings; use List::Util qw(any uniq pairmap); use Getopt::Long qw(:config posix_default bundling_values no_ignorecase); use Cwd qw(realpath); +use Errno qw(EEXIST); use File::Basename; use File::Path qw(make_path); use File::Copy qw(mv); use File::Find; use Time::Piece; +use Fcntl; use POSIX qw(:sys_wait_h); use Hash::Merge qw(merge); use YAML::XS qw(LoadFile); @@ -102,10 +104,24 @@ sub setup { sub process_template { my ($tt, $config, $input, $output) = @_; + # Set permissions for generated config based on the ones of the + # template, plus dropping all write permissions. + my $old_umask = umask 0222; + my $mode = (stat $input)[2]; + my $newfile = "$output.ngcpcfg-new"; - open my $outfh, '>', $newfile - or error("Cannot open template new file $newfile: $!"); + my $outfh; + if (!sysopen $outfh, $newfile, O_CREAT | O_EXCL | O_WRONLY, $mode) { + if ($! != EEXIST) { + error("Cannot open template new file $newfile: $!"); + } + unlink $newfile + or error("Cannot remove template new file $newfile: $!"); + + sysopen $outfh, $newfile, O_CREAT | O_EXCL | O_WRONLY, $mode + or error("Cannot open template new file $newfile: $!"); + } open my $infh, '<', $input or error("Cannot open file '$input' for reading: $!"); $tt->process($infh, $config, $outfh) @@ -113,6 +129,9 @@ sub process_template { close $infh; close $outfh; + # Restore previous umask. + umask $old_umask; + # XXX: Docker breaks sane Unix expectations when moving a file into # /etc/hosts, as it creates a bind mount on that pathname. We need to # use an implementation that will fallback to use copy semantics in @@ -179,17 +198,6 @@ sub process_input { info("Generating $output: OK"); } - if (-l $output) { - warning("File $output is a symlink - NOT adjusting permissions"); - } else { - # Set permissions for generated config based on the ones of the - # template, plus dropping all write permissions. - ## no critic (ValuesAndExpressions::ProhibitLeadingZeros) - my $mode = (stat $input)[2] & ~0222; - - chmod $mode, $output; - } - # Execute postbuild script. for my $postbuild (( "$input_dirname/$output_basename.postbuild",