file set contents: fix error handling with or-operator precedence

In perl the `or` and the `||` operator do mostly the same thing but
with a different precedence level [0].

A statement like:
`$foo += bar() or die "error"`
is basically equivalent to:
`($foo += bar()) or die "error"`

That means as long as bar only returns zero or positive integers the
`or die` can only happen the first time, as otherwise $foo is bigger
than zero and thus will never evaluate to false. This can be
reproduced by perl -we 'my $foo = 1; $foo += 0 or die "wont happen";'

While one could switch to the `||` operator, this is a bit to subtle,
so to fix this, separate tracking the total bytes written from getting
the bytes written by the current call, this avoids the error potential
completely.

[0]: https://perldoc.perl.org/perlop#Logical-or-and-Exclusive-Or

Reported-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
This commit is contained in:
Thomas Lamprecht 2024-10-14 11:02:51 +02:00
parent ef0bcc98ad
commit f1fe7a0733

View File

@ -299,8 +299,9 @@ sub file_set_contents {
my $len = length($data);
while ($offset < $len) {
$offset += syswrite($fh, $data, $len - $offset, $offset)
my $written_bytes = syswrite($fh, $data, $len - $offset, $offset)
or die "unable to write '$tmpname' - $!\n";
$offset += $written_bytes;
}
close $fh or die "closing file '$tmpname' failed - $!\n";