1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-27 12:41:57 +03:00

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.
This commit is contained in:
Peter Eisentraut
2001-05-19 09:01:10 +00:00
parent a008109d05
commit cb8b40e6d5
7 changed files with 394 additions and 529 deletions

View File

@ -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;