*** a/src/backend/utils/init/miscinit.c --- b/src/backend/utils/init/miscinit.c *************** *** 88,98 **** void SetDataDir(const char *dir) { char *new; AssertArg(dir); /* If presented path is relative, convert to absolute */ ! new = make_absolute_path(dir); if (DataDir) free(DataDir); --- 88,101 ---- SetDataDir(const char *dir) { char *new; + char *errstr; AssertArg(dir); /* If presented path is relative, convert to absolute */ ! new = make_absolute_path(dir, &errstr); ! if (new == NULL) ! ereport(FATAL, (errmsg_internal("%s", errstr))); if (DataDir) free(DataDir); *************** *** 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 * --- 120,125 ---- *** a/src/backend/utils/misc/guc.c --- b/src/backend/utils/misc/guc.c *************** *** 4184,4196 **** SelectConfigFiles(const char *userDoption, const char *progname) { char *configdir; char *fname; struct stat stat_buf; /* configdir is -D option, or $PGDATA if no -D */ if (userDoption) ! configdir = make_absolute_path(userDoption); else ! configdir = make_absolute_path(getenv("PGDATA")); /* * Find the configuration file: if config_file was specified on the --- 4184,4200 ---- { char *configdir; char *fname; + char *errstr; struct stat stat_buf; /* configdir is -D option, or $PGDATA if no -D */ if (userDoption) ! configdir = make_absolute_path(userDoption, &errstr); else ! configdir = make_absolute_path(getenv("PGDATA"), &errstr); ! ! if (configdir == NULL) ! ereport(FATAL, (errmsg_internal("%s", errstr))); /* * Find the configuration file: if config_file was specified on the *************** *** 4199,4205 **** SelectConfigFiles(const char *userDoption, const char *progname) * the same way by future backends. */ if (ConfigFileName) ! fname = make_absolute_path(ConfigFileName); else if (configdir) { fname = guc_malloc(FATAL, --- 4203,4213 ---- * the same way by future backends. */ if (ConfigFileName) ! { ! fname = make_absolute_path(ConfigFileName, &errstr); ! if (fname == NULL) ! ereport(FATAL, (errmsg_internal("%s", errstr))); ! } else if (configdir) { fname = guc_malloc(FATAL, *************** *** 4281,4287 **** SelectConfigFiles(const char *userDoption, const char *progname) * Figure out where pg_hba.conf is, and make sure the path is absolute. */ if (HbaFileName) ! fname = make_absolute_path(HbaFileName); else if (configdir) { fname = guc_malloc(FATAL, --- 4289,4299 ---- * Figure out where pg_hba.conf is, and make sure the path is absolute. */ if (HbaFileName) ! { ! fname = make_absolute_path(HbaFileName, &errstr); ! if (fname == NULL) ! ereport(FATAL, (errmsg_internal("%s", errstr))); ! } else if (configdir) { fname = guc_malloc(FATAL, *************** *** 4304,4310 **** SelectConfigFiles(const char *userDoption, const char *progname) * Likewise for pg_ident.conf. */ if (IdentFileName) ! fname = make_absolute_path(IdentFileName); else if (configdir) { fname = guc_malloc(FATAL, --- 4316,4326 ---- * Likewise for pg_ident.conf. */ if (IdentFileName) ! { ! fname = make_absolute_path(IdentFileName, &errstr); ! if (fname == NULL) ! ereport(FATAL, (errmsg_internal("%s", errstr))); ! } else if (configdir) { fname = guc_malloc(FATAL, *** 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,69 ---- extern bool get_home_path(char *ret_path); extern void get_parent_directory(char *path); + /* port/abspath.c */ + extern char *make_absolute_path(const char *path, char **errstr); + extern char *make_absolute_path_or_exit(const char *progname, const char *path); + /* port/dirmod.c */ extern char **pgfnames(const char *path); extern void pgfnames_cleanup(char **filenames); *** a/src/port/Makefile --- b/src/port/Makefile *************** *** 30,36 **** include $(top_builddir)/src/Makefile.global override CPPFLAGS := -I$(top_builddir)/src/port -DFRONTEND $(CPPFLAGS) LIBS += $(PTHREAD_LIBS) ! OBJS = $(LIBOBJS) chklocale.o dirmod.o erand48.o fls.o inet_net_ntop.o \ noblock.o path.o pgcheckdir.o pg_crc.o pgmkdirp.o pgsleep.o \ pgstrcasecmp.o pqsignal.o \ qsort.o qsort_arg.o quotes.o sprompt.o tar.o thread.o --- 30,36 ---- override CPPFLAGS := -I$(top_builddir)/src/port -DFRONTEND $(CPPFLAGS) LIBS += $(PTHREAD_LIBS) ! OBJS = $(LIBOBJS) abspath.o chklocale.o dirmod.o erand48.o fls.o inet_net_ntop.o \ noblock.o path.o pgcheckdir.o pg_crc.o pgmkdirp.o pgsleep.o \ pgstrcasecmp.o pqsignal.o \ qsort.o qsort_arg.o quotes.o sprompt.o tar.o thread.o *** /dev/null --- b/src/port/abspath.c *************** *** 0 **** --- 1,117 ---- + /*------------------------------------------------------------------------- + * + * abspath.c + * get absolute path for the given path + * + * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/port/abspath.c + * + *------------------------------------------------------------------------- + */ + + #ifndef FRONTEND + #include "postgres.h" + #else + #include "postgres_fe.h" + #endif + + #include + + /* + * 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. + * incase of error, the errstr is filled with palloced copy of error and + * returns NULL. Caller needs to take care of freeing the errstr memory. + */ + char * + make_absolute_path(const char *path, char **errstr) + { + char *result; + + /* 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 == NULL) + { + *errstr = psprintf("out of memory"); + return NULL; + } + if (getcwd(buf, buflen)) + break; + else if (errno == ERANGE) + { + free(buf); + buflen *= 2; + continue; + } + else + { + free(buf); + *errstr = psprintf("could not get current working directory :%s", strerror(errno)); + return NULL; + } + } + + result = malloc(strlen(buf) + strlen(path) + 2); + if (result == NULL) + { + free(buf); + *errstr = psprintf("out of memory"); + return NULL; + } + + sprintf(result, "%s/%s", buf, path); + free(buf); + } + else + { + result = strdup(path); + if (result == NULL) + { + *errstr = psprintf("out of memory"); + return NULL; + } + } + + /* Make sure punctuation is canonical, too */ + canonicalize_path(result); + return result; + } + + /* + * 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. + * incase of error it exits. + */ + char * + make_absolute_path_or_exit(const char *progname, const char *path) + { + char *errstr; + char *result; + + result = make_absolute_path(path, &errstr); + if (result == NULL) + { + fprintf(stderr, "%s: %s\n", progname, errstr); + exit(1); + } + + return result; + } *** 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 ---- *************** *** 2003,2009 **** regression_main(int argc, char *argv[], init_function ifunc, test_function tfunc add_stringlist_item(&schedulelist, optarg); break; case 9: ! temp_install = make_absolute_path(optarg); break; case 10: nolocale = true; --- 1976,1982 ---- add_stringlist_item(&schedulelist, optarg); break; case 9: ! temp_install = make_absolute_path_or_exit(progname, optarg); break; case 10: nolocale = true; *************** *** 2073,2081 **** regression_main(int argc, char *argv[], init_function ifunc, test_function tfunc */ port = 0xC000 | (PG_VERSION_NUM & 0x3FFF); ! inputdir = make_absolute_path(inputdir); ! outputdir = make_absolute_path(outputdir); ! dlpath = make_absolute_path(dlpath); /* * Initialization --- 2046,2054 ---- */ port = 0xC000 | (PG_VERSION_NUM & 0x3FFF); ! inputdir = make_absolute_path_or_exit(progname, inputdir); ! outputdir = make_absolute_path_or_exit(progname, outputdir); ! dlpath = make_absolute_path_or_exit(progname, dlpath); /* * Initialization *** a/src/tools/msvc/Mkvcbuild.pm --- b/src/tools/msvc/Mkvcbuild.pm *************** *** 65,71 **** sub mkvcbuild $solution = CreateSolution($vsVersion, $config); our @pgportfiles = qw( ! chklocale.c crypt.c fls.c fseeko.c getrusage.c inet_aton.c random.c srandom.c getaddrinfo.c gettimeofday.c inet_net_ntop.c kill.c open.c erand48.c snprintf.c strlcat.c strlcpy.c dirmod.c noblock.c path.c pgcheckdir.c pg_crc.c pgmkdirp.c pgsleep.c pgstrcasecmp.c pqsignal.c --- 65,71 ---- $solution = CreateSolution($vsVersion, $config); our @pgportfiles = qw( ! abspath.c chklocale.c crypt.c fls.c fseeko.c getrusage.c inet_aton.c random.c srandom.c getaddrinfo.c gettimeofday.c inet_net_ntop.c kill.c open.c erand48.c snprintf.c strlcat.c strlcpy.c dirmod.c noblock.c path.c pgcheckdir.c pg_crc.c pgmkdirp.c pgsleep.c pgstrcasecmp.c pqsignal.c