From 11c6e12750b2fc86c16a7ee5554e864fbc4438d3 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Tue, 9 Jan 2024 10:32:29 +0900
Subject: [PATCH v8 1/5] Refactor code to check file file existence

jit.c and dfgr.c had a copy of the same code to check if a file exists
or not.  This refactored routine will be used by an upcoming patch.

Note that this adds a check on EACCES for the JIT path.
---
 src/include/storage/fd.h       |  1 +
 src/backend/jit/jit.c          | 20 +-------------------
 src/backend/storage/file/fd.c  | 22 ++++++++++++++++++++++
 src/backend/utils/fmgr/dfmgr.c | 25 ++++---------------------
 4 files changed, 28 insertions(+), 40 deletions(-)

diff --git a/src/include/storage/fd.h b/src/include/storage/fd.h
index c4c60bc0a8..60bba5c970 100644
--- a/src/include/storage/fd.h
+++ b/src/include/storage/fd.h
@@ -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);
diff --git a/src/backend/jit/jit.c b/src/backend/jit/jit.c
index 3f9848e726..d323c199ea 100644
--- a/src/backend/jit/jit.c
+++ b/src/backend/jit/jit.c
@@ -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;
-}
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index 8917c6004a..c3585ced34 100644
--- a/src/backend/storage/file/fd.c
+++ b/src/backend/storage/file/fd.c
@@ -493,6 +493,28 @@ retry:
 	return rc;
 }
 
+/*
+ * pg_file_exists -- check that a given file exists.
+ *
+ * This requires an absolute path to the file.
+ */
+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
  *
diff --git a/src/backend/utils/fmgr/dfmgr.c b/src/backend/utils/fmgr/dfmgr.c
index 638eddf19f..eafa0128ef 100644
--- a/src/backend/utils/fmgr/dfmgr.c
+++ b/src/backend/utils/fmgr/dfmgr.c
@@ -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);
-- 
2.43.0

