diff mbox

[libgfortran] Fix PR59108 ACTION='READ' is using O_CREAT

Message ID CAO9iq9EE+ig4FkrhnRREuWAp2nkHOWAm41amyAcu8B3cfRim9g@mail.gmail.com
State New
Headers show

Commit Message

Janne Blomqvist Nov. 15, 2013, 9:05 p.m. UTC
On Fri, Nov 15, 2013 at 9:11 PM, Jerry DeLisle <jvdelisle@charter.net> wrote:
> The attached patch sets the create flag for the case where action is specified
> as read only.

I was looking at this yesterday, but didn't have time to finish
everything then. So I made a similar patch, which also takes into
account the case where ACTION= is not specified and opening the file
with read-write fails and we fall back to trying to open read-only.

> I have confirmed that the PR test case now only produces:
>
> open("wombat", O_RDONLY)                = 3
> open("numbat", O_RDONLY)                = 4
> open("dingbat", O_RDONLY)               = 5

FWIW, I see you haven't updated recently; since a week ago you should
also see O_CLOEXEC (unless you have some old system).

My alternate patch attached. Regtested on x86_64-unknown-linux-gnu, Ok
for trunk?

2013-11-15  Janne Blomqvist  <jb@gcc.gnu.org>

    PR fortran/59108
    * io/unix.c (regular_file): Don't set O_CREAT when opening a file
    read-only with unknown status. Mask out O_CREAT when falling back
    to opening read-only if ACTION= is not set and read-write fails.

Comments

Jerry DeLisle Nov. 15, 2013, 9:46 p.m. UTC | #1
On 11/15/2013 01:05 PM, Janne Blomqvist wrote:
> On Fri, Nov 15, 2013 at 9:11 PM, Jerry DeLisle <jvdelisle@charter.net> wrote:
>> The attached patch sets the create flag for the case where action is specified
>> as read only.
> 
> I was looking at this yesterday, but didn't have time to finish
> everything then. So I made a similar patch, which also takes into
> account the case where ACTION= is not specified and opening the file
> with read-write fails and we fall back to trying to open read-only.
> 
>> I have confirmed that the PR test case now only produces:
>>
>> open("wombat", O_RDONLY)                = 3
>> open("numbat", O_RDONLY)                = 4
>> open("dingbat", O_RDONLY)               = 5
> 
> FWIW, I see you haven't updated recently; since a week ago you should
> also see O_CLOEXEC (unless you have some old system).

I also have the O_CLOEXEC, I just did not paste it in my message.

> 
> My alternate patch attached. Regtested on x86_64-unknown-linux-gnu, Ok
> for trunk?
> 

OK. Simple enough.

Jerry
diff mbox

Patch

diff --git a/libgfortran/io/unix.c b/libgfortran/io/unix.c
index 8a84ae4..c2bc28a 100644
--- a/libgfortran/io/unix.c
+++ b/libgfortran/io/unix.c
@@ -1245,7 +1245,7 @@  regular_file (st_parameter_open *opp, unit_flags *flags)
   char path[min(PATH_MAX, opp->file_len + 1)];
   int mode;
   int rwflag;
-  int crflag;
+  int crflag, crflag2;
   int fd;
   int err;
 
@@ -1297,8 +1297,6 @@  regular_file (st_parameter_open *opp, unit_flags *flags)
     }
 #endif
 
-  rwflag = 0;
-
   switch (flags->action)
     {
     case ACTION_READ:
@@ -1329,8 +1327,10 @@  regular_file (st_parameter_open *opp, unit_flags *flags)
       break;
 
     case STATUS_UNKNOWN:
-    case STATUS_SCRATCH:
-      crflag = O_CREAT;
+      if (rwflag == O_RDONLY)
+	crflag = 0;
+      else
+	crflag = O_CREAT;
       break;
 
     case STATUS_REPLACE:
@@ -1338,6 +1338,8 @@  regular_file (st_parameter_open *opp, unit_flags *flags)
       break;
 
     default:
+      /* Note: STATUS_SCRATCH is handled by tempfile () and should
+	 never be seen here.  */
       internal_error (&opp->common, "regular_file(): Bad status");
     }
 
@@ -1366,14 +1368,18 @@  regular_file (st_parameter_open *opp, unit_flags *flags)
 
   /* retry for read-only access */
   rwflag = O_RDONLY;
-  fd = open (path, rwflag | crflag, mode);
+  if (flags->status == STATUS_UNKNOWN)
+    crflag2 = crflag & ~(O_CREAT);
+  else
+    crflag2 = crflag;
+  fd = open (path, rwflag | crflag2, mode);
   if (fd >=0)
     {
       flags->action = ACTION_READ;
       return fd;		/* success */
     }
   
-  if (errno != EACCES)
+  if (errno != EACCES && errno != ENOENT)
     return fd;			/* failure */
 
   /* retry for write-only access */