in reply to Using the file handle created by File::Temp to set specific file permissions

If your goal is to safely edit a file, without suffering nasty race conditions, the straightforward solution I concocted back in 2003 (and am still happy with) is to simply write a new file on the same file system ... and then use (atomic) rename to clobber the original file - but only after the new file has been successfully written. This is described in detail at:

  • Comment on Re: Using the file handle created by File::Temp to set specific file permissions

Replies are listed 'Best First'.
Re^2: Using the file handle created by File::Temp to set specific file permissions
by mldvx4 (Hermit) on Dec 11, 2021 at 08:37 UTC

    Interesting sample. I've tried the following so far, but will have to redo my location for the temporary file based on the location of the destination. That is so it will be on the same partition as the file it is replacing. Otherwise, I get the error, "Could not rename temporary file handle: Invalid cross-device link".

    #!/usr/bin/perl use File::Temp; use strict; use warnings; my @data = qw/a b c d e f g h i j k l m n o p/; my $file="/tmp/foo.txt"; my (undef, undef, $mode, undef, $uid, $gid) = stat("$file"); $mode = sprintf( "%04o", $mode & 07777); my $tmp = File::Temp->new( TEMPLATE => 'tempXXXXX', DIR => '/tmp', SUFFIX => '.foobar', UNLINK => 1 ); chmod(oct($mode), $tmp) or die("Could not change tempfile to mode $mode.\n"); for my $d (@data) { print $tmp $d,"\n"; } rename($file, "$file.orig") or die("Could not rename original file, '$file': $!\n"); rename($tmp, "$file") or die("Could not rename temporary file handle: $!\n"); close($tmp); exit(0);