*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/fmgr/dfmgr.c,v 1.51 2001/09/16 16:11:11 petere Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/fmgr/dfmgr.c,v 1.52 2001/10/04 19:13:55 tgl Exp $
*
*-------------------------------------------------------------------------
*/
/*
- * List of dynamically loaded files.
+ * List of dynamically loaded files (kept in malloc'd memory).
*/
typedef struct df_files
char *fullname;
fullname = expand_dynamic_library_name(filename);
- if (fullname)
- filename = fullname;
+ if (!fullname)
+ fullname = pstrdup(filename);
+ /* at this point fullname is always freshly palloc'd */
/*
* Scan the list of loaded FILES to see if the file has been loaded.
*/
for (file_scanner = file_list;
file_scanner != (DynamicFileList *) NULL &&
- strcmp(filename, file_scanner->filename) != 0;
+ strcmp(fullname, file_scanner->filename) != 0;
file_scanner = file_scanner->next)
;
if (file_scanner == (DynamicFileList *) NULL)
{
-
/*
* Check for same files - different paths (ie, symlink or link)
*/
- if (stat(filename, &stat_buf) == -1)
- elog(ERROR, "stat failed on file '%s': %m", filename);
+ if (stat(fullname, &stat_buf) == -1)
+ elog(ERROR, "stat failed on file '%s': %m", fullname);
for (file_scanner = file_list;
file_scanner != (DynamicFileList *) NULL &&
if (file_scanner == (DynamicFileList *) NULL)
{
-
/*
* File not loaded yet.
*/
file_scanner = (DynamicFileList *)
- malloc(sizeof(DynamicFileList) + strlen(filename));
+ malloc(sizeof(DynamicFileList) + strlen(fullname));
if (file_scanner == NULL)
elog(ERROR, "Out of memory in load_external_function");
MemSet((char *) file_scanner, 0, sizeof(DynamicFileList));
- strcpy(file_scanner->filename, filename);
+ strcpy(file_scanner->filename, fullname);
file_scanner->device = stat_buf.st_dev;
file_scanner->inode = stat_buf.st_ino;
file_scanner->next = (DynamicFileList *) NULL;
- file_scanner->handle = pg_dlopen(filename);
+ file_scanner->handle = pg_dlopen(fullname);
if (file_scanner->handle == (void *) NULL)
{
load_error = (char *) pg_dlerror();
free((char *) file_scanner);
- elog(ERROR, "Load of file %s failed: %s", filename, load_error);
+ elog(ERROR, "Load of file %s failed: %s", fullname, load_error);
}
/* OK to link it into list */
* If funcname is NULL, we only wanted to load the file.
*/
if (funcname == (char *) NULL)
+ {
+ pfree(fullname);
return (PGFunction) NULL;
+ }
retval = pg_dlsym(file_scanner->handle, funcname);
if (retval == (PGFunction) NULL && signalNotFound)
- elog(ERROR, "Can't find function %s in file %s", funcname, filename);
+ elog(ERROR, "Can't find function %s in file %s", funcname, fullname);
+ pfree(fullname);
return retval;
}
char *fullname;
fullname = expand_dynamic_library_name(filename);
- if (fullname)
- filename = fullname;
+ if (!fullname)
+ fullname = pstrdup(filename);
+ /* at this point fullname is always freshly palloc'd */
/*
* We need to do stat() in order to determine whether this is the same
* file as a previously loaded file; it's also handy so as to give a
* good error message if bogus file name given.
*/
- if (stat(filename, &stat_buf) == -1)
- elog(ERROR, "LOAD: could not open file '%s': %m", filename);
+ if (stat(fullname, &stat_buf) == -1)
+ elog(ERROR, "LOAD: could not open file '%s': %m", fullname);
if (file_list != (DynamicFileList *) NULL)
{
}
}
- load_external_function(filename, (char *) NULL, false);
+ load_external_function(fullname, (char *) NULL, false);
+
+ pfree(fullname);
}
* 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.
+ *
+ * A non-NULL result will always be freshly palloc'd.
*/
static char *
expand_dynamic_library_name(const char *name)
full = substitute_libpath_macro(name);
if (file_exists(full))
return full;
+ pfree(full);
}
new = palloc(strlen(name)+ strlen(DLSUFFIX) + 1);
else
{
full = substitute_libpath_macro(new);
+ pfree(new);
if (file_exists(full))
return full;
+ pfree(full);
}
return NULL;
}
-
+/*
+ * Substitute for any macros appearing in the given string.
+ * Result is always freshly palloc'd.
+ */
static char *
substitute_libpath_macro(const char * name)
{
elog(ERROR, "invalid macro name in dynamic library path");
if (name[macroname_len] == '\0')
- return replacement;
+ return pstrdup(replacement);
else
{
char * 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
- * in palloced memory. The the file is not found, return NULL.
+ * path Dynamic_library_path. If the file is found, the full file name
+ * is returned in freshly palloc'd memory. If the file is not found,
+ * return NULL.
*/
static char *
find_in_dynamic_libpath(const char * basename)
{
const char *p;
- char *full;
- size_t len;
size_t baselen;
AssertArg(basename != NULL);
baselen = strlen(basename);
- do {
+ for (;;)
+ {
+ size_t len;
char * piece;
- const char * mangled;
+ char * mangled;
+ char *full;
len = strcspn(p, ":");
piece[len] = '\0';
mangled = substitute_libpath_macro(piece);
+ pfree(piece);
/* only absolute paths */
if (mangled[0] != '/')
full = palloc(strlen(mangled) + 1 + baselen + 1);
sprintf(full, "%s/%s", mangled, basename);
+ pfree(mangled);
if (DebugLvl > 1)
elog(DEBUG, "find_in_dynamic_libpath: trying %s", full);
if (file_exists(full))
return full;
- pfree(piece);
pfree(full);
+
if (p[len] == '\0')
break;
else
p += len + 1;
- } while(1);
+ }
return NULL;
}