diff options
Diffstat (limited to 'src/port/path.c')
-rw-r--r-- | src/port/path.c | 111 |
1 files changed, 110 insertions, 1 deletions
diff --git a/src/port/path.c b/src/port/path.c index 39d6e43404a..438b5296042 100644 --- a/src/port/path.c +++ b/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> @@ -550,6 +554,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 */ void |