I have reorganized the code to allow path-relative installs. A relative
path is used if only the last directory of a path is different from the
hardcoded binary directory. For example, /a/b/c is relative to /a/b/d,
but /a/b/c is not relative to /a/f/g.
If the install used relative paths, then the system will use the current
binary directory, strip the /bin part, and add /lib or /share as
appropriate.
I also created new get_* functions to access compiled-in paths and
adjusted if relative installs are to be used.
I cleaned up substitute_libpath_macro() code.
I will do some doc updates now for the install file.
Patch attached and applied.
--
Bruce Momjian | http://candle.pha.pa.us
pgman@candle.pha.pa.us | (610) 359-1001
+ If your life is a hard drive, | 13 Roberts Road
+ Christ can be your backup. | Newtown Square, Pennsylvania 19073
Index: src/backend/postmaster/postmaster.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/postmaster/postmaster.c,v
retrieving revision 1.387
diff -c -c -r1.387 postmaster.c
*** src/backend/postmaster/postmaster.c 14 May 2004 17:04:44 -0000 1.387
--- src/backend/postmaster/postmaster.c 17 May 2004 14:25:35 -0000
***************
*** 697,702 ****
--- 697,704 ----
ereport(FATAL,
(errmsg("%s: could not locate my own executable path",
progname)));
+ if (strlen(pkglib_path) == 0)
+ get_pkglib_path(my_exec_path, pkglib_path);
#ifdef EXEC_BACKEND
if (find_other_exec(argv[0], "postgres", PG_VERSIONSTR, postgres_exec_path) < 0)
Index: src/backend/tcop/postgres.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/tcop/postgres.c,v
retrieving revision 1.406
diff -c -c -r1.406 postgres.c
*** src/backend/tcop/postgres.c 14 May 2004 17:04:45 -0000 1.406
--- src/backend/tcop/postgres.c 17 May 2004 14:25:38 -0000
***************
*** 2652,2657 ****
--- 2652,2660 ----
ereport(FATAL,
(errmsg("%s: could not locate postgres executable",
argv[0])));
+ if (strlen(pkglib_path) == 0)
+ get_pkglib_path(my_exec_path, pkglib_path);
+
/*
* Validate we have been given a reasonable-looking DataDir (if
* under postmaster, assume postmaster did this already).
Index: src/backend/utils/fmgr/Makefile
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/utils/fmgr/Makefile,v
retrieving revision 1.15
diff -c -c -r1.15 Makefile
*** src/backend/utils/fmgr/Makefile 23 Dec 2003 21:56:20 -0000 1.15
--- src/backend/utils/fmgr/Makefile 17 May 2004 14:25:38 -0000
***************
*** 14,20 ****
OBJS = dfmgr.o fmgr.o funcapi.o
! override CPPFLAGS += -DPKGLIBDIR=\"$(pkglibdir)\" -DDLSUFFIX=\"$(DLSUFFIX)\"
all: SUBSYS.o
--- 14,20 ----
OBJS = dfmgr.o fmgr.o funcapi.o
! override CPPFLAGS += -DDLSUFFIX=\"$(DLSUFFIX)\"
all: SUBSYS.o
Index: src/backend/utils/fmgr/dfmgr.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/utils/fmgr/dfmgr.c,v
retrieving revision 1.71
diff -c -c -r1.71 dfmgr.c
*** src/backend/utils/fmgr/dfmgr.c 9 Mar 2004 05:06:45 -0000 1.71
--- src/backend/utils/fmgr/dfmgr.c 17 May 2004 14:25:39 -0000
***************
*** 270,281 ****
#error "DLSUFFIX must be defined to compile this file."
#endif
- /* Example format: "/usr/local/pgsql/lib" */
- #ifndef PKGLIBDIR
- #error "PKGLIBDIR 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
--- 270,275 ----
***************
*** 341,402 ****
static char *
substitute_libpath_macro(const char *name)
{
! size_t macroname_len;
! char *replacement = NULL;
! #ifdef WIN32
! char basename[MAXPGPATH];
! #endif
!
AssertArg(name != NULL);
if (name[0] != '$')
return pstrdup(name);
! #ifndef WIN32
! macroname_len = strcspn(name + 1, "/") + 1;
! #else
! macroname_len = strcspn(name + 1, "/\\") + 1;
! #endif
!
! if (strncmp(name, "$libdir", macroname_len) == 0)
! #ifndef WIN32
! replacement = PKGLIBDIR;
! #else
! {
! char *p;
! if (GetModuleFileName(NULL,basename,MAXPGPATH) == 0)
! ereport(FATAL,
! (errmsg("GetModuleFileName failed (%i)",(int)GetLastError())));
!
! canonicalize_path(basename);
! if ((p = last_path_separator(basename)) == NULL)
! ereport(FATAL,
! (errmsg("unexpected failure in determining PKGLIBDIR (%s)",basename)));
! else
! *p = '\0';
!
! strcat(basename,"/../lib");
! replacement = basename;
! }
! #endif
! else
ereport(ERROR,
(errcode(ERRCODE_INVALID_NAME),
errmsg("invalid macro name in dynamic library path")));
! if (name[macroname_len] == '\0')
! return pstrdup(replacement);
! else
! {
! char *new;
! new = palloc(strlen(replacement) + (strlen(name) - macroname_len) + 1);
! strcpy(new, replacement);
! strcat(new, name + macroname_len);
!
! return new;
! }
}
--- 335,363 ----
static char *
substitute_libpath_macro(const char *name)
{
! const char *sep_ptr;
! char *ret;
!
AssertArg(name != NULL);
if (name[0] != '$')
return pstrdup(name);
! if ((sep_ptr = first_path_separator(name)) == NULL)
! sep_ptr = name + strlen(name);
!
! if (strlen("$libdir") != sep_ptr - name ||
! strncmp(name, "$libdir", strlen("$libdir")) != 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_NAME),
errmsg("invalid macro name in dynamic library path")));
! ret = palloc(strlen(pkglib_path) + strlen(sep_ptr) + 1);
! strcpy(ret, pkglib_path);
! strcat(ret, sep_ptr);
! return ret;
}
Index: src/backend/utils/init/globals.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/utils/init/globals.c,v
retrieving revision 1.85
diff -c -c -r1.85 globals.c
*** src/backend/utils/init/globals.c 13 May 2004 22:45:03 -0000 1.85
--- src/backend/utils/init/globals.c 17 May 2004 14:25:39 -0000
***************
*** 46,51 ****
--- 46,52 ----
char OutputFileName[MAXPGPATH];
char my_exec_path[MAXPGPATH]; /* full path to postgres executable */
+ char pkglib_path[MAXPGPATH]; /* full path to lib directory */
BackendId MyBackendId;
Index: src/bin/initdb/Makefile
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/initdb/Makefile,v
retrieving revision 1.37
diff -c -c -r1.37 Makefile
*** src/bin/initdb/Makefile 11 May 2004 21:57:14 -0000 1.37
--- src/bin/initdb/Makefile 17 May 2004 14:25:40 -0000
***************
*** 13,19 ****
top_builddir = ../../..
include $(top_builddir)/src/Makefile.global
! override CPPFLAGS := -DPGDATADIR=\"$(datadir)\" -DFRONTEND -I$(libpq_srcdir) $(CPPFLAGS)
OBJS= initdb.o \
$(filter exec.o, $(LIBOBJS))
--- 13,19 ----
top_builddir = ../../..
include $(top_builddir)/src/Makefile.global
! override CPPFLAGS := -DFRONTEND -I$(libpq_srcdir) $(CPPFLAGS)
OBJS= initdb.o \
$(filter exec.o, $(LIBOBJS))
Index: src/bin/initdb/initdb.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/initdb/initdb.c,v
retrieving revision 1.30
diff -c -c -r1.30 initdb.c
*** src/bin/initdb/initdb.c 17 May 2004 13:17:29 -0000 1.30
--- src/bin/initdb/initdb.c 17 May 2004 14:25:41 -0000
***************
*** 69,79 ****
/*
* these values are passed in by makefile defines
- *
- * Note that "datadir" is not the directory we're going to initialize,
- * it's merely how Autoconf names PREFIX/share.
*/
! char *datadir = PGDATADIR;
/* values to be obtained from arguments */
char *pg_data = "";
--- 69,76 ----
/*
* these values are passed in by makefile defines
*/
! char *share_path = NULL;
/* values to be obtained from arguments */
char *pg_data = "";
***************
*** 129,135 ****
/* path to 'initdb' binary directory */
! char bindir[MAXPGPATH];
char backend_exec[MAXPGPATH];
static void *xmalloc(size_t size);
--- 126,132 ----
/* path to 'initdb' binary directory */
! char bin_path[MAXPGPATH];
char backend_exec[MAXPGPATH];
static void *xmalloc(size_t size);
***************
*** 730,737 ****
static void
set_input(char **dest, char *filename)
{
! *dest = xmalloc(strlen(datadir) + strlen(filename) + 2);
! sprintf(*dest, "%s/%s", datadir, filename);
}
/*
--- 727,734 ----
static void
set_input(char **dest, char *filename)
{
! *dest = xmalloc(strlen(share_path) + strlen(filename) + 2);
! sprintf(*dest, "%s/%s", share_path, filename);
}
/*
***************
*** 1849,1855 ****
printf(_("Running in noclean mode. Mistakes will not be cleaned up.\n"));
break;
case 'L':
! datadir = xstrdup(optarg);
break;
case 1:
locale = xstrdup(optarg);
--- 1846,1852 ----
printf(_("Running in noclean mode. Mistakes will not be cleaned up.\n"));
break;
case 'L':
! share_path = xstrdup(optarg);
break;
case 1:
locale = xstrdup(optarg);
***************
*** 1951,1959 ****
}
/* store binary directory */
! strcpy(bindir, backend_exec);
! *last_path_separator(bindir) = '\0';
!
if ((short_version = get_short_version()) == NULL)
{
fprintf(stderr, _("%s: could not determine valid short version string\n"), progname);
--- 1948,1962 ----
}
/* store binary directory */
! strcpy(bin_path, backend_exec);
! *last_path_separator(bin_path) = '\0';
!
! if (!share_path)
! {
! share_path = xmalloc(MAXPGPATH);
! get_share_path(backend_exec, share_path);
! }
!
if ((short_version = get_short_version()) == NULL)
{
fprintf(stderr, _("%s: could not determine valid short version string\n"), progname);
***************
*** 1983,1995 ****
{
fprintf(stderr,
"VERSION=%s\n"
! "PGDATA=%s\ndatadir=%s\nPGPATH=%s\n"
"ENCODING=%s\nENCODINGID=%s\n"
"POSTGRES_SUPERUSERNAME=%s\nPOSTGRES_BKI=%s\n"
"POSTGRES_DESCR=%s\nPOSTGRESQL_CONF_SAMPLE=%s\n"
"PG_HBA_SAMPLE=%s\nPG_IDENT_SAMPLE=%s\n",
PG_VERSION,
! pg_data, datadir, bindir,
encoding, encodingid,
username, bki_file,
desc_file, conf_file,
--- 1986,1998 ----
{
fprintf(stderr,
"VERSION=%s\n"
! "PGDATA=%s\nshare_path=%s\nPGPATH=%s\n"
"ENCODING=%s\nENCODINGID=%s\n"
"POSTGRES_SUPERUSERNAME=%s\nPOSTGRES_BKI=%s\n"
"POSTGRES_DESCR=%s\nPOSTGRESQL_CONF_SAMPLE=%s\n"
"PG_HBA_SAMPLE=%s\nPG_IDENT_SAMPLE=%s\n",
PG_VERSION,
! pg_data, share_path, bin_path,
encoding, encodingid,
username, bki_file,
desc_file, conf_file,
***************
*** 2182,2189 ****
" %s%s%s/postmaster -D %s%s%s\n"
"or\n"
" %s%s%s/pg_ctl -D %s%s%s -l logfile start\n\n"),
! QUOTE_PATH, bindir, QUOTE_PATH, QUOTE_PATH, pg_data, QUOTE_PATH,
! QUOTE_PATH, bindir, QUOTE_PATH, QUOTE_PATH, pg_data, QUOTE_PATH);
return 0;
}
--- 2185,2192 ----
" %s%s%s/postmaster -D %s%s%s\n"
"or\n"
" %s%s%s/pg_ctl -D %s%s%s -l logfile start\n\n"),
! QUOTE_PATH, bin_path, QUOTE_PATH, QUOTE_PATH, pg_data, QUOTE_PATH,
! QUOTE_PATH, bin_path, QUOTE_PATH, QUOTE_PATH, pg_data, QUOTE_PATH);
return 0;
}
Index: src/bin/psql/Makefile
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/psql/Makefile,v
retrieving revision 1.43
diff -c -c -r1.43 Makefile
*** src/bin/psql/Makefile 26 Apr 2004 17:40:48 -0000 1.43
--- src/bin/psql/Makefile 17 May 2004 14:25:41 -0000
***************
*** 15,25 ****
REFDOCDIR= $(top_srcdir)/doc/src/sgml/ref
! override CPPFLAGS := -I$(libpq_srcdir) $(CPPFLAGS) -DFRONTEND -DSYSCONFDIR='"$(sysconfdir)"'
OBJS= command.o common.o help.o input.o stringutils.o mainloop.o copy.o \
startup.o prompt.o variables.o large_obj.o print.o describe.o \
! psqlscan.o tab-complete.o mbprint.o
FLEXFLAGS = -Cfe
--- 15,26 ----
REFDOCDIR= $(top_srcdir)/doc/src/sgml/ref
! override CPPFLAGS := -I$(libpq_srcdir) $(CPPFLAGS) -DFRONTEND
OBJS= command.o common.o help.o input.o stringutils.o mainloop.o copy.o \
startup.o prompt.o variables.o large_obj.o print.o describe.o \
! psqlscan.o tab-complete.o mbprint.o \
! $(filter exec.o, $(LIBOBJS))
FLEXFLAGS = -Cfe
***************
*** 29,34 ****
--- 30,38 ----
psql: $(OBJS) $(libpq_builddir)/libpq.a
$(CC) $(CFLAGS) $(OBJS) $(libpq) $(LDFLAGS) $(LIBS) -o $@$(X)
+ exec.c: % : $(top_srcdir)/src/port/%
+ rm -f $@ && $(LN_S) $< .
+
help.o: $(srcdir)/sql_help.h
ifdef PERL
***************
*** 60,66 ****
# psqlscan.c is in the distribution tarball, so is not cleaned here
clean distclean:
! rm -f psql$(X) $(OBJS)
maintainer-clean: distclean
rm -f $(srcdir)/sql_help.h $(srcdir)/psqlscan.c
--- 64,70 ----
# psqlscan.c is in the distribution tarball, so is not cleaned here
clean distclean:
! rm -f psql$(X) $(OBJS) exec.c
maintainer-clean: distclean
rm -f $(srcdir)/sql_help.h $(srcdir)/psqlscan.c
Index: src/bin/psql/startup.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/psql/startup.c,v
retrieving revision 1.92
diff -c -c -r1.92 startup.c
*** src/bin/psql/startup.c 2 May 2004 04:25:45 -0000 1.92
--- src/bin/psql/startup.c 17 May 2004 14:25:41 -0000
***************
*** 74,80 ****
static void parse_psql_options(int argc, char *argv[],
struct adhoc_opts * options);
! static void process_psqlrc(void);
static void process_psqlrc_file(char *filename);
static void showVersion(void);
--- 74,80 ----
static void parse_psql_options(int argc, char *argv[],
struct adhoc_opts * options);
! static void process_psqlrc(char *argv0);
static void process_psqlrc_file(char *filename);
static void showVersion(void);
***************
*** 239,245 ****
if (options.action == ACT_FILE && strcmp(options.action_string, "-") != 0)
{
if (!options.no_psqlrc)
! process_psqlrc();
successResult = process_file(options.action_string);
}
--- 239,245 ----
if (options.action == ACT_FILE && strcmp(options.action_string, "-") != 0)
{
if (!options.no_psqlrc)
! process_psqlrc(argv[0]);
successResult = process_file(options.action_string);
}
***************
*** 305,311 ****
SetVariable(pset.vars, "PROMPT3", DEFAULT_PROMPT3);
if (!options.no_psqlrc)
! process_psqlrc();
if (!pset.notty)
initializeInput(options.no_readline ? 0 : 1);
if (options.action_string) /* -f - was used */
--- 305,311 ----
SetVariable(pset.vars, "PROMPT3", DEFAULT_PROMPT3);
if (!options.no_psqlrc)
! process_psqlrc(argv[0]);
if (!pset.notty)
initializeInput(options.no_readline ? 0 : 1);
if (options.action_string) /* -f - was used */
***************
*** 567,588 ****
}
- #ifndef SYSCONFDIR
- #error "You must compile this file with SYSCONFDIR defined."
- #endif
-
/*
* Load .psqlrc file, if found.
*/
static void
! process_psqlrc(void)
{
- char *globalFile = SYSCONFDIR "/" SYSPSQLRC;
char *home;
char *psqlrc;
! process_psqlrc_file(globalFile);
if ((home = getenv("HOME")) != NULL)
{
--- 567,590 ----
}
/*
* Load .psqlrc file, if found.
*/
static void
! process_psqlrc(char *argv0)
{
char *home;
char *psqlrc;
+ char global_file[MAXPGPATH];
+ char my_exec_path[MAXPGPATH];
+ char etc_path[MAXPGPATH];
+
+ find_my_exec(argv0, my_exec_path);
+ get_etc_path(my_exec_path, etc_path);
! snprintf(global_file, MAXPGPATH, "%s/%s", etc_path, SYSPSQLRC);
! process_psqlrc_file(global_file);
if ((home = getenv("HOME")) != NULL)
{
Index: src/include/miscadmin.h
===================================================================
RCS file: /cvsroot/pgsql-server/src/include/miscadmin.h,v
retrieving revision 1.158
diff -c -c -r1.158 miscadmin.h
*** src/include/miscadmin.h 13 May 2004 22:45:04 -0000 1.158
--- src/include/miscadmin.h 17 May 2004 14:25:42 -0000
***************
*** 143,148 ****
--- 143,149 ----
extern char OutputFileName[];
extern char my_exec_path[];
+ extern char pkglib_path[];
/*
* done in storage/backendid.h for now.
Index: src/include/port.h
===================================================================
RCS file: /cvsroot/pgsql-server/src/include/port.h,v
retrieving revision 1.31
diff -c -c -r1.31 port.h
*** src/include/port.h 14 May 2004 17:04:47 -0000 1.31
--- src/include/port.h 17 May 2004 14:25:42 -0000
***************
*** 26,37 ****
extern char *last_path_separator(const char *filename);
extern void canonicalize_path(char *path);
extern const char *get_progname(const char *argv0);
/* Portable way to find binaries */
extern int find_my_exec(const char *argv0, char *full_path);
extern int find_other_exec(const char *argv0, char const *target,
const char *versionstr, char *retpath);
-
#if defined(__CYGWIN__) || defined(WIN32)
#define EXE ".exe"
#define DEVNULL "nul"
--- 26,42 ----
extern char *last_path_separator(const char *filename);
extern void canonicalize_path(char *path);
extern const char *get_progname(const char *argv0);
+ extern void get_share_path(const char *my_exec_path, char *ret_path);
+ extern void get_etc_path(const char *my_exec_path, char *ret_path);
+ extern void get_include_path(const char *my_exec_path, char *ret_path);
+ extern void get_pkginclude_path(const char *my_exec_path, char *ret_path);
+ extern void get_pkglib_path(const char *my_exec_path, char *ret_path);
+
/* Portable way to find binaries */
extern int find_my_exec(const char *argv0, char *full_path);
extern int find_other_exec(const char *argv0, char const *target,
const char *versionstr, char *retpath);
#if defined(__CYGWIN__) || defined(WIN32)
#define EXE ".exe"
#define DEVNULL "nul"
***************
*** 179,191 ****
char *buffer, size_t buflen,
struct hostent **result,
int *herrno);
-
- /* $PATH (or %PATH%) path separator */
- #ifdef WIN32
- #define PATHSEP ';'
- #else
- #define PATHSEP ':'
- #endif
/* FIXME: [win32] Placeholder win32 replacements, to allow continued development */
#ifdef WIN32
--- 184,189 ----
Index: src/interfaces/ecpg/preproc/Makefile
===================================================================
RCS file: /cvsroot/pgsql-server/src/interfaces/ecpg/preproc/Makefile,v
retrieving revision 1.103
diff -c -c -r1.103 Makefile
*** src/interfaces/ecpg/preproc/Makefile 30 Apr 2004 04:14:06 -0000 1.103
--- src/interfaces/ecpg/preproc/Makefile 17 May 2004 14:25:43 -0000
***************
*** 11,18 ****
override CPPFLAGS := -I$(srcdir)/../include -I$(srcdir) $(CPPFLAGS) \
-DMAJOR_VERSION=$(MAJOR_VERSION) \
-DMINOR_VERSION=$(MINOR_VERSION) -DPATCHLEVEL=$(PATCHLEVEL) \
- -DINCLUDEDIR=\"$(includedir)\" \
- -DPKGINCLUDEDIR=\"$(pkgincludedir)\" \
-DFRONTEND
ifeq ($(GCC), yes)
--- 11,16 ----
***************
*** 20,34 ****
endif
override CFLAGS += $(PTHREAD_CFLAGS)
! OBJS=preproc.o type.o ecpg.o ecpg_keywords.o output.o\
! keywords.o c_keywords.o ../ecpglib/typename.o descriptor.o variable.o
!
all: submake-libpgport ecpg
ecpg: $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) $^ $(LIBS) $(PTHREAD_LIBS) -o $@$(X)
# pgc is compiled as part of preproc
preproc.o: $(srcdir)/pgc.c
--- 18,35 ----
endif
override CFLAGS += $(PTHREAD_CFLAGS)
! OBJS= preproc.o type.o ecpg.o ecpg_keywords.o output.o\
! keywords.o c_keywords.o ../ecpglib/typename.o descriptor.o variable.o \
! $(filter exec.o, $(LIBOBJS))
all: submake-libpgport ecpg
ecpg: $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) $^ $(LIBS) $(PTHREAD_LIBS) -o $@$(X)
+ exec.c: % : $(top_srcdir)/src/port/%
+ rm -f $@ && $(LN_S) $< .
+
# pgc is compiled as part of preproc
preproc.o: $(srcdir)/pgc.c
***************
*** 65,71 ****
rm -f $(DESTDIR)$(bindir)/ecpg$(X)
clean distclean:
! rm -f *.o ecpg$(X)
# garbage from partial builds
@rm -f y.tab.c y.tab.h
# garbage from development
--- 66,72 ----
rm -f $(DESTDIR)$(bindir)/ecpg$(X)
clean distclean:
! rm -f *.o ecpg$(X) exec.c
# garbage from partial builds
@rm -f y.tab.c y.tab.h
# garbage from development
Index: src/interfaces/ecpg/preproc/ecpg.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/interfaces/ecpg/preproc/ecpg.c,v
retrieving revision 1.86
diff -c -c -r1.86 ecpg.c
*** src/interfaces/ecpg/preproc/ecpg.c 12 May 2004 13:38:48 -0000 1.86
--- src/interfaces/ecpg/preproc/ecpg.c 17 May 2004 14:25:43 -0000
***************
*** 120,126 ****
out_option = 0;
struct _include_path *ip;
const char *progname;
!
progname = get_progname(argv[0]);
if (argc > 1)
--- 120,128 ----
out_option = 0;
struct _include_path *ip;
const char *progname;
! char my_exec_path[MAXPGPATH];
! char include_path[MAXPGPATH];
!
progname = get_progname(argv[0]);
if (argc > 1)
***************
*** 138,143 ****
--- 140,147 ----
}
}
+ find_my_exec(argv[0], my_exec_path);
+
while ((c = getopt(argc, argv, "vcio:I:tD:dC:r:h")) != -1)
{
switch (c)
***************
*** 175,186 ****
case 'C':
if (strncmp(optarg, "INFORMIX", strlen("INFORMIX")) == 0)
{
compat = (strcmp(optarg, "INFORMIX") == 0) ? ECPG_COMPAT_INFORMIX : ECPG_COMPAT_INFORMIX_SE;
/* system_includes = true; */
add_preprocessor_define("dec_t=decimal");
add_preprocessor_define("intrvl_t=interval");
add_preprocessor_define("dtime_t=timestamp");
! add_include_path(PKGINCLUDEDIR "/informix/esql");
}
else
{
--- 179,196 ----
case 'C':
if (strncmp(optarg, "INFORMIX", strlen("INFORMIX")) == 0)
{
+ char pkginclude_path[MAXPGPATH];
+ char informix_path[MAXPGPATH];
+
compat = (strcmp(optarg, "INFORMIX") == 0) ? ECPG_COMPAT_INFORMIX : ECPG_COMPAT_INFORMIX_SE;
/* system_includes = true; */
add_preprocessor_define("dec_t=decimal");
add_preprocessor_define("intrvl_t=interval");
add_preprocessor_define("dtime_t=timestamp");
!
! get_pkginclude_path(my_exec_path, pkginclude_path);
! snprintf(informix_path, MAXPGPATH, "%s/informix/esql", pkginclude_path);
! add_include_path(informix_path);
}
else
{
***************
*** 216,222 ****
add_include_path(".");
add_include_path("/usr/local/include");
! add_include_path(INCLUDEDIR);
add_include_path("/usr/include");
if (verbose)
--- 226,233 ----
add_include_path(".");
add_include_path("/usr/local/include");
! get_include_path(my_exec_path, include_path);
! add_include_path(include_path);
add_include_path("/usr/include");
if (verbose)
Index: src/interfaces/libpq/Makefile
===================================================================
RCS file: /cvsroot/pgsql-server/src/interfaces/libpq/Makefile,v
retrieving revision 1.105
diff -c -c -r1.105 Makefile
*** src/interfaces/libpq/Makefile 10 May 2004 23:09:04 -0000 1.105
--- src/interfaces/libpq/Makefile 17 May 2004 14:25:43 -0000
***************
*** 19,25 ****
SO_MINOR_VERSION= 2
override CPPFLAGS := -I$(srcdir) $(CPPFLAGS) $(PTHREAD_CFLAGS) -DFRONTEND -DSYSCONFDIR='"$(sysconfdir)"'
! override CFLAGS += $(PTHREAD_CFLAGS)
OBJS= fe-auth.o fe-connect.o fe-exec.o fe-misc.o fe-print.o fe-lobj.o \
fe-protocol2.o fe-protocol3.o pqexpbuffer.o pqsignal.o fe-secure.o \
--- 19,31 ----
SO_MINOR_VERSION= 2
override CPPFLAGS := -I$(srcdir) $(CPPFLAGS) $(PTHREAD_CFLAGS) -DFRONTEND -DSYSCONFDIR='"$(sysconfdir)"'
! override CFLAGS += $(PTHREAD_CFLAGS) \
! -DPGBINDIR=\"$(bindir)\" \
! -DPGDATADIR=\"$(datadir)\" \
! -DSYSCONFDIR='"$(sysconfdir)"' \
! -DINCLUDEDIR=\"$(includedir)\" \
! -DPKGINCLUDEDIR=\"$(pkgincludedir)\" \
! -DPKGLIBDIR=\"$(pkglibdir)\"
OBJS= fe-auth.o fe-connect.o fe-exec.o fe-misc.o fe-print.o fe-lobj.o \
fe-protocol2.o fe-protocol3.o pqexpbuffer.o pqsignal.o fe-secure.o \
Index: src/port/Makefile
===================================================================
RCS file: /cvsroot/pgsql-server/src/port/Makefile,v
retrieving revision 1.10
diff -c -c -r1.10 Makefile
*** src/port/Makefile 23 Apr 2004 18:15:55 -0000 1.10
--- src/port/Makefile 17 May 2004 14:25:45 -0000
***************
*** 15,20 ****
--- 15,27 ----
top_builddir = ../..
include $(top_builddir)/src/Makefile.global
+ override CPPFLAGS += -DPGBINDIR=\"$(bindir)\" \
+ -DPGDATADIR=\"$(datadir)\" \
+ -DSYSCONFDIR='"$(sysconfdir)"' \
+ -DINCLUDEDIR=\"$(includedir)\" \
+ -DPKGINCLUDEDIR=\"$(pkgincludedir)\" \
+ -DPKGLIBDIR=\"$(pkglibdir)\"
+
ifdef LIBOBJS
all: libpgport.a
endif
Index: src/port/exec.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/port/exec.c,v
retrieving revision 1.5
diff -c -c -r1.5 exec.c
*** src/port/exec.c 14 May 2004 17:04:48 -0000 1.5
--- src/port/exec.c 17 May 2004 14:25:45 -0000
***************
*** 25,30 ****
--- 25,37 ----
#include "miscadmin.h"
+ /* $PATH (or %PATH%) path separator */
+ #ifdef WIN32
+ #define PATHSEP ';'
+ #else
+ #define PATHSEP ':'
+ #endif
+
#ifndef S_IRUSR /* XXX [TRH] should be in a header */
#define S_IRUSR S_IREAD
#define S_IWUSR S_IWRITE
***************
*** 265,270 ****
--- 272,287 ----
log_debug("could not find a \"%s\" to execute", argv0);
return -1;
+
+ #if 0
+ /*
+ * Win32 has a native way to find the executable name, but the above
+ * method works too.
+ */
+ if (GetModuleFileName(NULL,basename,MAXPGPATH) == 0)
+ ereport(FATAL,
+ (errmsg("GetModuleFileName failed (%i)",(int)GetLastError())));
+ #endif
}
Index: src/port/path.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/port/path.c,v
retrieving revision 1.7
diff -c -c -r1.7 path.c
*** src/port/path.c 12 May 2004 13:38:49 -0000 1.7
--- src/port/path.c 17 May 2004 14:25:45 -0000
***************
*** 16,21 ****
--- 16,39 ----
#include "c.h"
#include <ctype.h>
+ #ifndef WIN32
+ #define ISSEP(ch) ((ch) == '/')
+ #else
+ #define ISSEP(ch) ((ch) == '/' || (ch) == '\\')
+ #endif
+
+ static bool relative_path(const char *path1, const char *path2);
+ static void trim_directory(char *path);
+ static void trim_trailing_separator(char *path);
+
+ /* Move to last of consecutive separators or to null byte */
+ #define MOVE_TO_SEP_END(p) \
+ { \
+ while (ISSEP((p)[0]) && (ISSEP((p)[1]) || !(p)[1])) \
+ (p)++; \
+ }
+
+
/*
* is_absolute_path
*/
***************
*** 40,61 ****
char *
first_path_separator(const char *filename)
{
! #ifndef WIN32
! return strchr(filename, '/');
! #else
! char *slash,
! *bslash;
! /* How should we handle "C:file.c"? */
! slash = strchr(filename, '/');
! bslash = strchr(filename, '\\');
! if (slash == NULL)
! return bslash;
! else if (bslash == NULL)
! return slash;
! else
! return (slash < bslash) ? slash : bslash;
! #endif
}
--- 58,69 ----
char *
first_path_separator(const char *filename)
{
! char *p;
! for (p = (char *)filename; *p; p++)
! if (ISSEP(*p))
! return p;
! return NULL;
}
***************
*** 65,86 ****
char *
last_path_separator(const char *filename)
{
! #ifndef WIN32
! return strrchr(filename, '/');
! #else
! char *slash,
! *bslash;
! /* How should we handle "C:file.c"? */
! slash = strrchr(filename, '/');
! bslash = strrchr(filename, '\\');
! if (slash == NULL)
! return bslash;
! else if (bslash == NULL)
! return slash;
! else
! return (slash > bslash) ? slash : bslash;
! #endif
}
--- 73,84 ----
char *
last_path_separator(const char *filename)
{
! char *p, *ret = NULL;
! for (p = (char *)filename; *p; p++)
! if (ISSEP(*p))
! ret = p;
! return ret;
}
***************
*** 96,112 ****
void
canonicalize_path(char *path)
{
char *p;
for (p = path; *p; p++)
{
- #ifdef WIN32
if (*p == '\\')
*p = '/';
- #endif
}
! if (p > path+1 && *--p == '/')
! *p = '\0';
}
--- 94,110 ----
void
canonicalize_path(char *path)
{
+ #ifdef WIN32
char *p;
for (p = path; *p; p++)
{
if (*p == '\\')
*p = '/';
}
! #endif
!
! trim_trailing_separator(path);
}
***************
*** 120,124 ****
--- 118,328 ----
return argv0;
else
return last_path_separator(argv0) + 1;
+ }
+
+
+ /*
+ * get_share_path
+ */
+ void
+ get_share_path(const char *my_exec_path, char *ret_path)
+ {
+ if (relative_path(PGBINDIR, PGDATADIR))
+ {
+ /* Autoconf calls our /share 'datadir' */
+ StrNCpy(ret_path, my_exec_path, MAXPGPATH);
+ trim_directory(ret_path); /* trim off binary */
+ trim_directory(ret_path); /* trim off /bin */
+ strcat(ret_path, "/share"); /* add /share */
+ }
+ else
+ StrNCpy(ret_path, PGDATADIR, MAXPGPATH);
+ }
+
+
+
+ /*
+ * get_etc_path
+ */
+ void
+ get_etc_path(const char *my_exec_path, char *ret_path)
+ {
+ if (relative_path(PGBINDIR, SYSCONFDIR))
+ {
+ StrNCpy(ret_path, my_exec_path, MAXPGPATH);
+ trim_directory(ret_path);
+ trim_directory(ret_path);
+ strcat(ret_path, "/etc");
+ }
+ else
+ StrNCpy(ret_path, SYSCONFDIR, MAXPGPATH);
+ }
+
+
+
+ /*
+ * get_include_path
+ */
+ void
+ get_include_path(const char *my_exec_path, char *ret_path)
+ {
+ if (relative_path(PGBINDIR, INCLUDEDIR))
+ {
+ StrNCpy(ret_path, my_exec_path, MAXPGPATH);
+ trim_directory(ret_path);
+ trim_directory(ret_path);
+ strcat(ret_path, "/include");
+ }
+ else
+ StrNCpy(ret_path, INCLUDEDIR, MAXPGPATH);
+ }
+
+
+
+ /*
+ * get_pkginclude_path
+ */
+ void
+ get_pkginclude_path(const char *my_exec_path, char *ret_path)
+ {
+ if (relative_path(PGBINDIR, PKGINCLUDEDIR))
+ {
+ StrNCpy(ret_path, my_exec_path, MAXPGPATH);
+ trim_directory(ret_path);
+ trim_directory(ret_path);
+ strcat(ret_path, "/include");
+ }
+ else
+ StrNCpy(ret_path, PKGINCLUDEDIR, MAXPGPATH);
+ }
+
+
+
+ /*
+ * get_pkglib_path
+ *
+ * Return library path, either relative to /bin or hardcoded
+ */
+ void
+ get_pkglib_path(const char *my_exec_path, char *ret_path)
+ {
+ if (relative_path(PGBINDIR, PKGLIBDIR))
+ {
+ StrNCpy(ret_path, my_exec_path, MAXPGPATH);
+ trim_directory(ret_path);
+ trim_directory(ret_path);
+ strcat(ret_path, "/lib");
+ }
+ else
+ StrNCpy(ret_path, PKGLIBDIR, MAXPGPATH);
+ }
+
+
+
+ /*
+ * relative_path
+ *
+ * Do the supplied paths differ only in their last component?
+ */
+ static bool
+ relative_path(const char *path1, const char *path2)
+ {
+
+ #ifdef WIN32
+ /* Driver letters match? */
+ if (isalpha(*path1) && path1[1] == ':' &&
+ (!isalpha(*path2) || !path2[1] == ':'))
+ return false;
+ if ((!isalpha(*path1) || !path1[1] == ':') &&
+ (isalpha(*path2) && path2[1] == ':')
+ return false;
+ if (isalpha(*path1) && path1[1] == ':' &&
+ isalpha(*path2) && path2[1] == ':')
+ {
+ if (toupper(*path1) != toupper(*path2))
+ return false;
+ path1 += 2;
+ path2 += 2;
+ }
+ #endif
+
+ while (1)
+ {
+ /* Move past adjacent slashes like //, and trailing ones */
+ MOVE_TO_SEP_END(path1);
+ MOVE_TO_SEP_END(path2);
+
+ /* One of the paths is done? */
+ if (!*path1 || !*path2)
+ break;
+
+ /* Win32 filesystem is case insensitive */
+ #ifndef WIN32
+ if (*path1 != *path2)
+ #else
+ if (toupper((unsigned char) *path1) != toupper((unsigned char)*path2))
+ #endif
+ break;
+
+ path1++;
+ path2++;
+ }
+
+ /* both done, identical? */
+ if (!*path1 && !*path2)
+ return false;
+
+ /* advance past directory name */
+ while (!ISSEP(*path1) && *path1)
+ path1++;
+ while (!ISSEP(*path2) && *path2)
+ path2++;
+
+ MOVE_TO_SEP_END(path1);
+ MOVE_TO_SEP_END(path2);
+
+ /* Are both strings done? */
+ if (!*path1 && !*path2)
+ return true;
+ else
+ return false;
+ }
+
+
+ /*
+ * trim_directory
+ *
+ * Trim trailing directory from path
+ */
+ static void
+ trim_directory(char *path)
+ {
+ char *p;
+
+ if (path[0] == '\0')
+ return;
+
+ for (p = path + strlen(path) - 1; ISSEP(*p) && p > path; p--)
+ ;
+ for (; !ISSEP(*p) && p > path; p--)
+ ;
+ *p = '\0';
+ return;
+ }
+
+
+
+ /*
+ * trim_trailing_separator
+ */
+ static void
+ trim_trailing_separator(char *path)
+ {
+ char *p = path + strlen(path);
+
+ /* trim off trailing slashes */
+ if (p > path)
+ for (p--; p >= path && ISSEP(*p); p--)
+ *p = '\0';
}
Index: src/timezone/Makefile
===================================================================
RCS file: /cvsroot/pgsql-server/src/timezone/Makefile,v
retrieving revision 1.7
diff -c -c -r1.7 Makefile
*** src/timezone/Makefile 30 Apr 2004 20:23:28 -0000 1.7
--- src/timezone/Makefile 17 May 2004 14:25:45 -0000
***************
*** 12,19 ****
top_builddir = ../..
include $(top_builddir)/src/Makefile.global
- override CPPFLAGS += -DPGDATADIR=\"$(datadir)\"
-
OBJS= asctime.o difftime.o localtime.o pgtz.o
ZICOBJS= zic.o ialloc.o scheck.o localtime.o asctime.o pgtz.o
--- 12,17 ----
Index: src/timezone/pgtz.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/timezone/pgtz.c,v
retrieving revision 1.7
diff -c -c -r1.7 pgtz.c
*** src/timezone/pgtz.c 2 May 2004 03:12:12 -0000 1.7
--- src/timezone/pgtz.c 17 May 2004 14:25:45 -0000
***************
*** 25,46 ****
if (done_tzdir)
return tzdir;
! #ifndef WIN32
! StrNCpy(tzdir, PGDATADIR, MAXPGPATH);
! #else
! if (GetModuleFileName(NULL, tzdir, MAXPGPATH) == 0)
! return NULL;
! #endif
!
! canonicalize_path(tzdir);
! #ifdef WIN32
! /* trim off binary name, then go up a directory */
! if ((p = last_path_separator(tzdir)) == NULL)
! return NULL;
! else
! *p = '\0';
! strcat(tzdir, "/../share");
! #endif
strcat(tzdir, "/timezone");
done_tzdir = 1;
--- 25,31 ----
if (done_tzdir)
return tzdir;
! get_share_dir(my_exec_path, tzdir);
strcat(tzdir, "/timezone");
done_tzdir = 1;