From a28f1177901506aa32aafda987fc643dfefcbb8b Mon Sep 17 00:00:00 2001
From: Bruce Momjian <bruce@momjian.us>
Date: Fri, 12 May 2000 18:51:59 +0000
Subject: [PATCH] This is the second time I've answered this exact same problem
 in two days.  It seems to be a FAQ, and I think I know why. When creating a
 'c' language function, CREATE FUNCTION is fed the shared object filename, and
 seems to succeed. Only when trying to use the function is an error thrown, by
 which time the coder thinks something's wrong with executing the code, not
 with loading it.

I think I once saw it proposed to load shared objects at function creation
time, but that idea was shot down on the grounds of resident memory bloat,
ISTR. Here's a patch for a compromise: all it does is stat() the file,
just like the loader code does, so that the errors caused by non existent
files, and no directory 'x' permissions (the most common ones, it seems),
get caught while the developer is still thinking about code loading. It
doesn't catch all errors (like the code not being readable by the postgres
user) but seems to catch the most common, without actually opening the file.

What do you think?

Ross
---
 src/backend/commands/define.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/src/backend/commands/define.c b/src/backend/commands/define.c
index b7e7edd3736..5bc75faaec7 100644
--- a/src/backend/commands/define.c
+++ b/src/backend/commands/define.c
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.41 2000/04/13 11:51:07 wieck Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.42 2000/05/12 18:51:59 momjian Exp $
  *
  * DESCRIPTION
  *	  The "DefineFoo" routines take the parse tree and pick out the
@@ -35,6 +35,8 @@
  */
 #include <ctype.h>
 #include <math.h>
+#include <sys/stat.h>
+
 
 #include "postgres.h"
 
@@ -180,6 +182,8 @@ static void
 interpret_AS_clause(const char *languageName, const List *as,
 					char **prosrc_str_p, char **probin_str_p)
 {
+	struct stat stat_buf;
+
 	Assert(as != NIL);
 
 	if (strcmp(languageName, "C") == 0)
@@ -187,9 +191,15 @@ interpret_AS_clause(const char *languageName, const List *as,
 
 		/*
 		 * For "C" language, store the file name in probin and, when
-		 * given, the link symbol name in prosrc.
+		 * given, the link symbol name in prosrc. But first, stat the
+		 * file to make sure it's there!
 		 */
+		
+		if (stat(strVal(lfirst(as)), &stat_buf) == -1)
+				elog(ERROR, "stat failed on file '%s': %m", strVal(lfirst(as)));
+
 		*probin_str_p = strVal(lfirst(as));
+
 		if (lnext(as) == NULL)
 			*prosrc_str_p = "-";
 		else
-- 
GitLab