https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89020

            Bug ID: 89020
           Summary: close(status='DELETE') does not remove file
           Product: gcc
           Version: 7.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libfortran
          Assignee: unassigned at gcc dot gnu.org
          Reporter: robison at arlut dot utexas.edu
  Target Milestone: ---

Version: GNU Fortran (Ubuntu 7.2.0-8ubuntu3.2) 7.2.0
OS: Guest Ubuntu running inside Host Windows 10 using VirtualBox

Problem:

CLOSE(status='DELETE',iostat=stat) does not delete some files, and still
returns iostat == 0.

In order to delete files, I use the OPEN(file=..) followed by
CLOSE(...,status='DELETE') pattern.  Normally this works, but
it fails on VirtualBox's shared folders.  Running strace shows
that the unlink syscall happens while the file is still open,
and returns ETXTBSY, but the close then proceeds as usual.
 Testing shows that other programs are unable to unlink the
file while the fortran program has it open either, although
they can safely unlink it after a CLOSE call.

strace output:
   openat(AT_FDCWD, "/mnt/f_drive/dummyfile.xxx", O_RDWR|O_CREAT|O_CLOEXEC,
0666) = 3
   fstat(3, {st_mode=S_IFREG|0777, st_size=16, ...}) = 0
   unlink("/mnt/f_drive/dummyfile.xxx")    = -1 ETXTBSY (Text file busy)
   close(3)

I would expect one of two outputs: either the fortran CLOSE statement to note
an error, or a second unlink() is attempted after the close() syscall is
performed. 

I additionally have tried a few variations of opening it readonly, etc, but
these have no effect.

I realize this is somewhat of a corner case, but makes me wonder about
other network-mounts, where filesystems can behave a little funny.
Also, because the close(...,status='delete') is the only pure-fortran
way I know how to delete a file, I think it sees pretty wide usage.

=========================
Example Program:
Warning! this program will attempt to delete the file you provide it.
 ./a.out /path/to/file_WILL_BE_DELETED
=========================

PROGRAM file_del
implicit none

character(len=256) :: fname
integer :: xstat
logical :: file_exists

call GET_COMMAND_ARGUMENT(1,fname,status=xstat)
if (xstat .ne. 0) then
    print *, 'Required argument: Filename to create and delete'
    stop
end if

inquire(file=fname, exist=file_exists)
if (.not. file_exists) then
    open(file=fname, unit=10, iostat=xstat)
    if (xstat .ne. 0) then
        print *,'Error creating file: ',trim(fname)
        error stop 1
    else
        write(10,*) 'Dummy contents'
        close(10)
    end if
end if

20 continue
inquire(file=fname, exist=file_exists)
if (file_exists) then
    open(file=fname, unit=10, iostat=xstat)
    if (xstat .eq. 0) then
        close(10, status='DELETE', iostat=xstat)
        print *,'Closing with DELETE:',xstat
    else
        print *,'Could not open for DELETE:',xstat
    end if
    goto 20
end if

END PROGRAM file_del

Reply via email to