[patch, libgfortran] Fix for PR 18982

Thomas Koenig Thomas.Koenig@online.de
Mon Jan 17 20:58:00 GMT 2005


Here's another go at fixing PR 18982.

Testcase is also attached.

Ok?

2005-01-17  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.
	
-------------- next part --------------
Index: unix.c
===================================================================
RCS file: /cvsroot/gcc/gcc/libgfortran/io/unix.c,v
retrieving revision 1.19
diff -c -r1.19 unix.c
*** unix.c	12 Jan 2005 21:27:31 -0000	1.19
--- unix.c	17 Jan 2005 20:44:21 -0000
***************
*** 998,1013 ****
  
  
  /* regular_file()-- Open a regular file.
!  * Change flags->action if it is ACTION_UNSPECIFIED on entry.
   * 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 fd;
  
    if (unpack_filename (path, ioparm.file, ioparm.file_len))
--- 998,1014 ----
  
  
  /* regular_file()-- Open a regular file.
!  * 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];
    int mode;
    int rwflag;
+   int crflag;
    int fd;
  
    if (unpack_filename (path, ioparm.file, ioparm.file_len))
***************
*** 1040,1060 ****
    switch (flags->status)
      {
      case STATUS_NEW:
!       rwflag |= O_CREAT | O_EXCL;
        break;
  
!     case STATUS_OLD:		/* file must exist, so check for its existence */
!       if (stat (path, &statbuf) < 0)
! 	return -1;
        break;
  
      case STATUS_UNKNOWN:
      case STATUS_SCRATCH:
!       rwflag |= O_CREAT;
        break;
  
      case STATUS_REPLACE:
!         rwflag |= O_CREAT | O_TRUNC;
        break;
  
      default:
--- 1041,1060 ----
    switch (flags->status)
      {
      case STATUS_NEW:
!       crflag = O_CREAT | O_EXCL;
        break;
  
!     case STATUS_OLD:		/* open will fail if the file does not exist*/
!       crflag = 0;
        break;
  
      case STATUS_UNKNOWN:
      case STATUS_SCRATCH:
!       crflag = O_CREAT;
        break;
  
      case STATUS_REPLACE:
!         crflag = O_CREAT | O_TRUNC;
        break;
  
      default:
***************
*** 1064,1092 ****
    /* 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)
      {
!       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;
      }
!   return fd;
  }
  
  
--- 1064,1102 ----
    /* rwflag |= O_LARGEFILE; */
  
    mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
!   fd = open (path, rwflag | crflag, mode);
!   if (flags->action != ACTION_UNSPECIFIED)
!       return fd;
! 
!   if (fd >= 0)
      {
!       flags->action = ACTION_READWRITE;
!       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,1115 ****
      }
    else
      {
!       /* regular_file resets flags->action if it is ACTION_UNSPECIFIED.  */
        fd = regular_file (flags);
      }
  
--- 1119,1126 ----
      }
    else
      {
!       /* regular_file resets flags->action if it is ACTION_UNSPECIFIED and
!        * if it succeeds */
        fd = regular_file (flags);
      }
  
-------------- next part --------------
! { 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


More information about the Gcc-patches mailing list