From d5ee64eaf23ed94487c418170e0aef5a9a3ecfd3 Mon Sep 17 00:00:00 2001 From: Thomas Koenig Date: Sat, 22 Jan 2005 19:49:18 +0000 Subject: 2005-01-22 Thomas Koenig 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 --- libgfortran/ChangeLog | 13 ++++++++++ libgfortran/io/unix.c | 71 +++++++++++++++++++++++++++++---------------------- 2 files changed, 54 insertions(+), 30 deletions(-) (limited to 'libgfortran') 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 + + 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 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); } -- cgit v1.2.3