velocitygirl13 has asked for the wisdom of the Perl Monks concerning the following question:

Hi everyone. I'm new here. I have a question. I have a Perl script which runs perfectly in a Unix environment. However, when I run it in windows, I get an error that the temp file the script creates cannot be deleted because "Permission Denied". I tweaked my Windows permissions and gave every last user on my system full access to the temp directory where the temp files are created. I ran the script again and I still get permission denied. I seem to think that for some reason Windows or Perl is not honoring the close command I have in the script which causes the file to stay open and not be able to be deleted. The script creates the temp directory and files with no issues which means the script can write to the temp directory. It just can't delete the files it put there. The following is the snip of relevant code with some notes from me. My notes are in CAPS so you guys will know they are not part of the script. Thanks in advance for your help.

THIS WORKS WITHOUT ISSUE:
# create our temp file, $filename will contain the full path
my ($fh, $filename) = tempfile( DIR => $self->{Temp_Dir} );

THIS WORKS WITHOUT ISSUE:
# spew our mail into the temp file
my $SNF_fh = IO::File->new( $filename, "w" ) ||
die(__PACKAGE__ . ": Unable to create temporary file '" . $filename . "'");

THIS WORKS WITHOUT ISSUE:
$SNF_fh->print($mailtext) ||
$self->cleanup_die($filename,
__PACKAGE__ . ": Unable to write to temporary file '" .
$filename . "'");

THIS SEEMS WORKS WITHOUT ISSUE, BUT I'M NOT SURE. I'M NOT GETTING ANY ERRORS THAT SAYS IT'S NOT WORKING:
$SNF_fh->close ||
$self->cleanup_die($filename,
__PACKAGE__ . ": Unable to close temporary file '" .
$filename . "'");

THIS WORKS WITHOUT ISSUE:
#Change permissions.
my $cnt = chmod(0777, $filename) ||
$self->cleanup_die($filename, __PACKAGE__ .
": Unable to change permissions of temporary file '" .
$filename . "'");

THIS IS NOT WORKING. THIS IS WHERE I GET PERMISSION DENIED:
# Remove the temp file, we are done with it.
unlink ($filename) ||
$self->cleanup_die($filename,
__PACKAGE__ . ": Unable to delete temporary file '" .
$filename . "' because $!");

Replies are listed 'Best First'.
Re: Close command not being honored
by Corion (Patriarch) on Feb 21, 2014 at 15:24 UTC

    On Windows, you cannot delete, rename or do much of anything with a file if a filehandle to that file is open.

    In your first line of code, you open a filehandle to your tempfile when calling

    my ($fh, $filename) = tempfile( DIR => $self->{Temp_Dir} );

    You then never close $fh, which makes Windows deny your request to delete $filename.

    Simply close the filehandle if you only want the name.

      That is only the default behavior [when using one of the Unixy wrappers like fopen()]. You can use Win32API::File to open a file in a way that allows you to rename or delete it while you still have it open.

      - tye        

      Thanks Corion. I didn't write this script. I really don't know anything about Perl to be honest with you. However, I was under the impression that this command was to close the filehandle:

      $SNF_fh->close ||

      If not, what does that command do? Also, What is the correct line of code to use to close the filehandle that was open? Again, thank you so much for your response.

        The code

        $SNF_fh->close

        closes the filehandle $SNF_fh.

        But further up, the call to tempfile returns a filehandle that you store in the variable $fh. You never show where $fh is closed.

        If you are not interested in the filehandle and only in the name of the tempfile, immediately closing the filehandle returning from it is the sanest approach:

        my ($fh, $filename) = tempfile( DIR => $self->{Temp_Dir} ); close $fh; # we only want the filename
Re: Close command not being honored
by walto (Pilgrim) on Feb 21, 2014 at 15:23 UTC
    Are you sure the filehandle is closed?
    To handle temp files safely have a look at File::Temp
      Hi Walto. No, I'm not sure at all. I will have a look at that doc. Thanks!