aboutsummaryrefslogtreecommitdiff
path: root/libgfortran
diff options
context:
space:
mode:
authorThomas Koenig <Thomas.Koenig@online.de>2005-01-22 19:49:18 +0000
committerPaul Brook <paul@codesourcery.com>2005-01-22 19:49:18 +0000
commitd5ee64eaf23ed94487c418170e0aef5a9a3ecfd3 (patch)
treefda79f894c069363a2ace1fa2cd36b81203001de /libgfortran
parentc5112bfa950ddc109f94e25265914252a393ab84 (diff)
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. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@94076 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgfortran')
-rw-r--r--libgfortran/ChangeLog13
-rw-r--r--libgfortran/io/unix.c71
2 files changed, 54 insertions, 30 deletions
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog
index 95242b6396b..537415f16fe 100644
--- a/libgfortran/ChangeLog
+++ b/libgfortran/ChangeLog
@@ -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
diff --git a/libgfortran/io/unix.c b/libgfortran/io/unix.c
index e174e3be9ca..daa0fb11072 100644
--- a/libgfortran/io/unix.c
+++ b/libgfortran/io/unix.c
@@ -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);
}