OSDN Git Service

2005-01-22 Thomas Koenig <Thomas.Koenig@online.de>
authorpbrook <pbrook@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 22 Jan 2005 19:49:18 +0000 (19:49 +0000)
committerpbrook <pbrook@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 22 Jan 2005 19:49:18 +0000 (19:49 +0000)
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: svn+ssh://gcc.gnu.org/svn/gcc/trunk@94076 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/open_new.f90 [new file with mode: 0644]
libgfortran/ChangeLog
libgfortran/io/unix.c

index 7115b35..b39fb69 100644 (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.
diff --git a/gcc/testsuite/gfortran.dg/open_new.f90 b/gcc/testsuite/gfortran.dg/open_new.f90
new file mode 100644 (file)
index 0000000..9e9c951
--- /dev/null
@@ -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
index 95242b6..537415f 100644 (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
index e174e3b..daa0fb1 100644 (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);
     }