From 6234b5433f65bf4d1aa1fe2485e7f77f393a860a Mon Sep 17 00:00:00 2001 From: Janne Blomqvist Date: Wed, 11 Mar 2015 23:34:22 +0200 Subject: [PATCH] PR 65200 Handle EPERM in addition to EACCES. gcc/fortran ChangeLog: 2015-03-11 Janne Blomqvist PR libfortran/65200 * gfortran.texi: Document behavior when opening files without explicit ACTION= specifier. libgfortran ChangeLog: 2015-03-11 Janne Blomqvist PR libfortran/65200 * io/open.c (new_unit): Use gf_strerror rather than hardcoding error messages for different errno values. * io/unix.c (regular_file2): Handle EPERM in addition to EACCES. gcc/testsuite ChangeLog: 2015-03-11 Janne Blomqvist PR libfortran/65200 * gfortran.dg/open_errors.f90: Update checks for iomsg string. * gfortran.dg/open_new_segv.f90: Fix error message pattern. From-SVN: r221361 --- gcc/fortran/ChangeLog | 6 +++++ gcc/fortran/gfortran.texi | 17 ++++++++++++ gcc/testsuite/ChangeLog | 6 +++++ gcc/testsuite/gfortran.dg/open_errors.f90 | 12 ++++++--- gcc/testsuite/gfortran.dg/open_new_segv.f90 | 4 +-- libgfortran/ChangeLog | 7 +++++ libgfortran/io/open.c | 30 +++------------------ libgfortran/io/unix.c | 4 +-- 8 files changed, 52 insertions(+), 34 deletions(-) diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index b9f34a33c67..d7d854389e6 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,9 @@ +2015-03-11 Janne Blomqvist + + PR libfortran/65200 + * gfortran.texi: Document behavior when opening files without + explicit ACTION= specifier. + 2015-03-10 Paul Thomas PR fortran/65024 diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi index 300b8b8440c..34999dbcf90 100644 --- a/gcc/fortran/gfortran.texi +++ b/gcc/fortran/gfortran.texi @@ -1139,6 +1139,7 @@ might in some way or another become visible to the programmer. * Internal representation of LOGICAL variables:: * Thread-safety of the runtime library:: * Data consistency and durability:: +* Files opened without an explicit ACTION= specifier:: @end menu @@ -1328,6 +1329,22 @@ releasing @code{fcntl} file locks, if the server supports them, will also force cache validation and flushing dirty data and metadata. +@node Files opened without an explicit ACTION= specifier +@section Files opened without an explicit ACTION= specifier +@cindex open, action + +The Fortran standard says that if an @code{OPEN} statement is executed +without an explicit @code{ACTION=} specifier, the default value is +processor dependent. GNU Fortran behaves as follows: + +@enumerate +@item Attempt to open the file with @code{ACTION='READWRITE'} +@item If that fails, try to open with @code{ACTION='READ'} +@item If that fails, try to open with @code{ACTION='WRITE'} +@item If that fails, generate an error +@end enumerate + + @c --------------------------------------------------------------------- @c Extensions @c --------------------------------------------------------------------- diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 139ae1c46a5..f0a759bcf88 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2015-03-11 Janne Blomqvist + + PR libfortran/65200 + * gfortran.dg/open_errors.f90: Update checks for iomsg string. + * gfortran.dg/open_new_segv.f90: Fix error message pattern. + 2015-03-11 Jakub Jelinek * c-c++-common/asan/no-asan-check-glob.c: Add -ffat-lto-objects diff --git a/gcc/testsuite/gfortran.dg/open_errors.f90 b/gcc/testsuite/gfortran.dg/open_errors.f90 index d6f1e430526..23d4b3d807b 100644 --- a/gcc/testsuite/gfortran.dg/open_errors.f90 +++ b/gcc/testsuite/gfortran.dg/open_errors.f90 @@ -2,6 +2,9 @@ ! PR30005 Enhanced error messages for OPEN ! Submitted by Jerry DeLisle ! See PR38956. Test fails on cygwin when user has Administrator rights +! As of the fix for PR 65200, the error message is partly generated by +! strerror*(), so can depend on the target and the locale, so check +! only the beginning of the error string, which should be constant. character(60) :: msg character(25) :: n = "temptestfile" logical :: there @@ -13,16 +16,17 @@ endif msg="" open(77,file=n,status="new", iomsg=msg, iostat=i) if (i == 0) call abort() -if (msg /= "File 'temptestfile' already exists") call abort() +if (msg(1:33) /= "Cannot open file 'temptestfile': ") call abort() open(77,file=n,status="old") close(77, status="delete") open(77,file=n,status="old", iomsg=msg, iostat=i) if (i == 0) call abort() -if (msg /= "File 'temptestfile' does not exist") call abort() +if (msg(1:33) /= "Cannot open file 'temptestfile': ") call abort() open(77,file="./", iomsg=msg, iostat=i) -if (msg /= "'./' is a directory" .and. msg /= "Invalid argument") call abort() +if (msg(1:23) /= "Cannot open file './': " & + .and. msg /= "Invalid argument") call abort() open(77,file=n,status="new") i = chmod(n, "-w") @@ -30,7 +34,7 @@ if (i == 0 .and. getuid() /= 0) then close(77, status="keep") open(77,file=n, iomsg=msg, iostat=i, action="write") if (i == 0) call abort() - if (msg /= "Permission denied trying to open file 'temptestfile'") call abort() + if (msg(1:33) /= "Cannot open file 'temptestfile': ") call abort() endif i = chmod(n,"+w") diff --git a/gcc/testsuite/gfortran.dg/open_new_segv.f90 b/gcc/testsuite/gfortran.dg/open_new_segv.f90 index fe548f1a196..d9f28718bda 100644 --- a/gcc/testsuite/gfortran.dg/open_new_segv.f90 +++ b/gcc/testsuite/gfortran.dg/open_new_segv.f90 @@ -1,5 +1,5 @@ ! { dg-do run } -! { dg-shouldfail "File already exists" } +! { dg-shouldfail "Cannot open file" } ! PR 64770 SIGSEGV when trying to open an existing file with status="new" program pr64770 implicit none @@ -10,5 +10,5 @@ program pr64770 status="new") end program pr64770 ! { dg-output "At line 10 of file.*" } -! { dg-output "Fortran runtime error: File .pr64770test.dat. already exists" } +! { dg-output "Fortran runtime error: Cannot open file .pr64770test.dat.:" } ! { dg-final { remote_file build delete "pr64770test.dat" } } diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index 184338aaede..97ee01b59fc 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,10 @@ +2015-03-11 Janne Blomqvist + + PR libfortran/65200 + * io/open.c (new_unit): Use gf_strerror rather than hardcoding + error messages for different errno values. + * io/unix.c (regular_file2): Handle EPERM in addition to EACCES. + 2015-03-10 Alessandro Fanfarillo Tobias Burnus diff --git a/libgfortran/io/open.c b/libgfortran/io/open.c index 0a2fda9d476..4654de27bd1 100644 --- a/libgfortran/io/open.c +++ b/libgfortran/io/open.c @@ -502,34 +502,12 @@ new_unit (st_parameter_open *opp, gfc_unit *u, unit_flags * flags) s = open_external (opp, flags); if (s == NULL) { + char errbuf[256]; char *path = fc_strdup (opp->file, opp->file_len); - size_t msglen = opp->file_len + 51; + size_t msglen = opp->file_len + 22 + sizeof (errbuf); char *msg = xmalloc (msglen); - - switch (errno) - { - case ENOENT: - snprintf (msg, msglen, "File '%s' does not exist", path); - break; - - case EEXIST: - snprintf (msg, msglen, "File '%s' already exists", path); - break; - - case EACCES: - snprintf (msg, msglen, - "Permission denied trying to open file '%s'", path); - break; - - case EISDIR: - snprintf (msg, msglen, "'%s' is a directory", path); - break; - - default: - free (msg); - msg = NULL; - } - + snprintf (msg, msglen, "Cannot open file '%s': %s", path, + gf_strerror (errno, errbuf, sizeof (errbuf))); generate_error (&opp->common, LIBERROR_OS, msg); free (msg); free (path); diff --git a/libgfortran/io/unix.c b/libgfortran/io/unix.c index 912364b56db..e5fc6e19818 100644 --- a/libgfortran/io/unix.c +++ b/libgfortran/io/unix.c @@ -1353,7 +1353,7 @@ regular_file2 (const char *path, st_parameter_open *opp, unit_flags *flags) flags->action = ACTION_READWRITE; return fd; } - if (errno != EACCES && errno != EROFS) + if (errno != EACCES && errno != EPERM && errno != EROFS) return fd; /* retry for read-only access */ @@ -1369,7 +1369,7 @@ regular_file2 (const char *path, st_parameter_open *opp, unit_flags *flags) return fd; /* success */ } - if (errno != EACCES && errno != ENOENT) + if (errno != EACCES && errno != EPERM && errno != ENOENT) return fd; /* failure */ /* retry for write-only access */ -- 2.30.2