Paul.Unix has asked for the wisdom of the Perl Monks concerning the following question:

I encountered an issue with IO::Compress::Gzip. After a successful gzip I want to unlink the original file but sometimes the unlink fails with a "permission denied" I made a pragmatic work around by adding a delay and try the unlink again. But a good solution would be preferred. The same issue happens with moving the new .gz to another directory. The files are not in use by another process. Running Strawberry Perl 5.22.0 on Windows 2008 and 2012
use warnings; use strict; use POSIX; use Cwd; use Cwd 'abs_path'; use Time::Local 'timelocal_nocheck'; # used for SCHEDULE option in +the MQX.ini use Net::Domain qw(hostname hostfqdn hostdomain domainname); use File::Basename; use File::Copy; use IO::Compress::Gzip qw(gzip $GzipError) ; use IO::Uncompress::Gunzip qw(gunzip $GunzipError) ; # module used in the state messages use Digest::MD5; # modules used in put mode use threads; use threads::shared; use Thread::Queue; if ( gzip $archfile => "$archfile.gz", AutoClose => 1, BinModeI +n => 1 ) { my $delete_try_counter = mqx_get_setting('ARCHIVEMOVETRY'); while ( -f $archfile and not unlink $archfile and $dele +te_try_counter != 0 ) { $global_EVENTLOG_IN_LQ->enqueue("WARNING, $arch_ha +shref->{'EVENTLOG'},Can not delete $archfile. Error: $! try: $delete_ +try_counter"); $delete_try_counter -= 1; sleep(mqx_get_setting('ARCHIVEMOVEWAIT')); # wait x sec +onds before retrying } $archfile .= ".gz"; # add .gz to the file name } else { # if the gzip failed try to arc +hive the original file $global_EVENTLOG_IN_LQ->enqueue("ERROR, $arch_hashref->{' +EVENTLOG'}, gzip failed on $archfile\n$GzipError"); }

Replies are listed 'Best First'.
Re: IO::Compress::Gzip file close issues
by SimonPratt (Friar) on Jul 26, 2016 at 14:33 UTC

    Collecting the return code and handling it is generally the best (safest) course of action. When you call out to external processes, they can take time to complete and the OS can also take time to learn that the process is no longer holding a file open.

    Without digging into the IO::Compress::Gzip sourcecode and without a working sample, my expectation is that Perl is hooking into gzip (either through the executable, or more likely through a related dll), so you are somewhat at the mercy of the external process.

Re: IO::Compress::Gzip file close issues
by pmqs (Friar) on Jul 26, 2016 at 22:44 UTC

    Under the hood IO::Compress::Gzip only uses Perl IO. It does use an extarnal library for the compression, but not for the IO.

    That means that once this line of your script has been run

    gzip $archfile => "$archfile.gz", AutoClose

    the file referenced by $archfile will have been closed. What is the value of $! when unlink fails?

    Also, does any other process have $archfile open? You cannot delete a file on windows if a proces has it open.

      The $! is "Permission denied". The second unlink after 2 seconds sleep succeeds. First I did not check on the unlink status and the same issue was with moving the newly created .gz file. I noticed that if the move of the .gz file failed also the unlink had failed. That is why it seems to me that the file close is not completed after the gzip yet.