Refactor code checking for file existence
authorMichael Paquier <michael@paquier.xyz>
Fri, 12 Jan 2024 03:04:51 +0000 (12:04 +0900)
committerMichael Paquier <michael@paquier.xyz>
Fri, 12 Jan 2024 03:04:51 +0000 (12:04 +0900)
jit.c and dfgr.c had a copy of the same code to check if a file exists
or not, with a twist: jit.c did not check for EACCES when failing the
stat() call for the path whose existence is tested.  This refactored
routine will be used by an upcoming patch.

Reviewed-by: Ashutosh Bapat
Discussion: https://postgr.es/m/ZTiV8tn_MIb_H2rE@paquier.xyz

src/backend/jit/jit.c
src/backend/storage/file/fd.c
src/backend/utils/fmgr/dfmgr.c
src/include/storage/fd.h

index 3f9848e726b011a7e000d729cb5dd5d59175831f..d323c199eaa21bb47530a272a29ce498d8d66fb8 100644 (file)
@@ -45,7 +45,6 @@ static bool provider_failed_loading = false;
 
 
 static bool provider_init(void);
-static bool file_exists(const char *name);
 
 
 /*
@@ -89,7 +88,7 @@ provider_init(void)
     */
    snprintf(path, MAXPGPATH, "%s/%s%s", pkglib_path, jit_provider, DLSUFFIX);
    elog(DEBUG1, "probing availability of JIT provider at %s", path);
-   if (!file_exists(path))
+   if (!pg_file_exists(path))
    {
        elog(DEBUG1,
             "provider not available, disabling JIT for current session");
@@ -188,20 +187,3 @@ InstrJitAgg(JitInstrumentation *dst, JitInstrumentation *add)
    INSTR_TIME_ADD(dst->optimization_counter, add->optimization_counter);
    INSTR_TIME_ADD(dst->emission_counter, add->emission_counter);
 }
-
-static bool
-file_exists(const char *name)
-{
-   struct stat st;
-
-   Assert(name != NULL);
-
-   if (stat(name, &st) == 0)
-       return !S_ISDIR(st.st_mode);
-   else if (!(errno == ENOENT || errno == ENOTDIR))
-       ereport(ERROR,
-               (errcode_for_file_access(),
-                errmsg("could not access file \"%s\": %m", name)));
-
-   return false;
-}
index 8917c6004ace0de98fb6e5bdf3b7cb3e597ccd4f..43d2b2a156e11b0b93c0c41ae241c376013d365d 100644 (file)
@@ -493,6 +493,29 @@ retry:
    return rc;
 }
 
+/*
+ * pg_file_exists -- check that a file exists.
+ *
+ * This requires an absolute path to the file.  Returns true if the file is
+ * not a directory, false otherwise.
+ */
+bool
+pg_file_exists(const char *name)
+{
+   struct stat st;
+
+   Assert(name != NULL);
+
+   if (stat(name, &st) == 0)
+       return !S_ISDIR(st.st_mode);
+   else if (!(errno == ENOENT || errno == ENOTDIR || errno == EACCES))
+       ereport(ERROR,
+               (errcode_for_file_access(),
+                errmsg("could not access file \"%s\": %m", name)));
+
+   return false;
+}
+
 /*
  * pg_flush_data --- advise OS that the described dirty data should be flushed
  *
index 638eddf19f43e19a98fcf95d14977ad3baa71d7f..eafa0128ef05678e9e4d44b41a439a4b71417c43 100644 (file)
@@ -33,6 +33,7 @@
 #include "fmgr.h"
 #include "lib/stringinfo.h"
 #include "miscadmin.h"
+#include "storage/fd.h"
 #include "storage/shmem.h"
 #include "utils/hsearch.h"
 
@@ -78,7 +79,6 @@ char     *Dynamic_library_path;
 static void *internal_load_library(const char *libname);
 static void incompatible_module_error(const char *libname,
                                      const Pg_magic_struct *module_magic_data) pg_attribute_noreturn();
-static bool file_exists(const char *name);
 static char *expand_dynamic_library_name(const char *name);
 static void check_restricted_library_name(const char *name);
 static char *substitute_libpath_macro(const char *name);
@@ -400,23 +400,6 @@ incompatible_module_error(const char *libname,
             errdetail_internal("%s", details.data)));
 }
 
-static bool
-file_exists(const char *name)
-{
-   struct stat st;
-
-   Assert(name != NULL);
-
-   if (stat(name, &st) == 0)
-       return !S_ISDIR(st.st_mode);
-   else if (!(errno == ENOENT || errno == ENOTDIR || errno == EACCES))
-       ereport(ERROR,
-               (errcode_for_file_access(),
-                errmsg("could not access file \"%s\": %m", name)));
-
-   return false;
-}
-
 
 /*
  * If name contains a slash, check if the file exists, if so return
@@ -447,7 +430,7 @@ expand_dynamic_library_name(const char *name)
    else
    {
        full = substitute_libpath_macro(name);
-       if (file_exists(full))
+       if (pg_file_exists(full))
            return full;
        pfree(full);
    }
@@ -465,7 +448,7 @@ expand_dynamic_library_name(const char *name)
    {
        full = substitute_libpath_macro(new);
        pfree(new);
-       if (file_exists(full))
+       if (pg_file_exists(full))
            return full;
        pfree(full);
    }
@@ -582,7 +565,7 @@ find_in_dynamic_libpath(const char *basename)
 
        elog(DEBUG3, "find_in_dynamic_libpath: trying \"%s\"", full);
 
-       if (file_exists(full))
+       if (pg_file_exists(full))
            return full;
 
        pfree(full);
index c4c60bc0a8481a22ecd970b12d16125b322b97a6..60bba5c97080c938c070646d1393f0d738e5881e 100644 (file)
@@ -182,6 +182,7 @@ extern int  pg_fsync(int fd);
 extern int pg_fsync_no_writethrough(int fd);
 extern int pg_fsync_writethrough(int fd);
 extern int pg_fdatasync(int fd);
+extern bool pg_file_exists(const char *fname);
 extern void pg_flush_data(int fd, off_t offset, off_t nbytes);
 extern int pg_truncate(const char *path, off_t length);
 extern void fsync_fname(const char *fname, bool isdir);