As part of the work for making relocatable installs, I have re-factored
authorBruce Momjian <bruce@momjian.us>
Tue, 11 May 2004 21:57:15 +0000 (21:57 +0000)
committerBruce Momjian <bruce@momjian.us>
Tue, 11 May 2004 21:57:15 +0000 (21:57 +0000)
all the code that looks for other binaries.  I move FindExec into
port/exec.c (and renamed it to find_my_binary()).  I also added
find_other_binary that looks for another binary in the same directory as
the calling program, and checks the version string.

The only behavior change was that initdb and pg_dump would look in the
hard-coded bindir directory if it can't find the requested binary in the
same directory as the caller.  The new code throws an error.  The old
behavior seemed too error prone for version mismatches.

15 files changed:
configure
configure.in
src/Makefile.global.in
src/backend/postmaster/postmaster.c
src/backend/tcop/postgres.c
src/backend/utils/init/Makefile
src/bin/initdb/Makefile
src/bin/initdb/initdb.c
src/bin/pg_dump/Makefile
src/bin/pg_dump/pg_dumpall.c
src/include/miscadmin.h
src/include/port.h
src/port/exec.c [moved from src/backend/utils/init/findbe.c with 55% similarity]
src/port/path.c
src/port/pipe.c

index 9403fa4537390212a8bfcf3a0ba261fe078cbe1a..9deb026c4a3ff1786006fec60ce145cbf1986db0 100755 (executable)
--- a/configure
+++ b/configure
@@ -12011,7 +12011,6 @@ case $host_os in mingw*)
 LIBOBJS="$LIBOBJS copydir.$ac_objext"
 LIBOBJS="$LIBOBJS gettimeofday.$ac_objext"
 LIBOBJS="$LIBOBJS open.$ac_objext"
-LIBOBJS="$LIBOBJS pipe.$ac_objext"
 LIBOBJS="$LIBOBJS rand.$ac_objext"
 
 cat >>confdefs.h <<\_ACEOF
index 1cad0dbe281914a70b36ad359c720123baa7b669..8947a815830f5f32baca99fd09c0e6913a6f7893 100644 (file)
@@ -1,5 +1,5 @@
 dnl Process this file with autoconf to produce a configure script.
-dnl $PostgreSQL: pgsql/configure.in,v 1.345 2004/05/07 00:24:57 tgl Exp $
+dnl $PostgreSQL: pgsql/configure.in,v 1.346 2004/05/11 21:57:13 momjian Exp $
 dnl
 dnl Developers, please strive to achieve this order:
 dnl
@@ -892,7 +892,6 @@ case $host_os in mingw*)
 AC_LIBOBJ(copydir)
 AC_LIBOBJ(gettimeofday)
 AC_LIBOBJ(open)
-AC_LIBOBJ(pipe)
 AC_LIBOBJ(rand)
 AC_DEFINE(USE_PGTZ, 1,
    [Define to 1 to use our own timezone library])
index 9dda9bf8b0026542a04b09bea923fd61600f64ae..e87c1ba8efc475cfde15149b01bdf09cf00841c8 100644 (file)
@@ -1,5 +1,5 @@
 # -*-makefile-*-
-# $PostgreSQL: pgsql/src/Makefile.global.in,v 1.181 2004/05/07 00:24:57 tgl Exp $
+# $PostgreSQL: pgsql/src/Makefile.global.in,v 1.182 2004/05/11 21:57:14 momjian Exp $
 
 #------------------------------------------------------------------------------
 # All PostgreSQL makefiles include this file and use the variables it sets,
@@ -339,7 +339,7 @@ endif
 #
 # substitute implementations of the C library
 
-LIBOBJS = @LIBOBJS@ noblock.o path.o pgsleep.o pgstrcasecmp.o sprompt.o thread.o
+LIBOBJS = @LIBOBJS@ exec.o noblock.o path.o pipe.o pgsleep.o pgstrcasecmp.o sprompt.o thread.o
 
 ifneq (,$(LIBOBJS))
 LIBS += -lpgport
index 1d781d0bb5afb2b346fcceeabeb2c76e30700e85..e3df517d1ea148919d2428852294c3786f237bfe 100644 (file)
@@ -37,7 +37,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.382 2004/05/06 19:23:25 momjian Exp $
+ *   $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.383 2004/05/11 21:57:14 momjian Exp $
  *
  * NOTES
  *
@@ -692,7 +692,7 @@ PostmasterMain(int argc, char *argv[])
    /*
     * On some systems our dynloader code needs the executable's pathname.
     */
-   if (FindExec(pg_pathname, progname, "postgres") < 0)
+   if (find_my_binary(pg_pathname, progname, "postgres") < 0)
        ereport(FATAL,
                (errmsg("%s: could not locate postgres executable",
                        progname)));
@@ -3222,7 +3222,7 @@ CreateOptsFile(int argc, char *argv[])
    FILE       *fp;
    int         i;
 
-   if (FindExec(fullprogname, argv[0], "postmaster") < 0)
+   if (find_my_binary(fullprogname, argv[0], "postmaster") < 0)
    {
        elog(LOG, "could not locate postmaster");
        return false;
index 89ec36287c759756eb085fd375ed94f6c3e33e5c..caeef3cd5708dec8ccd66661bde25e46edf3285e 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.402 2004/05/07 01:53:41 momjian Exp $
+ *   $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.403 2004/05/11 21:57:14 momjian Exp $
  *
  * NOTES
  *   this is the "main" module of the postgres backend and
@@ -2649,7 +2649,7 @@ PostgresMain(int argc, char *argv[], const char *username)
         * On some systems our dynloader code needs the executable's
         * pathname.  (If under postmaster, this was done already.)
         */
-       if (FindExec(pg_pathname, argv[0], "postgres") < 0)
+       if (find_my_binary(pg_pathname, argv[0], "postgres") < 0)
            ereport(FATAL,
                    (errmsg("%s: could not locate postgres executable",
                            argv[0])));
index d5dc43ca5cab1948c02539b12359e7c0f472dbc1..8415de8b2a42a82b7c17582191480284a24ce29b 100644 (file)
@@ -4,7 +4,7 @@
 #    Makefile for utils/init
 #
 # IDENTIFICATION
-#    $PostgreSQL: pgsql/src/backend/utils/init/Makefile,v 1.16 2003/11/29 19:52:01 pgsql Exp $
+#    $PostgreSQL: pgsql/src/backend/utils/init/Makefile,v 1.17 2004/05/11 21:57:14 momjian Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -12,7 +12,7 @@ subdir = src/backend/utils/init
 top_builddir = ../../../..
 include $(top_builddir)/src/Makefile.global
 
-OBJS = findbe.o globals.o miscinit.o postinit.o
+OBJS = globals.o miscinit.o postinit.o
 
 all: SUBSYS.o
 
index 5bcaae92f755bf5c62561ea88d8644ee0fc5c986..d709f6076678cb990b5ab019a501cce8750637c6 100644 (file)
@@ -5,7 +5,7 @@
 # Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
 # Portions Copyright (c) 1994, Regents of the University of California
 #
-# $PostgreSQL: pgsql/src/bin/initdb/Makefile,v 1.36 2004/04/26 17:40:48 momjian Exp $
+# $PostgreSQL: pgsql/src/bin/initdb/Makefile,v 1.37 2004/05/11 21:57:14 momjian Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -13,15 +13,19 @@ subdir = src/bin/initdb
 top_builddir = ../../..
 include $(top_builddir)/src/Makefile.global
 
-override CPPFLAGS := -DPGBINDIR=\"$(bindir)\" -DPGDATADIR=\"$(datadir)\" -DFRONTEND -I$(libpq_srcdir) $(CPPFLAGS)
+override CPPFLAGS := -DPGDATADIR=\"$(datadir)\" -DFRONTEND -I$(libpq_srcdir) $(CPPFLAGS)
 
-OBJS=  initdb.o
+OBJS=  initdb.o \
+   $(filter exec.o, $(LIBOBJS))
 
 all: submake-libpq submake-libpgport initdb
 
 initdb: $(OBJS) $(libpq_builddir)/libpq.a
    $(CC) $(CFLAGS) $(OBJS) $(libpq) $(LDFLAGS) $(LIBS) -o $@$(X)
 
+exec.c: % : $(top_srcdir)/src/port/%
+   rm -f $@ && $(LN_S) $< .
+
 install: all installdirs
    $(INSTALL_PROGRAM) initdb$(X) $(DESTDIR)$(bindir)/initdb$(X)
 
@@ -32,8 +36,8 @@ uninstall:
    rm -f $(DESTDIR)$(bindir)/initdb$(X)
 
 clean distclean maintainer-clean:
-   rm -f initdb$(X) $(OBJS)
+   rm -f initdb$(X) $(OBJS) exec.c
 
 
-# ensure that changes in bindir etc. propagate into object file
+# ensure that changes in datadir propagate into object file
 initdb.o: initdb.c $(top_builddir)/src/Makefile.global
index 7b03c404ea3790fe5faacb38e8c040e464dd00c2..fa8bf28da865750fecba578d8767cbdbf66bb14a 100644 (file)
  *
  * template0 is made just by copying the completed template1.
  *
- *
- * TODO:
- *  - clean up find_postgres code and return values
- *
  * Note:
  *  The program has some memory leakage - it isn't worth cleaning it up.
  *
@@ -43,7 +39,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  * Portions taken from FreeBSD.
  *
- * $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.26 2004/05/10 20:51:58 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.27 2004/05/11 21:57:14 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -52,7 +48,6 @@
 
 #include <dirent.h>
 #include <sys/stat.h>
-#include <sys/wait.h>
 #include <unistd.h>
 #include <locale.h>
 #include <signal.h>
@@ -78,7 +73,6 @@ int           optreset;
  * Note that "datadir" is not the directory we're going to initialize,
  * it's merely how Autoconf names PREFIX/share.
  */
-char      *bindir = PGBINDIR;
 char      *datadir = PGDATADIR;
 
 /* values to be obtained from arguments */
@@ -100,7 +94,6 @@ bool     show_setting = false;
 
 /* internal vars */
 char      *progname;
-char      *self_path;
 char      *postgres;
 char      *encodingid = "0";
 char      *bki_file;
@@ -135,25 +128,9 @@ static const char *boot_options = "-F";
 static const char *backend_options = "-F -O -c search_path=pg_catalog -c exit_on_error=true";
 
 
-/* platform specific path stuff */
-#if defined(__CYGWIN__) || defined(WIN32)
-#define EXE ".exe"
-#define DEVNULL "nul"
-#else
-#define EXE ""
-#define DEVNULL "/dev/null"
-#endif
-
-
-/* detected path to postgres and (we assume) friends */
-char      *pgpath;
-
-/* forward declare all our functions */
-#ifdef WIN32
-static char *expanded_path(char *);
-#else
-#define expanded_path(x) (x)
-#endif
+/* path to 'initdb' binary directory */
+char      bindir[MAXPGPATH];
+char      backendbin[MAXPGPATH];
 
 static void *xmalloc(size_t size);
 static char *xstrdup(const char *s);
@@ -161,7 +138,6 @@ static bool rmtree(char *path, bool rmtopdir);
 static char **replace_token(char **lines, char *token, char *replacement);
 static char **readfile(char *path);
 static void writefile(char *path, char **lines);
-static void pclose_check(FILE *stream);
 static int mkdir_p(char *path, mode_t omode);
 static void exit_nicely(void);
 static char *get_id(void);
@@ -171,8 +147,6 @@ static int check_data_dir(void);
 static bool mkdatadir(char *subdir);
 static void set_input(char **dest, char *filename);
 static void check_input(char *path);
-static int find_postgres(char *path);
-static int set_paths(void);
 static void set_short_version(char *short_version, char *extrapath);
 static void set_null_conf(void);
 static void test_connections(void);
@@ -216,7 +190,8 @@ do { \
 
 #define PG_CMD_CLOSE \
 do { \
-   pclose_check(pg); \
+   if (pclose_check(pg)) \
+       exit_nicely(); \
 } while (0)
 
 #define PG_CMD_PUTLINE \
@@ -437,41 +412,6 @@ writefile(char *path, char **lines)
        exit_nicely();
 }
 
-/* pclose() plus useful error reporting */
-static void
-pclose_check(FILE *stream)
-{
-   int     exitstatus;
-
-   exitstatus = pclose(stream);
-
-   if (exitstatus == 0)
-       return;                 /* all is well */
-
-   if (exitstatus == -1)
-   {
-       /* pclose() itself failed, and hopefully set errno */
-       perror("pclose failed");
-   }
-   else if (WIFEXITED(exitstatus))
-   {
-       fprintf(stderr, _("%s: child process exited with exit code %d\n"),
-               progname, WEXITSTATUS(exitstatus));
-   }
-   else if (WIFSIGNALED(exitstatus))
-   {
-       fprintf(stderr, _("%s: child process was terminated by signal %d\n"),
-               progname, WTERMSIG(exitstatus));
-   }
-   else
-   {
-       fprintf(stderr, _("%s: child process exited with unrecognized status %d\n"),
-               progname, exitstatus);
-   }
-
-   exit_nicely();
-}
-
 /* source stolen from FreeBSD /src/bin/mkdir/mkdir.c and adapted */
 
 /*
@@ -814,193 +754,6 @@ check_input(char *path)
 
 }
 
-/*
- * TODO - clean this up and handle the errors properly
- * don't overkill
- */
-#define FIND_SUCCESS 0
-#define FIND_NOT_FOUND 1
-#define FIND_STAT_ERR 2
-#define FIND_NOT_REGFILE 3
-#define FIND_BAD_PERM 4
-#define FIND_EXEC_ERR 5
-#define FIND_WRONG_VERSION 6
-
-/*
- * see if there is a postgres executable in the given path, and giving the
- * right version number
- */
-static int
-find_postgres(char *path)
-{
-   char        fn[MAXPGPATH];
-   char        cmd[MAXPGPATH];
-   char        line[100];
-
-#ifndef WIN32
-   int         permmask = S_IROTH | S_IXOTH;
-#endif
-
-   struct stat statbuf;
-   FILE       *pgver;
-   int         plen = strlen(path);
-
-   if (plen > 0 && path[plen - 1] != '/')
-       snprintf(fn, sizeof(fn), "%s/postgres%s", path, EXE);
-   else
-       snprintf(fn, sizeof(fn), "%spostgres%s", path, EXE);
-
-   if (stat(fn, &statbuf) != 0)
-   {
-       if (errno == ENOENT)
-           return FIND_NOT_FOUND;
-       else
-           return FIND_STAT_ERR;
-   }
-   if (!S_ISREG(statbuf.st_mode))
-       return FIND_NOT_REGFILE;
-
-#ifndef WIN32
-
-   /*
-    * Only unix requires this test, on WIN32 an .exe file should be
-    * executable
-    */
-   if ((statbuf.st_mode & permmask) != permmask)
-       return FIND_BAD_PERM;
-#endif
-
-   snprintf(cmd, sizeof(cmd), "\"%s/postgres\" -V 2>%s", path, DEVNULL);
-
-   /* flush output buffers in case popen does not... */
-   fflush(stdout);
-   fflush(stderr);
-
-   if ((pgver = popen(cmd, "r")) == NULL)
-       return FIND_EXEC_ERR;
-
-   if (fgets(line, sizeof(line), pgver) == NULL)
-       perror("fgets failure");
-
-   pclose_check(pgver);
-
-   if (strcmp(line, PG_VERSIONSTR) != 0)
-       return FIND_WRONG_VERSION;
-
-   return FIND_SUCCESS;
-}
-
-/*
- * Windows doesn't like relative paths to executables (other things work fine)
- * so we call its builtin function to expand them. Elsewhere this is a NOOP
- */
-#ifdef WIN32
-static char *
-expanded_path(char *path)
-{
-   char        abspath[MAXPGPATH];
-
-   if (_fullpath(abspath, path, sizeof(abspath)) == NULL)
-   {
-       perror("expanded path");
-       return path;
-   }
-   canonicalize_path(abspath);
-   return xstrdup(abspath);
-}
-#endif
-
-/*
- * set the paths pointing to postgres
- *
- * look for it in the same place we found this program, or in the environment
- * path, or in the configured bindir.
- * We do it in this order because during upgrades users might move
- * their trees to backup places, so the hard-wired bindir might be inaccurate.
- *
- * XXX this needs work, as its error handling is vastly inferior to the
- * shell-script version, in particular the case where a postgres executable
- * is failing
- */
-static int
-set_paths(void)
-{
-   if (testpath && !self_path)
-   {
-       char       *path,
-                  *cursor;
-       int         pathlen,
-                   i,
-                   pathsegs;
-       char      **pathbits;
-       char        buf[MAXPGPATH];
-       struct stat statbuf;
-
-       path = xstrdup(getenv("PATH"));
-       pathlen = strlen(path);
-
-       for (i = 0, pathsegs = 1; i < pathlen; i++)
-       {
-           if (path[i] == PATHSEP)
-               pathsegs++;
-       }
-
-       pathbits = (char **) xmalloc(pathsegs * sizeof(char *));
-       for (i = 0, pathsegs = 0, cursor = path; i <= pathlen; i++)
-       {
-           if (path[i] == PATHSEP || path[i] == 0)
-           {
-               path[i] = 0;
-               if (strlen(cursor) == 0)
-               {
-                   /* empty path segment means current directory */
-                   pathbits[pathsegs] = xstrdup(".");
-               }
-               else
-               {
-                   canonicalize_path(cursor);
-                   pathbits[pathsegs] = cursor;
-               }
-               pathsegs++;
-               cursor = path + i + 1;
-           }
-       }
-
-       for (i = 0; i < pathsegs; i++)
-       {
-           snprintf(buf, sizeof(buf), "%s/%s%s", pathbits[i], progname, EXE);
-           if (stat(buf, &statbuf) == 0 && S_ISREG(statbuf.st_mode))
-           {
-               self_path = pathbits[i];
-               break;
-           }
-       }
-   }
-
-   if (testpath && self_path &&
-       (find_postgres(expanded_path(self_path)) == 0))
-   {
-       /* we found postgres on out own path */
-       pgpath = expanded_path(self_path);
-   }
-   else
-   {
-       /* look in the hardcoded bindir */
-       int         res;
-       char       *cbindir;
-
-       cbindir = xstrdup(bindir);
-       canonicalize_path(cbindir);
-       res = find_postgres(expanded_path(cbindir));
-       if (res == 0)
-           pgpath = expanded_path(cbindir);
-       else
-           return 1;
-   }
-
-   return 0;
-}
-
 /*
  * write out the PG_VERSION file in the data dir, or its subdirectory
  * if extrapath is not NULL
@@ -1063,10 +816,10 @@ test_connections(void)
    for (i = 0; i < len; i++)
    {
        snprintf(cmd, sizeof(cmd),
-                "\"%s/postgres\" -boot -x0 %s "
+                "\"%s\" -boot -x0 %s "
                 "-c shared_buffers=%d -c max_connections=%d template1 "
                 "<%s >%s 2>&1",
-                pgpath, boot_options,
+                backendbin, boot_options,
                 conns[i] * 5, conns[i],
                 DEVNULL, DEVNULL);
        status = system(cmd);
@@ -1099,10 +852,10 @@ test_buffers(void)
    for (i = 0; i < len; i++)
    {
        snprintf(cmd, sizeof(cmd),
-                "\"%s/postgres\" -boot -x0 %s "
+                "\"%s\" -boot -x0 %s "
                 "-c shared_buffers=%d -c max_connections=%d template1 "
                 "<%s >%s 2>&1",
-                pgpath, boot_options,
+                backendbin, boot_options,
                 bufs[i], n_connections,
                 DEVNULL, DEVNULL);
        status = system(cmd);
@@ -1250,8 +1003,8 @@ bootstrap_template1(char *short_version)
    unsetenv("PGCLIENTENCODING");
 
    snprintf(cmd, sizeof(cmd),
-            "\"%s/postgres\" -boot -x1 %s %s template1",
-            pgpath, boot_options, talkargs);
+            "\"%s\" -boot -x1 %s %s template1",
+            backendbin, boot_options, talkargs);
 
    PG_CMD_OPEN;
 
@@ -1300,8 +1053,8 @@ setup_shadow(void)
    fflush(stdout);
 
    snprintf(cmd, sizeof(cmd),
-            "\"%s/postgres\" %s template1 >%s",
-            pgpath, backend_options,
+            "\"%s\" %s template1 >%s",
+            backendbin, backend_options,
             DEVNULL);
 
    PG_CMD_OPEN;
@@ -1340,8 +1093,8 @@ get_set_pwd(void)
    fflush(stdout);
 
    snprintf(cmd, sizeof(cmd),
-            "\"%s/postgres\" %s template1 >%s",
-            pgpath, backend_options,
+            "\"%s\" %s template1 >%s",
+            backendbin, backend_options,
             DEVNULL);
 
    PG_CMD_OPEN;
@@ -1394,8 +1147,8 @@ unlimit_systables(void)
    fflush(stdout);
 
    snprintf(cmd, sizeof(cmd),
-            "\"%s/postgres\" %s template1 >%s",
-            pgpath, backend_options,
+            "\"%s\" %s template1 >%s",
+            backendbin, backend_options,
             DEVNULL);
 
    PG_CMD_OPEN;
@@ -1467,8 +1220,8 @@ setup_depend(void)
    fflush(stdout);
 
    snprintf(cmd, sizeof(cmd),
-            "\"%s/postgres\" %s template1 >%s",
-            pgpath, backend_options,
+            "\"%s\" %s template1 >%s",
+            backendbin, backend_options,
             DEVNULL);
 
    PG_CMD_OPEN;
@@ -1500,8 +1253,8 @@ setup_sysviews(void)
     * We use -N here to avoid backslashing stuff in system_views.sql
     */
    snprintf(cmd, sizeof(cmd),
-            "\"%s/postgres\" %s -N template1 >%s",
-            pgpath, backend_options,
+            "\"%s\" %s -N template1 >%s",
+            backendbin, backend_options,
             DEVNULL);
 
    PG_CMD_OPEN;
@@ -1532,8 +1285,8 @@ setup_description(void)
    fflush(stdout);
 
    snprintf(cmd, sizeof(cmd),
-            "\"%s/postgres\" %s template1 >%s",
-            pgpath, backend_options,
+            "\"%s\" %s template1 >%s",
+            backendbin, backend_options,
             DEVNULL);
 
    PG_CMD_OPEN;
@@ -1580,8 +1333,8 @@ setup_conversion(void)
    fflush(stdout);
 
    snprintf(cmd, sizeof(cmd),
-            "\"%s/postgres\" %s template1 >%s",
-            pgpath, backend_options,
+            "\"%s\" %s template1 >%s",
+            backendbin, backend_options,
             DEVNULL);
 
    PG_CMD_OPEN;
@@ -1636,8 +1389,8 @@ setup_privileges(void)
    fflush(stdout);
 
    snprintf(cmd, sizeof(cmd),
-            "\"%s/postgres\" %s template1 >%s",
-            pgpath, backend_options,
+            "\"%s\" %s template1 >%s",
+            backendbin, backend_options,
             DEVNULL);
 
    PG_CMD_OPEN;
@@ -1699,8 +1452,8 @@ setup_schema(void)
     * We use -N here to avoid backslashing stuff in information_schema.sql
     */
    snprintf(cmd, sizeof(cmd),
-            "\"%s/postgres\" %s -N template1 >%s",
-            pgpath, backend_options,
+            "\"%s\" %s -N template1 >%s",
+            backendbin, backend_options,
             DEVNULL);
 
    PG_CMD_OPEN;
@@ -1716,8 +1469,8 @@ setup_schema(void)
    PG_CMD_CLOSE;
 
    snprintf(cmd, sizeof(cmd),
-            "\"%s/postgres\" %s template1 >%s",
-            pgpath, backend_options,
+            "\"%s\" %s template1 >%s",
+            backendbin, backend_options,
             DEVNULL);
 
    PG_CMD_OPEN;
@@ -1756,8 +1509,8 @@ vacuum_db(void)
    fflush(stdout);
 
    snprintf(cmd, sizeof(cmd),
-            "\"%s/postgres\" %s template1 >%s",
-            pgpath, backend_options,
+            "\"%s\" %s template1 >%s",
+            backendbin, backend_options,
             DEVNULL);
 
    PG_CMD_OPEN;
@@ -1812,8 +1565,8 @@ make_template0(void)
    fflush(stdout);
 
    snprintf(cmd, sizeof(cmd),
-            "\"%s/postgres\" %s template1 >%s",
-            pgpath, backend_options,
+            "\"%s\" %s template1 >%s",
+            backendbin, backend_options,
             DEVNULL);
 
    PG_CMD_OPEN;
@@ -2043,48 +1796,17 @@ main(int argc, char *argv[])
    };
 
    int         c,
-               i;
+               i,
+               ret;
    int         option_index;
    char       *short_version;
    char       *pgdenv;         /* PGDATA value got from sent to
                                 * environment */
    char       *subdirs[] =
    {"global", "pg_xlog", "pg_clog", "base", "base/1"};
-   char       *lastsep;
-   char       *carg0;
-#if defined(__CYGWIN__) || defined(WIN32)
-   char       *exe;            /* location of exe suffix in progname */
-#endif
-
    init_nls();
 
-   /* parse argv[0] - detect explicit path if there was one */
-   carg0 = xstrdup(argv[0]);
-   canonicalize_path(carg0);
-
-   lastsep = strrchr(carg0, '/');
-   progname = lastsep ? xstrdup(lastsep + 1) : carg0;
-
-#if defined(__CYGWIN__) || defined(WIN32)
-   if (strlen(progname) > 4 &&
-       (exe = progname + (strlen(progname) - 4)) &&
-       stricmp(exe, EXE) == 0)
-   {
-       /* strip .exe suffix, regardless of case */
-       *exe = '\0';
-   }
-#endif
-
-   if (lastsep)
-   {
-       self_path = carg0;
-       *lastsep = '\0';
-   }
-   else
-   {
-       /* no path known to ourselves from argv[0] */
-       self_path = NULL;
-   }
+   progname = get_progname(argv[0]);
 
     if (argc > 1)
     {
@@ -2210,16 +1932,28 @@ main(int argc, char *argv[])
    sprintf(pgdenv, "PGDATA=%s", pg_data);
    putenv(pgdenv);
 
-   if (set_paths() != 0)
+   if ((ret = find_other_binary(backendbin, argv[0], progname, "postgres",
+                          PG_VERSIONSTR)) < 0)
    {
-       fprintf(stderr,
-               _("The program \"postgres\" is needed by %s "
-               "but was not found in \n"
-               "the directory \"%s\". Check your installation.\n"),
-               progname, bindir);
+       if (ret == -1)
+           fprintf(stderr,
+                       _("The program \"postgres\" is needed by %s "
+                       "but was not found in the same directory as \"%s\".\n"
+                       "Check your installation.\n"),
+                       progname, progname);
+       else
+           fprintf(stderr,
+                       _("The program \"postgres\" was found by %s "
+                       "but was not the same version as \"%s\".\n"
+                       "Check your installation.\n"),
+                       progname, progname);
        exit(1);
    }
 
+   /* store binary directory */
+   strcpy(bindir, backendbin);
+   *last_path_separator(bindir) = '\0';
+   
    if ((short_version = get_short_version()) == NULL)
    {
        fprintf(stderr, _("%s: could not determine valid short version string\n"), progname);
@@ -2255,7 +1989,7 @@ main(int argc, char *argv[])
                "POSTGRES_DESCR=%s\nPOSTGRESQL_CONF_SAMPLE=%s\n"
                "PG_HBA_SAMPLE=%s\nPG_IDENT_SAMPLE=%s\n",
                PG_VERSION,
-               pg_data, datadir, pgpath,
+               pg_data, datadir, bindir,
                encoding, encodingid,
                username, bki_file,
                desc_file, conf_file,
@@ -2448,8 +2182,8 @@ main(int argc, char *argv[])
           "    %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, pgpath, QUOTE_PATH, QUOTE_PATH, pg_data, QUOTE_PATH,
-       QUOTE_PATH, pgpath, QUOTE_PATH, QUOTE_PATH, pg_data, QUOTE_PATH);
+        QUOTE_PATH, bindir, QUOTE_PATH, QUOTE_PATH, pg_data, QUOTE_PATH,
+       QUOTE_PATH, bindir, QUOTE_PATH, QUOTE_PATH, pg_data, QUOTE_PATH);
 
    return 0;
 }
index 59722363a5d9657b62163e15a19fbc074cb253aa..414194cd30bfd8d065073981253a37dcd4e6c275 100644 (file)
@@ -5,7 +5,7 @@
 # Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
 # Portions Copyright (c) 1994, Regents of the University of California
 #
-# $PostgreSQL: pgsql/src/bin/pg_dump/Makefile,v 1.46 2004/04/30 20:01:39 momjian Exp $
+# $PostgreSQL: pgsql/src/bin/pg_dump/Makefile,v 1.47 2004/05/11 21:57:14 momjian Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -18,10 +18,11 @@ override CPPFLAGS += -DFRONTEND
 OBJS=  pg_backup_archiver.o pg_backup_db.o pg_backup_custom.o \
    pg_backup_files.o pg_backup_null.o pg_backup_tar.o \
    dumputils.o
+PG_DUMPALL_OBJS =  $(filter exec.o, $(LIBOBJS))
 
 EXTRA_OBJS = $(top_builddir)/src/backend/parser/keywords.o
 
-override CPPFLAGS := -I$(libpq_srcdir) $(CPPFLAGS) -DBINDIR=\"$(bindir)\"
+override CPPFLAGS := -I$(libpq_srcdir) $(CPPFLAGS)
 
 
 all: submake-libpq submake-libpgport submake-backend pg_dump pg_restore pg_dumpall
@@ -32,8 +33,11 @@ pg_dump: pg_dump.o common.o pg_dump_sort.o $(OBJS) $(libpq_builddir)/libpq.a
 pg_restore: pg_restore.o $(OBJS) $(libpq_builddir)/libpq.a
    $(CC) $(CFLAGS) pg_restore.o $(OBJS) $(EXTRA_OBJS) $(libpq) $(LDFLAGS) $(LIBS) -o $@$(X)
 
-pg_dumpall: pg_dumpall.o dumputils.o $(libpq_builddir)/libpq.a
-   $(CC) $(CFLAGS) pg_dumpall.o dumputils.o $(EXTRA_OBJS) $(libpq) $(LDFLAGS) $(LIBS) -o $@$(X)
+pg_dumpall: pg_dumpall.o dumputils.o $(PG_DUMPALL_OBJS) $(libpq_builddir)/libpq.a
+   $(CC) $(CFLAGS) pg_dumpall.o dumputils.o $(PG_DUMPALL_OBJS) $(EXTRA_OBJS) $(libpq) $(LDFLAGS) $(LIBS) -o $@$(X)
+
+exec.c: % : $(top_srcdir)/src/port/%
+   rm -f $@ && $(LN_S) $< .
 
 .PHONY: submake-backend
 submake-backend:
@@ -52,8 +56,4 @@ uninstall:
    rm -f $(addprefix $(DESTDIR)$(bindir)/, pg_dump$(X) pg_restore$(X) pg_dumpall$(X))
 
 clean distclean maintainer-clean:
-   rm -f pg_dump$(X) pg_restore$(X) pg_dumpall$(X) $(OBJS) pg_dump.o common.o pg_dump_sort.o pg_restore.o pg_dumpall.o
-
-
-# ensure that changes in bindir etc. propagate into object file
-pg_dumpall.o: pg_dumpall.c $(top_builddir)/src/Makefile.global
+   rm -f pg_dump$(X) pg_restore$(X) pg_dumpall$(X) $(OBJS) pg_dump.o common.o pg_dump_sort.o pg_restore.o pg_dumpall.o exec.c
index f15ddc206dcfc25d25ee3ac0546b3d2844693e6a..0817cabfb95df3531e64291866c78a701053f078 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  *
- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dumpall.c,v 1.30 2004/01/22 19:09:32 tgl Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dumpall.c,v 1.31 2004/05/11 21:57:14 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -35,6 +35,9 @@ int           optreset;
 
 #define _(x) gettext((x))
 
+/* version string we expect back from postgres */
+#define PG_VERSIONSTR "pg_dump (PostgreSQL) " PG_VERSION "\n"
+
 
 static char *progname;
 
@@ -52,10 +55,9 @@ static int   runPgDump(const char *dbname);
 static PGconn *connectDatabase(const char *dbname, const char *pghost, const char *pgport,
                const char *pguser, bool require_password);
 static PGresult *executeQuery(PGconn *conn, const char *query);
-static char *findPgDump(const char *argv0);
 
 
-char      *pgdumploc;
+char       pg_dump_bin[MAXPGPATH];
 PQExpBuffer pgdumpopts;
 bool       output_clean = false;
 bool       skip_acls = false;
@@ -75,7 +77,7 @@ main(int argc, char *argv[])
    bool        globals_only = false;
    bool        schema_only = false;
    PGconn     *conn;
-   int         c;
+   int         c, ret;
 
    static struct option long_options[] = {
        {"data-only", no_argument, NULL, 'a'},
@@ -121,7 +123,24 @@ main(int argc, char *argv[])
        }
    }
 
-   pgdumploc = findPgDump(argv[0]);
+   if ((ret = find_other_binary(pg_dump_bin, argv[0], progname, "pg_dump",
+                          PG_VERSIONSTR)) < 0)
+   {
+       if (ret == -1)
+           fprintf(stderr,
+                       _("The program \"pg_dump\" is needed by %s "
+                       "but was not found in the same directory as \"%s\".\n"
+                       "Check your installation.\n"),
+                       progname, progname);
+       else
+           fprintf(stderr,
+                       _("The program \"pg_dump\" was found by %s "
+                       "but was not the same version as \"%s\".\n"
+                       "Check your installation.\n"),
+                       progname, progname);
+       exit(1);
+   }
+
    pgdumpopts = createPQExpBuffer();
 
    while ((c = getopt_long(argc, argv, "acdDgh:iop:sU:vWx", long_options, &optindex)) != -1)
@@ -667,7 +686,7 @@ runPgDump(const char *dbname)
    const char *p;
    int         ret;
 
-   appendPQExpBuffer(cmd, "%s %s -Fp '", pgdumploc, pgdumpopts->data);
+   appendPQExpBuffer(cmd, "\"%s\" %s -Fp '", pg_dump_bin, pgdumpopts->data);
 
    /* Shell quoting is not quite like SQL quoting, so can't use fmtId */
    for (p = dbname; *p; p++)
@@ -792,51 +811,3 @@ executeQuery(PGconn *conn, const char *query)
 
    return res;
 }
-
-
-
-/*
- * Find location of pg_dump executable.
- */
-static char *
-findPgDump(const char *argv0)
-{
-   char       *last;
-   PQExpBuffer cmd;
-   static char *result = NULL;
-
-   if (result)
-       return result;
-
-   cmd = createPQExpBuffer();
-   last = last_path_separator(argv0);
-
-   if (!last)
-       appendPQExpBuffer(cmd, "pg_dump");
-   else
-   {
-       char       *dir = strdup(argv0);
-
-       *(dir + (last - argv0)) = '\0';
-       appendPQExpBuffer(cmd, "%s/pg_dump", dir);
-   }
-
-   result = strdup(cmd->data);
-
-   appendPQExpBuffer(cmd, " -V >/dev/null 2>&1");
-   if (system(cmd->data) == 0)
-       goto end;
-
-   result = BINDIR "/pg_dump";
-   if (system(BINDIR "/pg_dump -V >/dev/null 2>&1") == 0)
-       goto end;
-
-   fprintf(stderr, _("%s: could not find pg_dump\n"
-       "Make sure it is in the path or in the same directory as %s.\n"),
-           progname, progname);
-   exit(1);
-
-end:
-   destroyPQExpBuffer(cmd);
-   return result;
-}
index 76f2d086aea08298cbc087e6c05bc8db552e2f8a..fc312b3d74baafee9656be7851ae25e00ecb30b7 100644 (file)
@@ -13,7 +13,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.156 2004/04/12 16:19:18 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.157 2004/05/11 21:57:15 momjian Exp $
  *
  * NOTES
  *   some of the information in this file should be moved to
@@ -254,10 +254,6 @@ extern void SetSessionAuthorization(AclId userid, bool is_superuser);
 
 extern void SetDataDir(const char *dir);
 
-extern int FindExec(char *full_path, const char *argv0,
-        const char *binary_name);
-extern int CheckPathAccess(char *path, char *name, int open_mode);
-
 /* in utils/misc/superuser.c */
 extern bool superuser(void);   /* current user is superuser */
 extern bool superuser_arg(AclId userid);       /* given user is superuser */
index 2f5123483bf204b7f2d92698b8f79f95c4748dc2..177c82f8c4e7b8f64a6056db64991f3ad4f5ab2b 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/port.h,v 1.28 2004/05/07 00:24:58 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/port.h,v 1.29 2004/05/11 21:57:15 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -27,6 +27,20 @@ extern char *last_path_separator(const char *filename);
 extern void canonicalize_path(char *path);
 extern char *get_progname(char *argv0);
 
+/* Portable way to find binaries */
+extern int find_my_binary(char *full_path, const char *argv0,
+                    const char *binary_name);
+extern int find_other_binary(char *retpath, const char *argv0, const char *progname,
+                      char const *target, const char *versionstr);
+
+#if defined(__CYGWIN__) || defined(WIN32)
+#define EXE ".exe"
+#define DEVNULL "nul"
+#else
+#define EXE ""
+#define DEVNULL "/dev/null"
+#endif
+
 /* Portable delay handling */
 extern void pg_usleep(long microsec);
 
@@ -57,6 +71,7 @@ extern int pgpipe(int handles[2]);
 extern int piperead(int s, char* buf, int len);
 #define pipewrite(a,b,c)   send(a,b,c,0)
 #endif
+extern int pclose_check(FILE *stream);
 
 #if defined(__MINGW32__) || defined(__CYGWIN__)
 /*
similarity index 55%
rename from src/backend/utils/init/findbe.c
rename to src/port/exec.c
index 035ff0553aa8033386e8132a4d35df68f61d40a3..27e66cc0c8f74d99809839b1ed4baf11a48b6c5e 100644 (file)
@@ -1,17 +1,22 @@
 /*-------------------------------------------------------------------------
  *
- * findbe.c
+ * exec.c
  *
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/utils/init/findbe.c,v 1.42 2004/03/15 16:18:43 momjian Exp $
+ *   $PostgreSQL: pgsql/src/port/exec.c,v 1.1 2004/05/11 21:57:15 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
+
+#ifndef FRONTEND
 #include "postgres.h"
+#else
+#include "postgres_fe.h"
+#endif
 
 #include <grp.h>
 #include <pwd.h>
 #define S_IXOTH         ((S_IXUSR)>>6)
 #endif
 
+#ifndef FRONTEND
+/* We use only 3-parameter elog calls in this file, for simplicity */
+#define log_debug(str, param)  elog(DEBUG2, str, param)
+#else
+#define log_debug(str, param)  {}  /* do nothing */
+#endif
+
+static void win32_make_absolute(char *path);
 
 /*
- * ValidateBinary -- validate "path" as a POSTMASTER/POSTGRES executable file
+ * validate_exec -- validate "path" as an executable file
  *
  * returns 0 if the file is found and no error is encountered.
  *       -1 if the regular file "path" does not exist or cannot be executed.
  *       -2 if the file is otherwise valid but cannot be read.
  */
 static int
-ValidateBinary(char *path)
+validate_exec(char *path)
 {
    struct stat buf;
 
@@ -59,7 +72,8 @@ ValidateBinary(char *path)
 
 #ifdef WIN32
    /* Win32 requires a .exe suffix for stat() */
-   if (strlen(path) >= 4 && strcmp(path + strlen(path) - strlen(".exe"), ".exe") != 0)
+   if (strlen(path) >= strlen(".exe") &&
+       pg_strcasecmp(path + strlen(path) - strlen(".exe"), ".exe") != 0)
    {
        strcpy(path_exe, path);
        strcat(path_exe, ".exe");
@@ -75,22 +89,18 @@ ValidateBinary(char *path)
     */
    if (stat(path, &buf) < 0)
    {
-       elog(DEBUG3, "could not stat \"%s\": %m", path);
+       log_debug("could not stat \"%s\": %m", path);
        return -1;
    }
 
    if ((buf.st_mode & S_IFMT) != S_IFREG)
    {
-       elog(DEBUG3, "\"%s\" is not a regular file", path);
+       log_debug("\"%s\" is not a regular file", path);
        return -1;
    }
 
    /*
-    * Ensure that we are using an authorized backend.
-    *
-    * XXX I'm open to suggestions here.  I would like to enforce ownership
-    * of binaries by user "postgres" but people seem to like to run as
-    * users other than "postgres"...
+    * Ensure that we are using an authorized executable.
     */
 
    /*
@@ -103,23 +113,28 @@ ValidateBinary(char *path)
    return is_x ? (is_r ? 0 : -2) : -1;
 #else
    euid = geteuid();
+
+   /* If owned by us, just check owner bits */
    if (euid == buf.st_uid)
    {
        is_r = buf.st_mode & S_IRUSR;
        is_x = buf.st_mode & S_IXUSR;
        if (!(is_r && is_x))
-           elog(DEBUG3, "\"%s\" is not user read/execute", path);
+           log_debug("\"%s\" is not user read/execute", path);
        return is_x ? (is_r ? 0 : -2) : -1;
    }
-   pwp = getpwuid(euid);
+
+   /* OK, check group bits */
+   
+   pwp = getpwuid(euid);   /* not thread-safe */
    if (pwp)
    {
-       if (pwp->pw_gid == buf.st_gid)
+       if (pwp->pw_gid == buf.st_gid)  /* my primary group? */
            ++in_grp;
        else if (pwp->pw_name &&
-                (gp = getgrgid(buf.st_gid)) != NULL &&
+                (gp = getgrgid(buf.st_gid)) != NULL && /* not thread-safe */
                 gp->gr_mem != NULL)
-       {
+       {   /* try list of member groups */
            for (i = 0; gp->gr_mem[i]; ++i)
            {
                if (!strcmp(gp->gr_mem[i], pwp->pw_name))
@@ -134,28 +149,35 @@ ValidateBinary(char *path)
            is_r = buf.st_mode & S_IRGRP;
            is_x = buf.st_mode & S_IXGRP;
            if (!(is_r && is_x))
-               elog(DEBUG3, "\"%s\" is not group read/execute", path);
+               log_debug("\"%s\" is not group read/execute", path);
            return is_x ? (is_r ? 0 : -2) : -1;
        }
    }
+
+   /* Check "other" bits */
    is_r = buf.st_mode & S_IROTH;
    is_x = buf.st_mode & S_IXOTH;
    if (!(is_r && is_x))
-       elog(DEBUG3, "\"%s\" is not other read/execute", path);
+       log_debug("\"%s\" is not other read/execute", path);
    return is_x ? (is_r ? 0 : -2) : -1;
+
 #endif
 }
 
 /*
- * FindExec -- find an absolute path to a valid backend executable
+ * find_my_binary -- find an absolute path to a valid executable
  *
  * The reason we have to work so hard to find an absolute path is that
  * on some platforms we can't do dynamic loading unless we know the
  * executable's location.  Also, we need a full path not a relative
  * path because we will later change working directory.
+ *
+ * This function is not thread-safe because of it calls validate_exec(),
+ * which calls getgrgid().  This function should be used only in
+ * non-threaded binaries, not in library routines.
  */
 int
-FindExec(char *full_path, const char *argv0, const char *binary_name)
+find_my_binary(char *full_path, const char *argv0, const char *binary_name)
 {
    char        buf[MAXPGPATH + 2];
    char       *p;
@@ -164,13 +186,13 @@ FindExec(char *full_path, const char *argv0, const char *binary_name)
               *endp;
 
    /*
-    * for the postmaster: First try: use the binary that's located in the
-    * same directory as the postmaster, if it was invoked with an
-    * explicit path. Presumably the user used an explicit path because it
+    * First try: use the binary that's located in the
+    * same directory if it was invoked with an explicit path.
+    * Presumably the user used an explicit path because it
     * wasn't in PATH, and we don't want to use incompatible executables.
     *
     * This has the neat property that it works for installed binaries, old
-    * source trees (obj/support/post{master,gres}) and new marc source
+    * source trees (obj/support/post{master,gres}) and new source
     * trees (obj/post{master,gres}) because they all put the two binaries
     * in the same place.
     *
@@ -187,13 +209,14 @@ FindExec(char *full_path, const char *argv0, const char *binary_name)
        strcat(buf, argv0);
        p = last_path_separator(buf);
        strcpy(++p, binary_name);
-       if (ValidateBinary(buf) == 0)
+       if (validate_exec(buf) == 0)
        {
            strncpy(full_path, buf, MAXPGPATH);
-           elog(DEBUG2, "found \"%s\" using argv[0]", full_path);
+           win32_make_absolute(full_path);
+           log_debug("found \"%s\" using argv[0]", full_path);
            return 0;
        }
-       elog(DEBUG2, "invalid binary \"%s\"", buf);
+       log_debug("invalid binary \"%s\"", buf);
        return -1;
    }
 
@@ -203,7 +226,7 @@ FindExec(char *full_path, const char *argv0, const char *binary_name)
     */
    if ((p = getenv("PATH")) && *p)
    {
-       elog(DEBUG2, "searching PATH for executable");
+       log_debug("searching PATH for executable%s", "");
        path = strdup(p);       /* make a modifiable copy */
        for (startp = path, endp = strchr(path, PATHSEP);
             startp && *startp;
@@ -220,17 +243,18 @@ FindExec(char *full_path, const char *argv0, const char *binary_name)
            strcat(buf, startp);
            strcat(buf, "/");
            strcat(buf, binary_name);
-           switch (ValidateBinary(buf))
+           switch (validate_exec(buf))
            {
                case 0: /* found ok */
                    strncpy(full_path, buf, MAXPGPATH);
-                   elog(DEBUG2, "found \"%s\" using PATH", full_path);
+                   win32_make_absolute(full_path);
+                   log_debug("found \"%s\" using PATH", full_path);
                    free(path);
                    return 0;
                case -1:        /* wasn't even a candidate, keep looking */
                    break;
                case -2:        /* found but disqualified */
-                   elog(DEBUG2, "could not read binary \"%s\"", buf);
+                   log_debug("could not read binary \"%s\"", buf);
                    free(path);
                    return -1;
            }
@@ -240,6 +264,77 @@ FindExec(char *full_path, const char *argv0, const char *binary_name)
        free(path);
    }
 
-   elog(DEBUG2, "could not find a \"%s\" to execute", binary_name);
+   log_debug("could not find a \"%s\" to execute", binary_name);
    return -1;
 }
+
+
+/*
+ * Find our binary directory, then make sure the "target" executable
+ * is the proper version.
+ */
+int find_other_binary(char *retpath, const char *argv0, const char *progname,
+               char const *target, const char *versionstr)
+{
+   char        cmd[MAXPGPATH];
+   char        line[100];
+   FILE       *pgver;
+
+   if (find_my_binary(retpath, argv0, progname) < 0)
+       return -1;
+
+   /* Trim off program name and keep just directory */ 
+   *last_path_separator(retpath) = '\0';
+
+   snprintf(retpath + strlen(retpath), MAXPGPATH - strlen(retpath),
+            "/%s%s", target, EXE);
+
+   if (validate_exec(retpath))
+       return -1;
+   
+   snprintf(cmd, sizeof(cmd), "\"%s\" -V 2>%s", retpath, DEVNULL);
+
+   /* flush output buffers in case popen does not... */
+   fflush(stdout);
+   fflush(stderr);
+
+   if ((pgver = popen(cmd, "r")) == NULL)
+       return -1;
+
+   if (fgets(line, sizeof(line), pgver) == NULL)
+       perror("fgets failure");
+
+   if (pclose_check(pgver))
+       return -1;
+
+   if (strcmp(line, versionstr) != 0)
+       return -2;
+
+   return 0;
+}
+
+
+/*
+ * Windows doesn't like relative paths to executables (other things work fine)
+ * so we call its builtin function to expand them. Elsewhere this is a NOOP
+ *
+ * Returns malloc'ed memory.
+ */
+static void
+win32_make_absolute(char *path)
+{
+#ifdef WIN32
+   char        abspath[MAXPGPATH];
+
+   if (_fullpath(abspath, path, MAXPGPATH) == NULL)
+   {
+       log_debug("Win32 path expansion failed:  %s", strerror());
+       return path;
+   }
+   canonicalize_path(abspath);
+
+   StrNCpy(path, abspath, MAXPGPATH);
+#endif
+   return;
+}
+
index 3f672d5b22e72789646193c5a7a4e51df5ec2c87..965d63ea330f5e32be8a510b1947dfde84e393bb 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/port/path.c,v 1.5 2004/03/09 04:49:02 momjian Exp $
+ *   $PostgreSQL: pgsql/src/port/path.c,v 1.6 2004/05/11 21:57:15 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -121,3 +121,4 @@ get_progname(char *argv0)
    else
        return last_path_separator(argv0) + 1;
 }
+
index 4a707f7335c677a6d30a0fb21452391581833c50..9fdab8ca738777e8d804c980ab76b6c0dae643d2 100644 (file)
  * must be replaced with recv/send.
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/port/pipe.c,v 1.2 2004/04/19 17:42:59 momjian Exp $
+ *   $PostgreSQL: pgsql/src/port/pipe.c,v 1.3 2004/05/11 21:57:15 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
 
 #include "postgres.h"
 
+#include <sys/wait.h>
+
+#define _(x) gettext((x))
+
+#ifdef WIN32
 int
 pgpipe(int handles[2])
 {
@@ -63,3 +68,42 @@ int piperead(int s, char* buf, int len)
        ret = 0;
    return ret;
 }
+#endif
+
+/*
+ * pclose() plus useful error reporting
+ * Is this necessary?  bjm 2004-05-11
+ */
+int
+pclose_check(FILE *stream)
+{
+   int     exitstatus;
+
+   exitstatus = pclose(stream);
+
+   if (exitstatus == 0)
+       return 0;                   /* all is well */
+
+   if (exitstatus == -1)
+   {
+       /* pclose() itself failed, and hopefully set errno */
+       perror("pclose failed");
+   }
+   else if (WIFEXITED(exitstatus))
+   {
+       fprintf(stderr, _("child process exited with exit code %d\n"),
+               WEXITSTATUS(exitstatus));
+   }
+   else if (WIFSIGNALED(exitstatus))
+   {
+       fprintf(stderr, _("child process was terminated by signal %d\n"),
+               WTERMSIG(exitstatus));
+   }
+   else
+   {
+       fprintf(stderr, _("child process exited with unrecognized status %d\n"),
+               exitstatus);
+   }
+
+   return -1;
+}