This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch, libfortran] Use access(2) instead of stat(2) to test file existence


Hello,

this simple patch uses access(2) instead of stat(2) in the
file_exists() function used to test whether a file pathname exists.
The reason why this is better is because stat() is potentially a
heavyweight operation (as those who have waited half an hour for 'ls
-l' to complete on a distributed fs such as Lustre can attest). This
does not change any the behavior for any corner cases such as dangling
symlinks (see PR 41387), as both access(2) and stat(2) will follow
symlinks.

As an aside, we seem to be quite happily using stat(2). One way to
reduce it would be to cache the device and inode numbers for open
units; as Fortran apparently forbids having multiple units pointing to
the same file (?), every time we open a file we walk through all
existing units and compare device and inode numbers.

Regtested on x86_64-unknown-linux-gnu, ok for trunk?

-- 
Janne Blomqvist

Attachment: ChangeLog
Description: Binary data

diff --git a/libgfortran/io/unix.c b/libgfortran/io/unix.c
index eea03ba..a2903af 100644
--- a/libgfortran/io/unix.c
+++ b/libgfortran/io/unix.c
@@ -131,6 +131,46 @@ typedef struct stat gfstat_t;
 #endif
 
 
+#ifndef HAVE_ACCESS
+
+#ifndef W_OK
+#define W_OK 2
+#endif
+
+#ifndef R_OK
+#define R_OK 4
+#endif
+
+#ifndef F_OK
+#define F_OK 0
+#endif
+
+/* Fallback implementation of access() on systems that don't have it.
+   Only modes R_OK, W_OK and F_OK are used in this file.  */
+
+static int
+fallback_access (const char *path, int mode)
+{
+  if ((mode & R_OK) && open (path, O_RDONLY) < 0)
+    return -1;
+
+  if ((mode & W_OK) && open (path, O_WRONLY) < 0)
+    return -1;
+
+  if (mode == F_OK)
+    {
+      gfstat_t st;
+      return stat (path, &st);
+    }
+
+  return 0;
+}
+
+#undef access
+#define access fallback_access
+#endif
+
+
 /* Unix and internal stream I/O module */
 
 static const int BUFFER_SIZE = 8192;
@@ -1580,15 +1620,11 @@ int
 file_exists (const char *file, gfc_charlen_type file_len)
 {
   char path[PATH_MAX + 1];
-  gfstat_t statbuf;
 
   if (unpack_filename (path, file, file_len))
     return 0;
 
-  if (stat (path, &statbuf) < 0)
-    return 0;
-
-  return 1;
+  return !(access (path, F_OK));
 }
 
 
@@ -1695,36 +1731,6 @@ inquire_unformatted (const char *string, int len)
 }
 
 
-#ifndef HAVE_ACCESS
-
-#ifndef W_OK
-#define W_OK 2
-#endif
-
-#ifndef R_OK
-#define R_OK 4
-#endif
-
-/* Fallback implementation of access() on systems that don't have it.
-   Only modes R_OK and W_OK are used in this file.  */
-
-static int
-fallback_access (const char *path, int mode)
-{
-  if ((mode & R_OK) && open (path, O_RDONLY) < 0)
-    return -1;
-
-  if ((mode & W_OK) && open (path, O_WRONLY) < 0)
-    return -1;
-
-  return 0;
-}
-
-#undef access
-#define access fallback_access
-#endif
-
-
 /* inquire_access()-- Given a fortran string, determine if the file is
  * suitable for access. */
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]