]> granicus.if.org Git - postgresql/commitdiff
Make sure -D is an absolute path when starting server on Windows.
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 4 Apr 2014 22:42:13 +0000 (18:42 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 4 Apr 2014 22:42:13 +0000 (18:42 -0400)
This is needed because Windows services may get started with a different
current directory than where pg_ctl is executed.  We want relative -D
paths to be interpreted relative to pg_ctl's CWD, similarly to what
happens on other platforms.

In support of this, move the backend's make_absolute_path() function
into src/port/path.c (where it probably should have been long since)
and get rid of the rather inferior version in pg_regress.

Kumar Rajeev Rastogi, reviewed by MauMau

src/backend/utils/init/miscinit.c
src/bin/pg_ctl/pg_ctl.c
src/include/miscadmin.h
src/include/port.h
src/port/path.c
src/test/regress/pg_regress.c

index c17bca8306161b143f1515ab8cd0db76171d89b2..6115ce3f3373640d48bc9be9d0c0ab7858f69122 100644 (file)
@@ -117,77 +117,6 @@ ChangeToDataDir(void)
                                                DataDir)));
 }
 
-/*
- * If the given pathname isn't already absolute, make it so, interpreting
- * it relative to the current working directory.
- *
- * Also canonicalizes the path.  The result is always a malloc'd copy.
- *
- * Note: interpretation of relative-path arguments during postmaster startup
- * should happen before doing ChangeToDataDir(), else the user will probably
- * not like the results.
- */
-char *
-make_absolute_path(const char *path)
-{
-       char       *new;
-
-       /* Returning null for null input is convenient for some callers */
-       if (path == NULL)
-               return NULL;
-
-       if (!is_absolute_path(path))
-       {
-               char       *buf;
-               size_t          buflen;
-
-               buflen = MAXPGPATH;
-               for (;;)
-               {
-                       buf = malloc(buflen);
-                       if (!buf)
-                               ereport(FATAL,
-                                               (errcode(ERRCODE_OUT_OF_MEMORY),
-                                                errmsg("out of memory")));
-
-                       if (getcwd(buf, buflen))
-                               break;
-                       else if (errno == ERANGE)
-                       {
-                               free(buf);
-                               buflen *= 2;
-                               continue;
-                       }
-                       else
-                       {
-                               free(buf);
-                               elog(FATAL, "could not get current working directory: %m");
-                       }
-               }
-
-               new = malloc(strlen(buf) + strlen(path) + 2);
-               if (!new)
-                       ereport(FATAL,
-                                       (errcode(ERRCODE_OUT_OF_MEMORY),
-                                        errmsg("out of memory")));
-               sprintf(new, "%s/%s", buf, path);
-               free(buf);
-       }
-       else
-       {
-               new = strdup(path);
-               if (!new)
-                       ereport(FATAL,
-                                       (errcode(ERRCODE_OUT_OF_MEMORY),
-                                        errmsg("out of memory")));
-       }
-
-       /* Make sure punctuation is canonical, too */
-       canonicalize_path(new);
-
-       return new;
-}
-
 
 /* ----------------------------------------------------------------
  *     User ID state
index 56d238f39481da3c8bd5043e8889a3e58cfdca84..1f921819c23563bc9068fb1bab83ba2bec61627d 100644 (file)
@@ -1387,7 +1387,19 @@ pgwin32_CommandLine(bool registration)
                                                  register_servicename);
 
        if (pg_config)
-               appendPQExpBuffer(cmdLine, " -D \"%s\"", pg_config);
+       {
+               /* We need the -D path to be absolute */
+               char       *dataDir;
+
+               if ((dataDir = make_absolute_path(pg_config)) == NULL)
+               {
+                       /* make_absolute_path already reported the error */
+                       exit(1);
+               }
+               make_native_path(dataDir);
+               appendPQExpBuffer(cmdLine, " -D \"%s\"", dataDir);
+               free(dataDir);
+       }
 
        if (registration && do_wait)
                appendPQExpBuffer(cmdLine, " -w");
index 947906a280546b81a855f4ebfcb3f4c80889abcc..0d61b82eb50d9df67c16a2c8dca6fdbe52535f26 100644 (file)
@@ -296,7 +296,6 @@ extern void SetCurrentRoleId(Oid roleid, bool is_superuser);
 
 extern void SetDataDir(const char *dir);
 extern void ChangeToDataDir(void);
-extern char *make_absolute_path(const char *path);
 
 /* in utils/misc/superuser.c */
 extern bool superuser(void);   /* current user is superuser */
index aeb7754cb0940b4fb0355ba015f98f3ab40fc681..06986858b60d88d459190f1e2ca8918618da9882 100644 (file)
@@ -45,6 +45,7 @@ extern void make_native_path(char *path);
 extern bool path_contains_parent_reference(const char *path);
 extern bool path_is_relative_and_below_cwd(const char *path);
 extern bool path_is_prefix_of_path(const char *path1, const char *path2);
+extern char *make_absolute_path(const 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);
index 39d6e43404a65eca8b41de7ead942ba04c709bbb..438b52960423bfec077e78e7d80246fffa4899ac 100644 (file)
  *-------------------------------------------------------------------------
  */
 
-#include "c.h"
+#ifndef FRONTEND
+#include "postgres.h"
+#else
+#include "postgres_fe.h"
+#endif
 
 #include <ctype.h>
 #include <sys/stat.h>
@@ -549,6 +553,111 @@ no_match:
 }
 
 
+/*
+ * make_absolute_path
+ *
+ * If the given pathname isn't already absolute, make it so, interpreting
+ * it relative to the current working directory.
+ *
+ * Also canonicalizes the path.  The result is always a malloc'd copy.
+ *
+ * In backend, failure cases result in ereport(ERROR); in frontend,
+ * we write a complaint on stderr and return NULL.
+ *
+ * Note: interpretation of relative-path arguments during postmaster startup
+ * should happen before doing ChangeToDataDir(), else the user will probably
+ * not like the results.
+ */
+char *
+make_absolute_path(const char *path)
+{
+       char       *new;
+
+       /* Returning null for null input is convenient for some callers */
+       if (path == NULL)
+               return NULL;
+
+       if (!is_absolute_path(path))
+       {
+               char       *buf;
+               size_t          buflen;
+
+               buflen = MAXPGPATH;
+               for (;;)
+               {
+                       buf = malloc(buflen);
+                       if (!buf)
+                       {
+#ifndef FRONTEND
+                               ereport(ERROR,
+                                               (errcode(ERRCODE_OUT_OF_MEMORY),
+                                                errmsg("out of memory")));
+#else
+                               fprintf(stderr, _("out of memory\n"));
+                               return NULL;
+#endif
+                       }
+
+                       if (getcwd(buf, buflen))
+                               break;
+                       else if (errno == ERANGE)
+                       {
+                               free(buf);
+                               buflen *= 2;
+                               continue;
+                       }
+                       else
+                       {
+                               free(buf);
+#ifndef FRONTEND
+                               elog(ERROR, "could not get current working directory: %m");
+#else
+                               fprintf(stderr, _("could not get current working directory: %s\n"),
+                                               strerror(errno));
+                               return NULL;
+#endif
+                       }
+               }
+
+               new = malloc(strlen(buf) + strlen(path) + 2);
+               if (!new)
+               {
+                       free(buf);
+#ifndef FRONTEND
+                       ereport(ERROR,
+                                       (errcode(ERRCODE_OUT_OF_MEMORY),
+                                        errmsg("out of memory")));
+#else
+                       fprintf(stderr, _("out of memory\n"));
+                       return NULL;
+#endif
+               }
+               sprintf(new, "%s/%s", buf, path);
+               free(buf);
+       }
+       else
+       {
+               new = strdup(path);
+               if (!new)
+               {
+#ifndef FRONTEND
+                       ereport(ERROR,
+                                       (errcode(ERRCODE_OUT_OF_MEMORY),
+                                        errmsg("out of memory")));
+#else
+                       fprintf(stderr, _("out of memory\n"));
+                       return NULL;
+#endif
+               }
+       }
+
+       /* Make sure punctuation is canonical, too */
+       canonicalize_path(new);
+
+       return new;
+}
+
+
 /*
  *     get_share_path
  */
index abde5b477c670068e051315e04650af365b2a92f..07dd8037ac3f3323a869cc8bbaa1aad37302061d 100644 (file)
@@ -1855,33 +1855,6 @@ create_role(const char *rolename, const _stringlist * granted_dbs)
        }
 }
 
-static char *
-make_absolute_path(const char *in)
-{
-       char       *result;
-
-       if (is_absolute_path(in))
-               result = strdup(in);
-       else
-       {
-               static char cwdbuf[MAXPGPATH];
-
-               if (!cwdbuf[0])
-               {
-                       if (!getcwd(cwdbuf, sizeof(cwdbuf)))
-                       {
-                               fprintf(stderr, _("could not get current working directory: %s\n"), strerror(errno));
-                               exit(2);
-                       }
-               }
-
-               result = psprintf("%s/%s", cwdbuf, in);
-       }
-
-       canonicalize_path(result);
-       return result;
-}
-
 static void
 help(void)
 {