aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPeter Eisentraut <peter_e@gmx.net>2001-05-19 09:01:10 +0000
committerPeter Eisentraut <peter_e@gmx.net>2001-05-19 09:01:10 +0000
commitcb8b40e6d5dbaa6a8ada4a6b1db2686a0f1e1f68 (patch)
tree184906e59e816698b635e3cb5b08f27b0687e893 /src
parenta008109d05b43ab8115ace963b8e8aa8c3d4e0d1 (diff)
downloadpostgresql-cb8b40e6d5dbaa6a8ada4a6b1db2686a0f1e1f68.tar.gz
postgresql-cb8b40e6d5dbaa6a8ada4a6b1db2686a0f1e1f68.zip
Allow special '$libdir' macro to show up in object file path in CREATE
FUNCTION command. Guard against trying to load a directory. Update documentation some.
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/fmgr/dfmgr.c119
1 files changed, 60 insertions, 59 deletions
diff --git a/src/backend/utils/fmgr/dfmgr.c b/src/backend/utils/fmgr/dfmgr.c
index 695fb1ed76e..0448632aadb 100644
--- a/src/backend/utils/fmgr/dfmgr.c
+++ b/src/backend/utils/fmgr/dfmgr.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/fmgr/dfmgr.c,v 1.49 2001/05/17 17:44:18 petere Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/fmgr/dfmgr.c,v 1.50 2001/05/19 09:01:10 petere Exp $
*
*-------------------------------------------------------------------------
*/
@@ -51,7 +51,7 @@ char * Dynamic_library_path;
static bool file_exists(const char *name);
static char * find_in_dynamic_libpath(const char * basename);
static char * expand_dynamic_library_name(const char *name);
-
+static char * substitute_libpath_macro(const char * name);
/*
* Load the specified dynamic-link library file, and look for a function
@@ -210,7 +210,7 @@ file_exists(const char *name)
AssertArg(name != NULL);
if (stat(name, &st) == 0)
- return true;
+ return S_ISDIR(st.st_mode) ? false : true;
else if (!(errno == ENOENT || errno == ENOTDIR || errno == EACCES))
elog(ERROR, "stat failed on %s: %s", name, strerror(errno));
@@ -234,15 +234,14 @@ file_exists(const char *name)
* the name. Else (no slash) try to expand using search path (see
* find_in_dynamic_libpath below); if that works, return the fully
* expanded file name. If the previous failed, append DLSUFFIX and
- * try again. If all fails, return NULL. The return value is
- * palloc'ed.
+ * try again. If all fails, return NULL.
*/
static char *
expand_dynamic_library_name(const char *name)
{
bool have_slash;
char * new;
- size_t len;
+ char * full;
AssertArg(name);
@@ -250,28 +249,23 @@ expand_dynamic_library_name(const char *name)
if (!have_slash)
{
- char * full;
-
full = find_in_dynamic_libpath(name);
if (full)
return full;
}
else
{
- if (file_exists(name))
- return pstrdup(name);
+ full = substitute_libpath_macro(name);
+ if (file_exists(full))
+ return full;
}
- len = strlen(name);
-
- new = palloc(len + strlen(DLSUFFIX) + 1);
+ new = palloc(strlen(name)+ strlen(DLSUFFIX) + 1);
strcpy(new, name);
- strcpy(new + len, DLSUFFIX);
+ strcat(new, DLSUFFIX);
if (!have_slash)
{
- char * full;
-
full = find_in_dynamic_libpath(new);
pfree(new);
if (full)
@@ -279,8 +273,9 @@ expand_dynamic_library_name(const char *name)
}
else
{
- if (file_exists(new))
- return new;
+ full = substitute_libpath_macro(new);
+ if (file_exists(full))
+ return full;
}
return NULL;
@@ -288,6 +283,40 @@ expand_dynamic_library_name(const char *name)
+static char *
+substitute_libpath_macro(const char * name)
+{
+ size_t macroname_len;
+ char * replacement = NULL;
+
+ AssertArg(name != NULL);
+
+ if (strlen(name) == 0 || name[0] != '$')
+ return pstrdup(name);
+
+ macroname_len = strcspn(name + 1, "/") + 1;
+
+ if (strncmp(name, "$libdir", macroname_len)==0)
+ replacement = LIBDIR;
+ else
+ elog(ERROR, "invalid macro name in dynamic library path");
+
+ if (name[macroname_len] == '\0')
+ return replacement;
+ else
+ {
+ char * new;
+
+ new = palloc(strlen(replacement) + (strlen(name) - macroname_len) + 1);
+
+ strcpy(new, replacement);
+ strcat(new, name + macroname_len);
+
+ return new;
+ }
+}
+
+
/*
* Search for a file called 'basename' in the colon-separated search
* path 'path'. If the file is found, the full file name is returned
@@ -312,55 +341,26 @@ find_in_dynamic_libpath(const char * basename)
baselen = strlen(basename);
do {
+ char * piece;
+ const char * mangled;
+
len = strcspn(p, ":");
if (len == 0)
elog(ERROR, "zero length dynamic_library_path component");
- /* substitute special value */
- if (p[0] == '$')
- {
- size_t varname_len = strcspn(p + 1, "/") + 1;
- const char * replacement = NULL;
- size_t repl_len;
+ piece = palloc(len + 1);
+ strncpy(piece, p, len);
+ piece[len] = '\0';
- if (strncmp(p, "$libdir", varname_len)==0)
- replacement = LIBDIR;
- else
- elog(ERROR, "invalid dynamic_library_path specification");
+ mangled = substitute_libpath_macro(piece);
- repl_len = strlen(replacement);
+ /* only absolute paths */
+ if (mangled[0] != '/')
+ elog(ERROR, "dynamic_library_path component is not absolute");
- if (p[varname_len] == '\0')
- {
- full = palloc(repl_len + 1 + baselen + 1);
- snprintf(full, repl_len + 1 + baselen + 1,
- "%s/%s", replacement, basename);
- }
- else
- {
- full = palloc(repl_len + (len - varname_len) + 1 + baselen + 1);
-
- strcpy(full, replacement);
- strncat(full, p + varname_len, len - varname_len);
- full[repl_len + (len - varname_len)] = '\0';
- strcat(full, "/");
- strcat(full, basename);
- }
- }
-
- /* regular case */
- else
- {
- /* only absolute paths */
- if (p[0] != '/')
- elog(ERROR, "dynamic_library_path component is not absolute");
-
- full = palloc(len + 1 + baselen + 1);
- strncpy(full, p, len);
- full[len] = '/';
- strcpy(full + len + 1, basename);
- }
+ full = palloc(strlen(mangled) + 1 + baselen + 1);
+ sprintf(full, "%s/%s", mangled, basename);
if (DebugLvl > 1)
elog(DEBUG, "find_in_dynamic_libpath: trying %s", full);
@@ -368,6 +368,7 @@ find_in_dynamic_libpath(const char * basename)
if (file_exists(full))
return full;
+ pfree(piece);
pfree(full);
if (p[len] == '\0')
break;