-
-
Notifications
You must be signed in to change notification settings - Fork 163
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,7 +5,7 @@ | |
# | ||
use strict; | ||
use feature 'state'; | ||
use Fcntl ':flock'; | ||
use Fcntl qw(:flock O_RDWR O_CREAT); | ||
|
||
our $json; | ||
eval "use JSON::XS"; | ||
|
@@ -78,38 +78,59 @@ sub stats_read_file_contents { | |
# Write file contents | ||
sub stats_write_file_contents { | ||
my ($filename, $contents) = @_; | ||
# Open file for writing | ||
my $fh; | ||
if (!open($fh, '>', $filename)) { | ||
error_stderr("Failed to open file '$filename' for writing: $!"); | ||
return 0; | ||
} | ||
# Acquire lock the file for writing | ||
if (!flock($fh, LOCK_EX)) { | ||
error_stderr("Failed to acquire exclusive lock on file '$filename': $!"); | ||
close($fh); | ||
my $cleanup = sub { | ||
my ($fh, $unlock, $success) = @_; | ||
# Unlock the file. Not strictly necessary as Perl | ||
# automatically releases locks on file closure | ||
flock($fh, LOCK_UN) if ($unlock); | ||
# Close file handle | ||
close($fh) | ||
or do { | ||
error_stderr("Failed to close file '$filename': $!"); | ||
undef($fh); | ||
return 0; | ||
}; | ||
# Release memory. Generally not necessary as Perl's garbage collection | ||
# should always handle this. However, it doesn't hurt and can be | ||
# useful in certain scenarios, like long-running processes | ||
undef($fh); | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
iliajie
Author
Collaborator
|
||
return 0; | ||
} | ||
# Return result | ||
return $success ? 1 : 0; | ||
}; | ||
# Open file for reading and writing without truncating it, or | ||
# create it if it doesn't exist | ||
sysopen(my $fh, $filename, O_RDWR | O_CREAT) | ||
or do { | ||
error_stderr("Failed to open file '$filename' for reading and writing: $!"); | ||
return 0; | ||
}; | ||
# Acquire exclusive lock on the file for writing | ||
flock($fh, LOCK_EX) | ||
or do { | ||
error_stderr("Failed to acquire exclusive lock on file '$filename': $!"); | ||
return $cleanup->($fh, 0); | ||
}; | ||
# Truncate the file after acquiring the lock | ||
This comment has been minimized.
Sorry, something went wrong.
jcameron
Collaborator
|
||
truncate($fh, 0) | ||
or do { | ||
error_stderr("Failed to truncate file '$filename': $!"); | ||
return $cleanup->($fh, 1); | ||
}; | ||
# Reset the file pointer to the beginning of the file | ||
# preventing potential race conditions | ||
seek($fh, 0, 0) | ||
This comment has been minimized.
Sorry, something went wrong.
jcameron
Collaborator
|
||
or do { | ||
error_stderr("Failed to seek to the beginning of file '$filename': $!"); | ||
return $cleanup->($fh, 1); | ||
}; | ||
# Write to file | ||
if (!print($fh $contents)) { | ||
error_stderr("Failed to write to file '$filename': $!"); | ||
close($fh); | ||
undef($fh); | ||
return 0; | ||
} | ||
# Unlock the file | ||
flock($fh, LOCK_UN); | ||
# Close file | ||
if (!close($fh)) { | ||
error_stderr("Failed to close file '$filename': $!"); | ||
undef($fh); | ||
return 0; | ||
} | ||
# Release memory | ||
undef($fh); | ||
# Return success | ||
return 1; | ||
print($fh $contents) | ||
or do { | ||
error_stderr("Failed to write to file '$filename': $!"); | ||
return $cleanup->($fh, 1); | ||
}; | ||
# Clean up and return success | ||
return $cleanup->($fh, 1, 1); | ||
} | ||
|
||
# Check if feature is enabled | ||
|
How does setting $fh to undef do anything if it's a local variable?