re PR libfortran/18982 (open(status="new") does not generate an error if the file exists)

2005-01-22  Thomas Koenig  <Thomas.Koenig@online.de>

	PR libfortran/18982
	* io/unix.c (regular_file):  No need to change flags->action
	if an error occurs.  Document this.
	No need to call stat() for STATUS_OLD, open() will
	fail anyway.
	For ACTION_UNSPECIFIED, try open for read-write, then for
	read-only if open fails with EACCES, then for write-only
	if that fails with EACCES again.
	* io/unix.c (open_external): Document changed behavior of
	regular_file.
testsuite/
	* gfortran.dg/open_new.f90: New file.

From-SVN: r94076
This commit is contained in:
Thomas Koenig 2005-01-22 19:49:18 +00:00 committed by Paul Brook
parent d7c71ee3e6
commit d02b2c6474
4 changed files with 70 additions and 30 deletions

View File

@ -1,3 +1,8 @@
2005-01-22 Thomas Koenig <Thomas.Koenig@online.de>
PR libfortran/18982
* gfortran.dg/open_new.f90: New file.
2005-01-22 Paul Brook <paul@codesourcery.com>
* namelist_1.f90: New test.

View File

@ -0,0 +1,11 @@
! { dg do-run }
! PR 18982: verifies that opening an existing file with
! status="new" is an error
program main
nout = 10
open(nout, file="foo.dat", status="replace") ! make sure foo.dat exists
close(nout)
open(nout, file="foo.dat", status="new",err=100)
call abort ! This should never happen
100 continue
end program main

View File

@ -1,3 +1,16 @@
2005-01-22 Thomas Koenig <Thomas.Koenig@online.de>
PR libfortran/18982
* io/unix.c (regular_file): No need to change flags->action
if an error occurs. Document this.
No need to call stat() for STATUS_OLD, open() will
fail anyway.
For ACTION_UNSPECIFIED, try open for read-write, then for
read-only if open fails with EACCES, then for write-only
if that fails with EACCES again.
* io/unix.c (open_external): Document changed behavior of
regular_file.
2005-01-22 Tobias Schl"uter <tobias.schlueter@physik.uni-muenchen.de>
PR fortran/19194

View File

@ -998,16 +998,17 @@ tempfile (void)
/* regular_file()-- Open a regular file.
* Change flags->action if it is ACTION_UNSPECIFIED on entry.
* Change flags->action if it is ACTION_UNSPECIFIED on entry,
* unless an error occurs.
* Returns the descriptor, which is less than zero on error. */
static int
regular_file (unit_flags *flags)
{
char path[PATH_MAX + 1];
struct stat statbuf;
int mode;
int rwflag;
int crflag;
int fd;
if (unpack_filename (path, ioparm.file, ioparm.file_len))
@ -1040,21 +1041,20 @@ regular_file (unit_flags *flags)
switch (flags->status)
{
case STATUS_NEW:
rwflag |= O_CREAT | O_EXCL;
crflag = O_CREAT | O_EXCL;
break;
case STATUS_OLD: /* file must exist, so check for its existence */
if (stat (path, &statbuf) < 0)
return -1;
case STATUS_OLD: /* open will fail if the file does not exist*/
crflag = 0;
break;
case STATUS_UNKNOWN:
case STATUS_SCRATCH:
rwflag |= O_CREAT;
crflag = O_CREAT;
break;
case STATUS_REPLACE:
rwflag |= O_CREAT | O_TRUNC;
crflag = O_CREAT | O_TRUNC;
break;
default:
@ -1064,29 +1064,39 @@ regular_file (unit_flags *flags)
/* rwflag |= O_LARGEFILE; */
mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
fd = open (path, rwflag, mode);
if (flags->action == ACTION_UNSPECIFIED)
fd = open (path, rwflag | crflag, mode);
if (flags->action != ACTION_UNSPECIFIED)
return fd;
if (fd >= 0)
{
if (fd < 0)
{
rwflag = rwflag & !O_RDWR | O_RDONLY;
fd = open (path, rwflag, mode);
if (fd < 0)
{
rwflag = rwflag & !O_RDONLY | O_WRONLY;
fd = open (path, rwflag, mode);
if (fd < 0)
flags->action = ACTION_READWRITE; /* Could not open at all. */
else
flags->action = ACTION_WRITE;
}
else
flags->action = ACTION_READ;
}
else
flags->action = ACTION_READWRITE;
flags->action = ACTION_READWRITE;
return fd;
}
return fd;
if (errno != EACCES)
return fd;
/* retry for read-only access */
rwflag = O_RDONLY;
fd = open (path, rwflag | crflag, mode);
if (fd >=0)
{
flags->action = ACTION_READ;
return fd; /* success */
}
if (errno != EACCES)
return fd; /* failure */
/* retry for write-only access */
rwflag = O_WRONLY;
fd = open (path, rwflag | crflag, mode);
if (fd >=0)
{
flags->action = ACTION_WRITE;
return fd; /* success */
}
return fd; /* failure */
}
@ -1109,7 +1119,8 @@ open_external (unit_flags *flags)
}
else
{
/* regular_file resets flags->action if it is ACTION_UNSPECIFIED. */
/* regular_file resets flags->action if it is ACTION_UNSPECIFIED and
* if it succeeds */
fd = regular_file (flags);
}