diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c
index aab0c21230e843dbca7b287a6c32acb1545fa419..de4cc3dd994f2dc4415c9e38f3805be66a2760e7 100644
--- a/src/backend/bootstrap/bootstrap.c
+++ b/src/backend/bootstrap/bootstrap.c
@@ -8,10 +8,12 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.95 2000/10/24 09:56:09 vadim Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.96 2000/11/04 12:43:23 petere Exp $
  *
  *-------------------------------------------------------------------------
  */
+#include "postgres.h"
+
 #include <unistd.h>
 #include <time.h>
 #include <signal.h>
@@ -19,7 +21,6 @@
 
 #define BOOTSTRAP_INCLUDE		/* mask out stuff in tcop/tcopprot.h */
 
-#include "postgres.h"
 #ifdef HAVE_GETOPT_H
 #include <getopt.h>
 #endif
@@ -220,6 +221,7 @@ BootstrapMain(int argc, char *argv[])
 	char	   *dbName;
 	int			flag;
 	bool		xloginit = false;
+	char       *potential_DataDir = NULL;
 
 	extern int	optind;
 	extern char *optarg;
@@ -255,7 +257,7 @@ BootstrapMain(int argc, char *argv[])
 	if (!IsUnderPostmaster)
 	{
 		ResetAllOptions();
-		DataDir = getenv("PGDATA"); /* Null if no PGDATA variable */
+		potential_DataDir = getenv("PGDATA"); /* Null if no PGDATA variable */
 	}
 
 	while ((flag = getopt(argc, argv, "D:dCQxpB:F")) != EOF)
@@ -263,7 +265,7 @@ BootstrapMain(int argc, char *argv[])
 		switch (flag)
 		{
 			case 'D':
-				DataDir = optarg;
+				potential_DataDir = optarg;
 				break;
 			case 'd':
 				DebugMode = true;		/* print out debugging info while
@@ -301,15 +303,20 @@ BootstrapMain(int argc, char *argv[])
 	SetProcessingMode(BootstrapProcessing);
 	IgnoreSystemIndexes(true);
 
-	if (!DataDir)
+	if (!IsUnderPostmaster)
 	{
-		fprintf(stderr, "%s does not know where to find the database system "
-				"data.  You must specify the directory that contains the "
-				"database system either by specifying the -D invocation "
-			 "option or by setting the PGDATA environment variable.\n\n",
-				argv[0]);
-		proc_exit(1);
+		if (!potential_DataDir)
+		{
+			fprintf(stderr, "%s does not know where to find the database system "
+					"data.  You must specify the directory that contains the "
+					"database system either by specifying the -D invocation "
+					"option or by setting the PGDATA environment variable.\n\n",
+					argv[0]);
+			proc_exit(1);
+		}
+		SetDataDir(potential_DataDir);
 	}
+	Assert(DataDir);
 
 	if (dbName == NULL)
 	{
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index eb7daeb7dbee14d51e234f43c21a6f7a422dbf65..060b0e5ef40c73c64d8c95697d81fbbba98d256a 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.177 2000/11/01 21:14:02 petere Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.178 2000/11/04 12:43:23 petere Exp $
  *
  * NOTES
  *
@@ -268,12 +268,12 @@ extern void GetCharSetByHost(char *, int, char *);
 
 
 static void
-checkDataDir(const char *DataDir)
+checkDataDir(const char *checkdir)
 {
 	char		path[MAXPGPATH];
 	FILE	   *fp;
 
-	if (DataDir == NULL)
+	if (checkdir == NULL)
 	{
 		fprintf(stderr, "%s does not know where to find the database system "
 				"data.  You must specify the directory that contains the "
@@ -285,10 +285,10 @@ checkDataDir(const char *DataDir)
 
 #ifdef OLD_FILE_NAMING
 	snprintf(path, sizeof(path), "%s%cbase%ctemplate1%cpg_class",
-			 DataDir, SEP_CHAR, SEP_CHAR, SEP_CHAR);
+			 checkdir, SEP_CHAR, SEP_CHAR, SEP_CHAR);
 #else
 	snprintf(path, sizeof(path), "%s%cbase%c%u%c%u",
-			 DataDir, SEP_CHAR, SEP_CHAR, 
+			 checkdir, SEP_CHAR, SEP_CHAR, 
 			 TemplateDbOid, SEP_CHAR, RelOid_pg_class);
 #endif
 
@@ -298,13 +298,13 @@ checkDataDir(const char *DataDir)
 		fprintf(stderr, "%s does not find the database system."
 				"\n\tExpected to find it in the PGDATA directory \"%s\","
 				"\n\tbut unable to open file \"%s\": %s\n\n",
-				progname, DataDir, path, strerror(errno));
+				progname, checkdir, path, strerror(errno));
 		exit(2);
 	}
 
 	FreeFile(fp);
 
-	ValidatePgVersion(DataDir);
+	ValidatePgVersion(checkdir);
 }
 
 
@@ -314,6 +314,7 @@ PostmasterMain(int argc, char *argv[])
 	int			opt;
 	int			status;
 	char		original_extraoptions[MAXPGPATH];
+	char       *potential_DataDir = NULL;
 
 	IsUnderPostmaster = true;	/* so that backends know this */
 
@@ -353,8 +354,7 @@ PostmasterMain(int argc, char *argv[])
 	/*
 	 * Options setup
 	 */
-	if (getenv("PGDATA"))
-		DataDir = strdup(getenv("PGDATA")); /* default value */
+	potential_DataDir = getenv("PGDATA"); /* default value */
 
 	ResetAllOptions();
 
@@ -377,9 +377,7 @@ PostmasterMain(int argc, char *argv[])
 		switch(opt)
 		{
 			case 'D':
-				if (DataDir)
-					free(DataDir);
-				DataDir = strdup(optarg);
+				potential_DataDir = optarg;
 				break;
 
 			case '-':
@@ -415,12 +413,14 @@ PostmasterMain(int argc, char *argv[])
 		}
 	}
 
-	optind = 1; /* start over */
-	checkDataDir(DataDir);	/* issues error messages */
+	checkDataDir(potential_DataDir);	/* issues error messages */
+	SetDataDir(potential_DataDir);
 
 	ProcessConfigFile(PGC_POSTMASTER);
 
 	IgnoreSystemIndexes(false);
+
+	optind = 1; /* start over */
 	while ((opt = getopt(argc, argv, "A:a:B:b:D:d:Film:MN:no:p:Ss-:?")) != EOF)
 	{
 		switch (opt)
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index b024d604dc899154da0c75eff2813837034ad3a2..29192686e6c99788919b7c750438f4ecf8da389c 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.184 2000/10/28 18:27:56 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.185 2000/11/04 12:43:24 petere Exp $
  *
  * NOTES
  *	  this is the "main" module of the postgres backend and
@@ -29,7 +29,7 @@
 #include <errno.h>
 #if HAVE_SYS_SELECT_H
 #include <sys/select.h>
-#endif	 /* aix */
+#endif
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <netdb.h>
@@ -1058,6 +1058,8 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[], const cha
 	char	   *remote_host;
 	unsigned short remote_port;
 
+	char       *potential_DataDir = NULL;
+
 	extern int	optind;
 	extern char *optarg;
 	extern int	DebugLvl;
@@ -1082,8 +1084,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[], const cha
 	if (!IsUnderPostmaster)
 	{
 		ResetAllOptions();
-		if (getenv("PGDATA"))
-			DataDir = strdup(getenv("PGDATA"));
+		potential_DataDir = getenv("PGDATA");
 	}
 	StatFp = stderr;
 
@@ -1142,9 +1143,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[], const cha
 			case 'D':			/* PGDATA directory */
 				if (secure)
 				{
-					if (DataDir)
-						free(DataDir);
-					DataDir = strdup(optarg);
+					potential_DataDir = optarg;
 				}
 				break;
 
@@ -1429,15 +1428,20 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[], const cha
 		Show_query_stats = false;
 	}
 
-	if (!DataDir)
+	if (!IsUnderPostmaster)
 	{
-		fprintf(stderr, "%s does not know where to find the database system "
-				"data.  You must specify the directory that contains the "
-				"database system either by specifying the -D invocation "
-			 "option or by setting the PGDATA environment variable.\n\n",
-				argv[0]);
-		proc_exit(1);
+		if (!potential_DataDir)
+		{
+			fprintf(stderr, "%s does not know where to find the database system "
+					"data.  You must specify the directory that contains the "
+					"database system either by specifying the -D invocation "
+					"option or by setting the PGDATA environment variable.\n\n",
+					argv[0]);
+			proc_exit(1);
+		}
+		SetDataDir(potential_DataDir);
 	}
+	Assert(DataDir);
 
 	/*
 	 * 1. Set BlockSig and UnBlockSig masks. 2. Set up signal handlers. 3.
@@ -1631,7 +1635,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[], const cha
 	if (!IsUnderPostmaster)
 	{
 		puts("\nPOSTGRES backend interactive interface ");
-		puts("$Revision: 1.184 $ $Date: 2000/10/28 18:27:56 $\n");
+		puts("$Revision: 1.185 $ $Date: 2000/11/04 12:43:24 $\n");
 	}
 
 	/*
diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c
index 0974a05715981a9f37f44728fda18bc93eafc1df..026f2cc8114af34d0c06509f7ef20d776106aeec 100644
--- a/src/backend/utils/init/miscinit.c
+++ b/src/backend/utils/init/miscinit.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.55 2000/09/19 18:17:57 petere Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.56 2000/11/04 12:43:24 petere Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -366,6 +366,62 @@ GetUserName(Oid userid)
 
 
 
+/*-------------------------------------------------------------------------
+ * Set data directory, but make sure it's an absolute path.  Use this,
+ * never set DataDir directly.
+ *-------------------------------------------------------------------------
+ */
+void
+SetDataDir(const char *dir)
+{
+	char *new;
+
+	AssertArg(dir);
+	if (DataDir)
+		free(DataDir);
+
+	if (dir[0] != '/')
+	{
+		char *buf;
+		size_t buflen;
+
+		buflen = MAXPGPATH;
+		for (;;)
+		{
+			buf = malloc(buflen);
+			if (!buf)
+				elog(FATAL, "out of memory");
+
+			if (getcwd(buf, buflen))
+				break;
+			else if (errno == ERANGE)
+			{
+				free(buf);
+				buflen *= 2;
+				continue;
+			}
+			else
+			{
+				free(buf);
+				elog(FATAL, "cannot get current working directory: %m");
+			}
+		}
+
+		new = malloc(strlen(buf) + 1 + strlen(dir) + 1);
+		sprintf(new, "%s/%s", buf, dir);
+	}
+	else
+	{
+		new = strdup(dir);
+	}
+
+	if (!new)
+		elog(FATAL, "out of memory");
+	DataDir = new;		
+}
+
+
+
 /*-------------------------------------------------------------------------
  *
  * postmaster pid file stuffs. $DATADIR/postmaster.pid is created when:
diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h
index fcced217efb928c6ec2fdadd801e563c4b29b045..6e6436d1528dc1b95bb95baae5526993cdf21d70 100644
--- a/src/include/miscadmin.h
+++ b/src/include/miscadmin.h
@@ -12,7 +12,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: miscadmin.h,v 1.68 2000/10/08 09:25:38 ishii Exp $
+ * $Id: miscadmin.h,v 1.69 2000/11/04 12:43:24 petere Exp $
  *
  * NOTES
  *	  some of the information in this file will be moved to
@@ -137,6 +137,8 @@ extern Oid GetSessionUserId(void);
 extern void SetSessionUserId(Oid userid);
 extern void SetSessionUserIdFromUserName(const char *username);
 
+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);