[review] PostgreSQL Service on Windows does not start if data directory given is relative path
Hi Rajeev san,
I reviewed the patch content. I find this fix useful.
I'd like to suggest some code improvements. I'll apply and test the patch
when I receive your reply.
(1)
I think it is appropriate to place find_my_abs_path() in path.c rather than
exec.c. Please look at the comments at the beginning of those files.
exec.c handles functions related to executables, while path.c handles
general functions handling paths.
It's better to rename the function to follow the naming of other functions
in path.c, something like get_absolute_path() or so. Unfortunately, we
cannot use make_absolute_path() as the name because it is used in
src/backend/utils/init/miscinit.c, which conflicts in the backend module.
(2)
In pg_ctl.c, dbpath can be better named as datadir, because it holds data
directory location. dbpath is used to mean some different location in other
source files.
(3)
find_my_abs_path() had better not call make_native_path() because the role
of this function should be to just return an absolute path. pg_ctl.c can
instead call make_native_path() after find_my_abs_path().
(4)
find_my_abs_path() should not call resolve_symlinks(). For reference, look
at make_absolute_path() in src/backend/utils/init/miscinit.c and
src/test/regress/pg_regress.c. I guess the reason is that if the user
changed to the directory through a symbolic link, we should retain the
symbolic link name.
(5)
Change "file/path" in the comment of find_my_abs_path() to "path", because
file is also a path.
Regards
MauMau
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 1st February 2014, MauMau Wrote:
I reviewed the patch content. I find this fix useful.
I'd like to suggest some code improvements. I'll apply and test the
patch when I receive your reply.
Thanks for reviewing the patch.
(1)
I think it is appropriate to place find_my_abs_path() in path.c rather
than
exec.c. Please look at the comments at the beginning of those files.
exec.c handles functions related to executables, while path.c handles
general functions handling paths.
I have moved this function to path.c
It's better to rename the function to follow the naming of other
functions
in path.c, something like get_absolute_path() or so. Unfortunately, we
cannot use make_absolute_path() as the name because it is used in
src/backend/utils/init/miscinit.c, which conflicts in the backend
module.
Renamed the function as get_absolute_path.
(2)
In pg_ctl.c, dbpath can be better named as datadir, because it holds
data
directory location. dbpath is used to mean some different location in
other
source files.
Renamed as dataDir.
(3)
find_my_abs_path() had better not call make_native_path() because the
role
of this function should be to just return an absolute path. pg_ctl.c
can
instead call make_native_path() after find_my_abs_path().
Changed as per suggestion.
(4)
find_my_abs_path() should not call resolve_symlinks(). For reference,
look
at make_absolute_path() in src/backend/utils/init/miscinit.c and
src/test/regress/pg_regress.c. I guess the reason is that if the user
changed to the directory through a symbolic link, we should retain the
symbolic link name.
Changed as per suggestion.
(5)
Change "file/path" in the comment of find_my_abs_path() to "path",
because
file is also a path.
Changed as per suggestion.
Please find the attached revised patch.
Thanks and Regards,
Kumar Rajeev Rastogi
Attachments:
pgctl_win32service_rel_dbpath_v3.patchapplication/octet-stream; name=pgctl_win32service_rel_dbpath_v3.patchDownload
*** a/src/bin/pg_ctl/pg_ctl.c
--- b/src/bin/pg_ctl/pg_ctl.c
***************
*** 1326,1332 **** pgwin32_CommandLine(bool registration)
register_servicename);
if (pg_config)
! appendPQExpBuffer(cmdLine, " -D \"%s\"", pg_config);
if (registration && do_wait)
appendPQExpBuffer(cmdLine, " -w");
--- 1326,1344 ----
register_servicename);
if (pg_config)
! {
! char dataDir[MAXPGPATH];
!
! if (get_absolute_path(pg_config, dataDir) != 0)
! {
! write_stderr(_("%s: could not identify current directory\n"),
! progname);
! exit(1);
! }
!
! make_native_path(dataDir);
! appendPQExpBuffer(cmdLine, " -D \"%s\"", dataDir);
! }
if (registration && do_wait)
appendPQExpBuffer(cmdLine, " -w");
*** a/src/include/port.h
--- b/src/include/port.h
***************
*** 59,64 **** extern void get_html_path(const char *my_exec_path, char *ret_path);
--- 59,65 ----
extern void get_man_path(const char *my_exec_path, char *ret_path);
extern bool get_home_path(char *ret_path);
extern void get_parent_directory(char *path);
+ extern int get_absolute_path(char *inpath, char *retpath);
/* port/dirmod.c */
extern char **pgfnames(const char *path);
*** a/src/port/path.c
--- b/src/port/path.c
***************
*** 757,759 **** trim_trailing_separator(char *path)
--- 757,788 ----
for (p--; p > path && IS_DIR_SEP(*p); p--)
*p = '\0';
}
+
+ /*
+ * get_absolute_path -- get an absolute path to a given path
+ *
+ * inpath is the input path for which absolute path required.
+ * retpath is the output area (must be of size MAXPGPATH)
+ * Returns 0 if OK, -1 if error.
+ */
+ int
+ get_absolute_path(char *inpath, char *retpath)
+ {
+ /*
+ * Check if it is already absolute path.
+ */
+ if (is_absolute_path(inpath))
+ {
+ strlcpy(retpath, inpath, MAXPGPATH);
+ }
+ else
+ {
+ if (!getcwd(retpath, MAXPGPATH))
+ return -1;
+
+ join_path_components(retpath, retpath, inpath);
+ canonicalize_path(retpath);
+ }
+
+ return 0;
+ }
From: "Rajeev rastogi" <rajeev.rastogi@huawei.com>
Please find the attached revised patch.
Thanks, your patch looks good. I confirmed the following:
* Applied cleanly to the latest source tree, and built on Linux and Windows
(with MSVC) without any warnings.
* Changed to D:\ and ran "pg_ctl register -N pg -D pgdata", and checked the
registry value ImagePath with regedit. It contained -D "D:\pgdata".
* Changed to D:\pgdata and ran "pg_ctl register -N pg -D ..\pgdata", and
checked the registry value ImagePath with regedit. It contained -D
"D:\pgdata".
Finally, please change the function description comment of
get_absolute_path() so that the style follows other function in path.c.
That is:
/*
* <function_name>
*
* Function description
*/
Then update the CommitFest entry with the latest patch and let me know of
that. Then, I'll change the patch status to ready for committer.
Regards
MauMau
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 3rd February 2014, MauMau Wrote:
Thanks, your patch looks good. I confirmed the following:
* Applied cleanly to the latest source tree, and built on Linux and
Windows (with MSVC) without any warnings.* Changed to D:\ and ran "pg_ctl register -N pg -D pgdata", and checked
the registry value ImagePath with regedit. It contained -D "D:\pgdata".* Changed to D:\pgdata and ran "pg_ctl register -N pg -D ..\pgdata",
and checked the registry value ImagePath with regedit. It contained -D
"D:\pgdata".
Thanks for reviewing and testing the patch.
Finally, please change the function description comment of
get_absolute_path() so that the style follows other function in path.c.
That is:/*
* <function_name>
*
* Function description
*/
I have modified the function description comment as per your suggestion.
Then update the CommitFest entry with the latest patch and let me know
of that. Then, I'll change the patch status to ready for committer.
I will update commitFest with the latest patch immediately after sending the mail.
Thanks and Regards,
Kumar Rajeev Rastogi
Attachments:
pgctl_win32service_rel_dbpath_v4.patchapplication/octet-stream; name=pgctl_win32service_rel_dbpath_v4.patchDownload
*** a/src/bin/pg_ctl/pg_ctl.c
--- b/src/bin/pg_ctl/pg_ctl.c
***************
*** 1326,1332 **** pgwin32_CommandLine(bool registration)
register_servicename);
if (pg_config)
! appendPQExpBuffer(cmdLine, " -D \"%s\"", pg_config);
if (registration && do_wait)
appendPQExpBuffer(cmdLine, " -w");
--- 1326,1344 ----
register_servicename);
if (pg_config)
! {
! char dataDir[MAXPGPATH];
!
! if (get_absolute_path(pg_config, dataDir) != 0)
! {
! write_stderr(_("%s: could not identify current directory\n"),
! progname);
! exit(1);
! }
!
! make_native_path(dataDir);
! appendPQExpBuffer(cmdLine, " -D \"%s\"", dataDir);
! }
if (registration && do_wait)
appendPQExpBuffer(cmdLine, " -w");
*** a/src/include/port.h
--- b/src/include/port.h
***************
*** 59,64 **** extern void get_html_path(const char *my_exec_path, char *ret_path);
--- 59,65 ----
extern void get_man_path(const char *my_exec_path, char *ret_path);
extern bool get_home_path(char *ret_path);
extern void get_parent_directory(char *path);
+ extern int get_absolute_path(char *inpath, char *retpath);
/* port/dirmod.c */
extern char **pgfnames(const char *path);
*** a/src/port/path.c
--- b/src/port/path.c
***************
*** 757,759 **** trim_trailing_separator(char *path)
--- 757,789 ----
for (p--; p > path && IS_DIR_SEP(*p); p--)
*p = '\0';
}
+
+ /*
+ * get_absolute_path
+ *
+ * Get an absolute path to a given path.
+ * inpath is the input path for which absolute path required.
+ * retpath is the output area (must be of size MAXPGPATH)
+ * Returns 0 if OK, -1 if error.
+ */
+ int
+ get_absolute_path(char *inpath, char *retpath)
+ {
+ /*
+ * Check if it is already absolute path.
+ */
+ if (is_absolute_path(inpath))
+ {
+ strlcpy(retpath, inpath, MAXPGPATH);
+ }
+ else
+ {
+ if (!getcwd(retpath, MAXPGPATH))
+ return -1;
+
+ join_path_components(retpath, retpath, inpath);
+ canonicalize_path(retpath);
+ }
+
+ return 0;
+ }
From: "Rajeev rastogi" <rajeev.rastogi@huawei.com>
I will update commitFest with the latest patch immediately after sending
the mail.
OK, done setting the status to ready for committer.
Regards
MauMau
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Mon, Feb 3, 2014 at 3:06 PM, MauMau <maumau307@gmail.com> wrote:
From: "Rajeev rastogi" <rajeev.rastogi@huawei.com>
I will update commitFest with the latest patch immediately after sending
the mail.
OK, done setting the status to ready for committer.
We already have two different versions of make_absolute_path() in the tree
- one in src/backend/utils/init/miscinit.c and one in
src/test/regress/pg_regress.c.
I don't think we need a third one.
If we put it in port/ like this patch done, then we should make the other
callers use it. We might need one for frontend and one for backend (I
haven't looked into that much detail), but definitely the one between
pg_regress and pg_ctl should be shared.
--
Magnus Hagander
Me: http://www.hagander.net/
Work: http://www.redpill-linpro.com/
From: "Magnus Hagander" <magnus@hagander.net>
We already have two different versions of make_absolute_path() in the tree
- one in src/backend/utils/init/miscinit.c and one in
src/test/regress/pg_regress.c.I don't think we need a third one.
If we put it in port/ like this patch done, then we should make the other
callers use it. We might need one for frontend and one for backend (I
haven't looked into that much detail), but definitely the one between
pg_regress and pg_ctl should be shared.
Agreed. Sorry, I should have proposed the refactoring.
Rajeev, could you refactor the code so that there is only one
make_absolute_path()? I think we can do like this:
1. Delete get_absolute_path() in src/port/path.c.
2. Delete make_absolute_path() in src/test/regress/pg_regress.c.
3. Move make_absolute_path() from src/backend/utils/init/miscinit.c to
src/port/path.c, and delete the declaration in miscadmin.h.
4. Modify make_absolute_path() in path.c so that it can be used both in
backend and frontend. That is, surround the error message output with
#ifdef FRONTEND ... #else ... #endif. See some other source files in
src/port.
Regards
MauMau
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 18 February 2014 21:47, MauMau Wrote:
We already have two different versions of make_absolute_path() in the
tree
- one in src/backend/utils/init/miscinit.c and one in
src/test/regress/pg_regress.c.I don't think we need a third one.
If we put it in port/ like this patch done, then we should make the
other callers use it. We might need one for frontend and one for
backend (I haven't looked into that much detail), but definitely the
one between pg_regress and pg_ctl should be shared.Agreed. Sorry, I should have proposed the refactoring.
Rajeev, could you refactor the code so that there is only one
make_absolute_path()? I think we can do like this:1. Delete get_absolute_path() in src/port/path.c.
2. Delete make_absolute_path() in src/test/regress/pg_regress.c.
3. Move make_absolute_path() from src/backend/utils/init/miscinit.c to
src/port/path.c, and delete the declaration in miscadmin.h.
4. Modify make_absolute_path() in path.c so that it can be used both in
backend and frontend. That is, surround the error message output with
#ifdef FRONTEND ... #else ... #endif. See some other source files in
src/port.
Changed the patch as per your suggestion.
Now only one version of make_absolute_path there defined in src/port/path.c
Found one small memory leak in the existing function make_absolute_path(miscinit.c),
fixed the same.
Please find the revised patch.
Thanks and Regards,
Kumar Rajeev Rastogi
Attachments:
pgctl_win32service_rel_dbpath_v5.patchapplication/octet-stream; name=pgctl_win32service_rel_dbpath_v5.patchDownload
*** a/src/backend/utils/init/miscinit.c
--- b/src/backend/utils/init/miscinit.c
***************
*** 117,194 **** 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
*
--- 117,122 ----
*** a/src/bin/pg_ctl/pg_ctl.c
--- b/src/bin/pg_ctl/pg_ctl.c
***************
*** 1326,1332 **** pgwin32_CommandLine(bool registration)
register_servicename);
if (pg_config)
! appendPQExpBuffer(cmdLine, " -D \"%s\"", pg_config);
if (registration && do_wait)
appendPQExpBuffer(cmdLine, " -w");
--- 1326,1345 ----
register_servicename);
if (pg_config)
! {
! char *dataDir;
!
! if ((dataDir = make_absolute_path(pg_config)) == NULL)
! {
! write_stderr(_("%s: could not identify current directory\n"),
! progname);
! exit(1);
! }
!
! make_native_path(dataDir);
! appendPQExpBuffer(cmdLine, " -D \"%s\"", dataDir);
! free(dataDir);
! }
if (registration && do_wait)
appendPQExpBuffer(cmdLine, " -w");
*** a/src/include/miscadmin.h
--- b/src/include/miscadmin.h
***************
*** 296,302 **** 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 */
--- 296,301 ----
*** a/src/include/port.h
--- b/src/include/port.h
***************
*** 60,65 **** extern void get_man_path(const char *my_exec_path, char *ret_path);
--- 60,67 ----
extern bool get_home_path(char *ret_path);
extern void get_parent_directory(char *path);
+ extern char *make_absolute_path(const char *path);
+
/* port/dirmod.c */
extern char **pgfnames(const char *path);
extern void pgfnames_cleanup(char **filenames);
*** a/src/port/path.c
--- b/src/port/path.c
***************
*** 13,19 ****
*-------------------------------------------------------------------------
*/
! #include "c.h"
#include <ctype.h>
#include <sys/stat.h>
--- 13,23 ----
*-------------------------------------------------------------------------
*/
! #ifndef FRONTEND
! #include "postgres.h"
! #else
! #include "postgres_fe.h"
! #endif
#include <ctype.h>
#include <sys/stat.h>
***************
*** 757,759 **** trim_trailing_separator(char *path)
--- 761,864 ----
for (p--; p > path && IS_DIR_SEP(*p); p--)
*p = '\0';
}
+
+ /*
+ * 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)
+ {
+ #ifndef FRONTEND
+ ereport(FATAL,
+ (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(FATAL, "could not get current working directory: %m");
+ #else
+ fprintf(stderr, _("could not get current working directory\n"));
+ return NULL;
+ #endif
+
+ }
+ }
+
+ new = malloc(strlen(buf) + strlen(path) + 2);
+ if (!new)
+ {
+ free(buf);
+ #ifndef FRONTEND
+ ereport(FATAL,
+ (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);
+ }
+ else
+ {
+ new = strdup(path);
+ if (!new)
+ {
+ #ifndef FRONTEND
+ ereport(FATAL,
+ (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;
+ }
+
*** a/src/test/regress/pg_regress.c
--- b/src/test/regress/pg_regress.c
***************
*** 1832,1864 **** 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)
{
--- 1832,1837 ----
Hi Rajeev,
From: "Rajeev rastogi" <rajeev.rastogi@huawei.com>
Changed the patch as per your suggestion.
Now only one version of make_absolute_path there defined in src/port/path.c
Found one small memory leak in the existing function
make_absolute_path(miscinit.c),
fixed the same.
Thanks for refactoring. I confirmed that the revised patch applies to HEAD
cleanly, the source files built without extra warnings, and the original
intended problem was solved.
Please make small cosmetic changes so that make_absolute_path() follows the
style of other parts. Then I'll make this ready for committer.
(1)
Add the function name in the comment as in:
/*
* make_absolute_path
*
* ...existing function descripton
*/
(2)
Add errno description as in:
fprintf(stderr, _("could not get current working directory: %s\n",
strerror(errno)));
Regards
MauMau
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 22 February 2014 06:16, MauMau Wrote:
Thanks for reviewing again.
Please make small cosmetic changes so that make_absolute_path() follows
the
style of other parts. Then I'll make this ready for committer.(1)
Add the function name in the comment as in:/*
* make_absolute_path
*
* ...existing function descripton
*/
Added.
(2)
Add errno description as in:fprintf(stderr, _("could not get current working directory: %s\n",
strerror(errno)));
Modified.
Please find the attached modified patch.
Thanks and Regards,
Kumar Rajeev Rastogi
Attachments:
pgctl_win32service_rel_dbpath_v6.patchapplication/octet-stream; name=pgctl_win32service_rel_dbpath_v6.patchDownload
*** a/src/backend/utils/init/miscinit.c
--- b/src/backend/utils/init/miscinit.c
***************
*** 117,194 **** 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
*
--- 117,122 ----
*** a/src/bin/pg_ctl/pg_ctl.c
--- b/src/bin/pg_ctl/pg_ctl.c
***************
*** 1326,1332 **** pgwin32_CommandLine(bool registration)
register_servicename);
if (pg_config)
! appendPQExpBuffer(cmdLine, " -D \"%s\"", pg_config);
if (registration && do_wait)
appendPQExpBuffer(cmdLine, " -w");
--- 1326,1345 ----
register_servicename);
if (pg_config)
! {
! char *dataDir;
!
! if ((dataDir = make_absolute_path(pg_config)) == NULL)
! {
! write_stderr(_("%s: could not identify current directory\n"),
! progname);
! exit(1);
! }
!
! make_native_path(dataDir);
! appendPQExpBuffer(cmdLine, " -D \"%s\"", dataDir);
! free(dataDir);
! }
if (registration && do_wait)
appendPQExpBuffer(cmdLine, " -w");
*** a/src/include/miscadmin.h
--- b/src/include/miscadmin.h
***************
*** 296,302 **** 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 */
--- 296,301 ----
*** a/src/include/port.h
--- b/src/include/port.h
***************
*** 60,65 **** extern void get_man_path(const char *my_exec_path, char *ret_path);
--- 60,67 ----
extern bool get_home_path(char *ret_path);
extern void get_parent_directory(char *path);
+ extern char *make_absolute_path(const char *path);
+
/* port/dirmod.c */
extern char **pgfnames(const char *path);
extern void pgfnames_cleanup(char **filenames);
*** a/src/port/path.c
--- b/src/port/path.c
***************
*** 13,19 ****
*-------------------------------------------------------------------------
*/
! #include "c.h"
#include <ctype.h>
#include <sys/stat.h>
--- 13,23 ----
*-------------------------------------------------------------------------
*/
! #ifndef FRONTEND
! #include "postgres.h"
! #else
! #include "postgres_fe.h"
! #endif
#include <ctype.h>
#include <sys/stat.h>
***************
*** 757,759 **** trim_trailing_separator(char *path)
--- 761,867 ----
for (p--; p > path && IS_DIR_SEP(*p); p--)
*p = '\0';
}
+
+ /*
+ * 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.
+ *
+ * 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(FATAL,
+ (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(FATAL, "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(FATAL,
+ (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);
+ }
+ else
+ {
+ new = strdup(path);
+ if (!new)
+ {
+ #ifndef FRONTEND
+ ereport(FATAL,
+ (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;
+ }
+
*** a/src/test/regress/pg_regress.c
--- b/src/test/regress/pg_regress.c
***************
*** 1832,1864 **** 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)
{
--- 1832,1837 ----
From: "Rajeev rastogi" <rajeev.rastogi@huawei.com>
Please find the attached modified patch.
Thanks, reviewed and made this patch ready for committer.
Regards
MauMau
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
While registering the service for PostgreSQL on windows, we cannot expect user to give absolute path always.
So it is required to support relative path as data directory. So this patch will be very useful to handle the same.
This patch has been in "Ready for committer" stage for long time.
Please check if this can be committed now or any other changes required.
Thanks and Regards,
Kumar Rajeev Rastogi
-----Original Message-----
From: MauMau [mailto:maumau307@gmail.com]
Sent: 24 February 2014 15:31
To: Rajeev rastogi
Cc: pgsql-hackers@postgresql.org; Magnus Hagander
Subject: Re: [HACKERS] [review] PostgreSQL Service on Windows does not
start if data directory given is relative pathFrom: "Rajeev rastogi" <rajeev.rastogi@huawei.com> Please find the
attached modified patch.Thanks, reviewed and made this patch ready for committer.
Regards
MauMau
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Rajeev rastogi <rajeev.rastogi@huawei.com> writes:
[ pgctl_win32service_rel_dbpath_v6.patch ]
Committed with minor corrections, mostly but not all cosmetic.
regards, tom lane
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 05 April 2014 04:14, Tom Lane
[ pgctl_win32service_rel_dbpath_v6.patch ]
Committed with minor corrections, mostly but not all cosmetic.
Thanks a lot...
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers