in reply to What if FILE deleted during WHILE read-in loop?

It does vary by operating system. As others have mentioned, on Unix-type systems it works the way you've observed. On Win32, at least in my experience (unless there's some secret API I don't know about), it's simply not possible to delete a file that is opened by another (or the same, for that matter) process. This is the sort of semantic difference between OS's that no programming language can make up for. Of course, the authors of Perl being the nice people they are, have documented this in perlport :
Some platforms can’t delete or rename files held open by the system, this limitation may also apply to changing filesystem metainformation like file permissions or owners. Remember to "close" files when you are done with them. Don’t "unlink" or "rename" an open file. Don’t "tie" or "open" a file already tied or opened; "untie" or "close" it first.
  • Comment on Re: What if FILE deleted during WHILE read-in loop?

Replies are listed 'Best First'.
Re^2: What if FILE deleted during WHILE read-in loop?
by ikegami (Patriarch) on May 13, 2006 at 08:27 UTC

    Actually, it is possible. Kinda. If you set the right share permission, the file can be deleted. Actually, it only gets flagged as being deleted. The file still appears in the directory until all file handles to it are closed. Open file handles still function. New handles can't be created. ("Access denied".)

    For example,

    use Win32API::File qw( createFile ReadFile CloseHandle ); $|=1; my $share = $ARGV[0]; print("share: $share\n"); { open(my $fh, '>', 'deleteme') or die("Unable to create file: $!\n"); print $fh ("foo\n"); } { my $h = createFile('deleteme', 'r', $share) or die("Unable to open file: $^E\n"); { ReadFile($h, my $buf, 1, [], []) or die("Unable to read from file: $^E\n"); print("Read $buf\n"); } print("pre unlink dir: "); system('dir /b deleteme'); print("pre unlink type: "); system('type deleteme'); if (unlink('deleteme')) { print("File deleted\n"); } else { print("Unable to delete file\n"); } print("post unlink dir: "); system('dir /b deleteme'); print("post unlink type: "); system('type deleteme'); { ReadFile($h, my $buf, 1, [], []) or die("Unable to read from file: $^E\n"); print("Read $buf\n"); } print("pre CloseHandle dir: "); system('dir /b deleteme'); print("pre CloseHandle type: "); system('type deleteme'); CloseHandle($h); print("post CloseHandle dir: "); system('dir /b deleteme'); print("post CloseHandle type: "); system('type deleteme'); }

    outputs

    >perl 549202.pl rw share: rw Read f pre unlink dir: deleteme pre unlink type: foo Unable to delete file <--- post unlink dir: deleteme post unlink type: foo Read o pre CloseHandle dir: deleteme pre CloseHandle type: foo post CloseHandle dir: deleteme post CloseHandle type: foo >perl 549202.pl rwd share: rwd Read f pre unlink dir: deleteme pre unlink type: foo File deleted <--- post unlink dir: deleteme post unlink type: Access is denied. Read o pre CloseHandle dir: deleteme pre CloseHandle type: Access is denied. post CloseHandle dir: File Not Found post CloseHandle type: The system cannot find the file specified.