mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-21 08:29:39 +08:00
Make sure -D is an absolute path when starting server on Windows.
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
This commit is contained in:
parent
8120c7452a
commit
9aca512506
@ -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
|
||||
|
@ -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");
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
111
src/port/path.c
111
src/port/path.c
@ -13,7 +13,11 @@
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#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
|
||||
*/
|
||||
|
@ -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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user