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

Add dynamic_library_path parameter and automatic appending of shared

library extension.
This commit is contained in:
Peter Eisentraut
2001-05-17 17:44:18 +00:00
parent 8266e8a84b
commit 761a0bb69b
5 changed files with 252 additions and 5 deletions

View File

@ -4,7 +4,7 @@
# Makefile for utils/fmgr
#
# IDENTIFICATION
# $Header: /cvsroot/pgsql/src/backend/utils/fmgr/Makefile,v 1.10 2000/08/31 16:10:50 petere Exp $
# $Header: /cvsroot/pgsql/src/backend/utils/fmgr/Makefile,v 1.11 2001/05/17 17:44:18 petere Exp $
#
#-------------------------------------------------------------------------
@ -14,6 +14,9 @@ include $(top_builddir)/src/Makefile.global
OBJS = dfmgr.o fmgr.o
override CPPFLAGS += -DLIBDIR=\"$(libdir)\" -DDLSUFFIX=\"$(DLSUFFIX)\"
all: SUBSYS.o
SUBSYS.o: $(OBJS)

View File

@ -8,16 +8,18 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/fmgr/dfmgr.c,v 1.48 2001/03/22 03:59:58 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/fmgr/dfmgr.c,v 1.49 2001/05/17 17:44:18 petere Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "dynloader.h"
#include "miscadmin.h"
#include "utils/dynamic_loader.h"
@ -44,6 +46,12 @@ static DynamicFileList *file_tail = (DynamicFileList *) NULL;
#define SAME_INODE(A,B) ((A).st_ino == (B).inode && (A).st_dev == (B).device)
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);
/*
* Load the specified dynamic-link library file, and look for a function
@ -60,6 +68,11 @@ load_external_function(char *filename, char *funcname,
PGFunction retval;
char *load_error;
struct stat stat_buf;
char *fullname;
fullname = expand_dynamic_library_name(filename);
if (fullname)
filename = fullname;
/*
* Scan the list of loaded FILES to see if the file has been loaded.
@ -143,6 +156,11 @@ load_file(char *filename)
DynamicFileList *file_scanner,
*p;
struct stat stat_buf;
char *fullname;
fullname = expand_dynamic_library_name(filename);
if (fullname)
filename = fullname;
/*
* We need to do stat() in order to determine whether this is the same
@ -181,3 +199,181 @@ load_file(char *filename)
load_external_function(filename, (char *) NULL, false);
}
static bool
file_exists(const char *name)
{
struct stat st;
AssertArg(name != NULL);
if (stat(name, &st) == 0)
return true;
else if (!(errno == ENOENT || errno == ENOTDIR || errno == EACCES))
elog(ERROR, "stat failed on %s: %s", name, strerror(errno));
return false;
}
/* Example format: ".so" */
#ifndef DLSUFFIX
#error "DLSUFFIX must be defined to compile this file."
#endif
/* Example format: "/usr/local/pgsql/lib" */
#ifndef LIBDIR
#error "LIBDIR needs to be defined to compile this file."
#endif
/*
* If name contains a slash, check if the file exists, if so return
* 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.
*/
static char *
expand_dynamic_library_name(const char *name)
{
bool have_slash;
char * new;
size_t len;
AssertArg(name);
have_slash = (strchr(name, '/') != NULL);
if (!have_slash)
{
char * full;
full = find_in_dynamic_libpath(name);
if (full)
return full;
}
else
{
if (file_exists(name))
return pstrdup(name);
}
len = strlen(name);
new = palloc(len + strlen(DLSUFFIX) + 1);
strcpy(new, name);
strcpy(new + len, DLSUFFIX);
if (!have_slash)
{
char * full;
full = find_in_dynamic_libpath(new);
pfree(new);
if (full)
return full;
}
else
{
if (file_exists(new))
return new;
}
return NULL;
}
/*
* 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.
*/
static char *
find_in_dynamic_libpath(const char * basename)
{
const char *p;
char *full;
size_t len;
size_t baselen;
AssertArg(basename != NULL);
AssertArg(strchr(basename, '/') == NULL);
AssertState(Dynamic_library_path != NULL);
p = Dynamic_library_path;
if (strlen(p) == 0)
return NULL;
baselen = strlen(basename);
do {
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;
if (strncmp(p, "$libdir", varname_len)==0)
replacement = LIBDIR;
else
elog(ERROR, "invalid dynamic_library_path specification");
repl_len = strlen(replacement);
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);
}
if (DebugLvl > 1)
elog(DEBUG, "find_in_dynamic_libpath: trying %s", full);
if (file_exists(full))
return full;
pfree(full);
if (p[len] == '\0')
break;
else
p += len + 1;
} while(1);
return NULL;
}

View File

@ -4,7 +4,7 @@
* Support for grand unified configuration scheme, including SET
* command, configuration file, and command line options.
*
* $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.35 2001/03/22 17:41:47 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.36 2001/05/17 17:44:18 petere Exp $
*
* Copyright 2000 by PostgreSQL Global Development Group
* Written by Peter Eisentraut <peter_e@gmx.net>.
@ -22,6 +22,7 @@
#include "access/xlog.h"
#include "commands/async.h"
#include "fmgr.h"
#include "libpq/auth.h"
#include "libpq/pqcomm.h"
#include "miscadmin.h"
@ -328,6 +329,9 @@ static struct config_real
static struct config_string
ConfigureNamesString[] =
{
{"dynamic_library_path", PGC_SUSET, &Dynamic_library_path,
"$libdir", NULL, NULL},
{"krb_server_keyfile", PGC_POSTMASTER, &pg_krb_server_keyfile,
PG_KRB_SRVTAB, NULL, NULL},

View File

@ -11,7 +11,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: fmgr.h,v 1.13 2001/03/22 04:00:25 momjian Exp $
* $Id: fmgr.h,v 1.14 2001/05/17 17:44:18 petere Exp $
*
*-------------------------------------------------------------------------
*/
@ -350,6 +350,7 @@ extern Oid fmgr_internal_function(const char *proname);
extern PGFunction load_external_function(char *filename, char *funcname,
bool signalNotFound);
extern void load_file(char *filename);
extern char * Dynamic_library_path;
/*