mirror of
https://github.com/postgres/postgres.git
synced 2025-04-21 12:05:57 +03:00
Use setenv() in preference to putenv().
Since at least 2001 we've used putenv() and avoided setenv(), on the grounds that the latter was unportable and not in POSIX. However, POSIX added it that same year, and by now the situation has reversed: setenv() is probably more portable than putenv(), since POSIX now treats the latter as not being a core function. And setenv() has cleaner semantics too. So, let's reverse that old policy. This commit adds a simple src/port/ implementation of setenv() for any stragglers (we have one in the buildfarm, but I'd not be surprised if that code is never used in the field). More importantly, extend win32env.c to also support setenv(). Then, replace usages of putenv() with setenv(), and get rid of some ad-hoc implementations of setenv() wannabees. Also, adjust our src/port/ implementation of unsetenv() to follow the POSIX spec that it returns an error indicator, rather than returning void as per the ancient BSD convention. I don't feel a need to make all the call sites check for errors, but the portability stub ought to match real-world practice. Discussion: https://postgr.es/m/2065122.1609212051@sss.pgh.pa.us
This commit is contained in:
parent
62097a4cc8
commit
7ca37fb040
17
configure
vendored
17
configure
vendored
@ -15959,11 +15959,28 @@ case $host_os in
|
|||||||
# Windows uses a specialised env handler
|
# Windows uses a specialised env handler
|
||||||
mingw*)
|
mingw*)
|
||||||
|
|
||||||
|
$as_echo "#define HAVE_SETENV 1" >>confdefs.h
|
||||||
|
|
||||||
|
|
||||||
$as_echo "#define HAVE_UNSETENV 1" >>confdefs.h
|
$as_echo "#define HAVE_UNSETENV 1" >>confdefs.h
|
||||||
|
|
||||||
|
ac_cv_func_setenv=yes
|
||||||
ac_cv_func_unsetenv=yes
|
ac_cv_func_unsetenv=yes
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
|
ac_fn_c_check_func "$LINENO" "setenv" "ac_cv_func_setenv"
|
||||||
|
if test "x$ac_cv_func_setenv" = xyes; then :
|
||||||
|
$as_echo "#define HAVE_SETENV 1" >>confdefs.h
|
||||||
|
|
||||||
|
else
|
||||||
|
case " $LIBOBJS " in
|
||||||
|
*" setenv.$ac_objext "* ) ;;
|
||||||
|
*) LIBOBJS="$LIBOBJS setenv.$ac_objext"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
ac_fn_c_check_func "$LINENO" "unsetenv" "ac_cv_func_unsetenv"
|
ac_fn_c_check_func "$LINENO" "unsetenv" "ac_cv_func_unsetenv"
|
||||||
if test "x$ac_cv_func_unsetenv" = xyes; then :
|
if test "x$ac_cv_func_unsetenv" = xyes; then :
|
||||||
$as_echo "#define HAVE_UNSETENV 1" >>confdefs.h
|
$as_echo "#define HAVE_UNSETENV 1" >>confdefs.h
|
||||||
|
@ -1757,11 +1757,13 @@ fi
|
|||||||
case $host_os in
|
case $host_os in
|
||||||
# Windows uses a specialised env handler
|
# Windows uses a specialised env handler
|
||||||
mingw*)
|
mingw*)
|
||||||
|
AC_DEFINE(HAVE_SETENV, 1, [Define to 1 because replacement version used.])
|
||||||
AC_DEFINE(HAVE_UNSETENV, 1, [Define to 1 because replacement version used.])
|
AC_DEFINE(HAVE_UNSETENV, 1, [Define to 1 because replacement version used.])
|
||||||
|
ac_cv_func_setenv=yes
|
||||||
ac_cv_func_unsetenv=yes
|
ac_cv_func_unsetenv=yes
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
AC_REPLACE_FUNCS([unsetenv])
|
AC_REPLACE_FUNCS([setenv unsetenv])
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
-- Initialization that requires path substitution.
|
-- Initialization that requires path substitution.
|
||||||
|
|
||||||
CREATE FUNCTION putenv(text)
|
CREATE FUNCTION setenv(text, text)
|
||||||
RETURNS void
|
RETURNS void
|
||||||
AS '@libdir@/regress@DLSUFFIX@', 'regress_putenv'
|
AS '@libdir@/regress@DLSUFFIX@', 'regress_setenv'
|
||||||
LANGUAGE C STRICT;
|
LANGUAGE C STRICT;
|
||||||
|
|
||||||
CREATE FUNCTION wait_pid(int)
|
CREATE FUNCTION wait_pid(int)
|
||||||
@ -11,4 +11,4 @@ CREATE FUNCTION wait_pid(int)
|
|||||||
LANGUAGE C STRICT;
|
LANGUAGE C STRICT;
|
||||||
|
|
||||||
CREATE FUNCTION set_pgservicefile(text) RETURNS void LANGUAGE SQL
|
CREATE FUNCTION set_pgservicefile(text) RETURNS void LANGUAGE SQL
|
||||||
AS $$SELECT putenv('PGSERVICEFILE=@abs_srcdir@/' || $1)$$;
|
AS $$SELECT setenv('PGSERVICEFILE', '@abs_srcdir@/' || $1)$$;
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
-- Initialization that requires path substitution.
|
-- Initialization that requires path substitution.
|
||||||
CREATE FUNCTION putenv(text)
|
CREATE FUNCTION setenv(text, text)
|
||||||
RETURNS void
|
RETURNS void
|
||||||
AS '@libdir@/regress@DLSUFFIX@', 'regress_putenv'
|
AS '@libdir@/regress@DLSUFFIX@', 'regress_setenv'
|
||||||
LANGUAGE C STRICT;
|
LANGUAGE C STRICT;
|
||||||
CREATE FUNCTION wait_pid(int)
|
CREATE FUNCTION wait_pid(int)
|
||||||
RETURNS void
|
RETURNS void
|
||||||
AS '@libdir@/regress@DLSUFFIX@'
|
AS '@libdir@/regress@DLSUFFIX@'
|
||||||
LANGUAGE C STRICT;
|
LANGUAGE C STRICT;
|
||||||
CREATE FUNCTION set_pgservicefile(text) RETURNS void LANGUAGE SQL
|
CREATE FUNCTION set_pgservicefile(text) RETURNS void LANGUAGE SQL
|
||||||
AS $$SELECT putenv('PGSERVICEFILE=@abs_srcdir@/' || $1)$$;
|
AS $$SELECT setenv('PGSERVICEFILE', '@abs_srcdir@/' || $1)$$;
|
||||||
|
@ -105,20 +105,6 @@ char *localized_full_months[12 + 1];
|
|||||||
static bool CurrentLocaleConvValid = false;
|
static bool CurrentLocaleConvValid = false;
|
||||||
static bool CurrentLCTimeValid = false;
|
static bool CurrentLCTimeValid = false;
|
||||||
|
|
||||||
/* Environment variable storage area */
|
|
||||||
|
|
||||||
#define LC_ENV_BUFSIZE (NAMEDATALEN + 20)
|
|
||||||
|
|
||||||
static char lc_collate_envbuf[LC_ENV_BUFSIZE];
|
|
||||||
static char lc_ctype_envbuf[LC_ENV_BUFSIZE];
|
|
||||||
|
|
||||||
#ifdef LC_MESSAGES
|
|
||||||
static char lc_messages_envbuf[LC_ENV_BUFSIZE];
|
|
||||||
#endif
|
|
||||||
static char lc_monetary_envbuf[LC_ENV_BUFSIZE];
|
|
||||||
static char lc_numeric_envbuf[LC_ENV_BUFSIZE];
|
|
||||||
static char lc_time_envbuf[LC_ENV_BUFSIZE];
|
|
||||||
|
|
||||||
/* Cache for collation-related knowledge */
|
/* Cache for collation-related knowledge */
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@ -163,7 +149,6 @@ pg_perm_setlocale(int category, const char *locale)
|
|||||||
{
|
{
|
||||||
char *result;
|
char *result;
|
||||||
const char *envvar;
|
const char *envvar;
|
||||||
char *envbuf;
|
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
result = setlocale(category, locale);
|
result = setlocale(category, locale);
|
||||||
@ -199,7 +184,7 @@ pg_perm_setlocale(int category, const char *locale)
|
|||||||
*/
|
*/
|
||||||
if (category == LC_CTYPE)
|
if (category == LC_CTYPE)
|
||||||
{
|
{
|
||||||
static char save_lc_ctype[LC_ENV_BUFSIZE];
|
static char save_lc_ctype[NAMEDATALEN + 20];
|
||||||
|
|
||||||
/* copy setlocale() return value before callee invokes it again */
|
/* copy setlocale() return value before callee invokes it again */
|
||||||
strlcpy(save_lc_ctype, result, sizeof(save_lc_ctype));
|
strlcpy(save_lc_ctype, result, sizeof(save_lc_ctype));
|
||||||
@ -216,16 +201,13 @@ pg_perm_setlocale(int category, const char *locale)
|
|||||||
{
|
{
|
||||||
case LC_COLLATE:
|
case LC_COLLATE:
|
||||||
envvar = "LC_COLLATE";
|
envvar = "LC_COLLATE";
|
||||||
envbuf = lc_collate_envbuf;
|
|
||||||
break;
|
break;
|
||||||
case LC_CTYPE:
|
case LC_CTYPE:
|
||||||
envvar = "LC_CTYPE";
|
envvar = "LC_CTYPE";
|
||||||
envbuf = lc_ctype_envbuf;
|
|
||||||
break;
|
break;
|
||||||
#ifdef LC_MESSAGES
|
#ifdef LC_MESSAGES
|
||||||
case LC_MESSAGES:
|
case LC_MESSAGES:
|
||||||
envvar = "LC_MESSAGES";
|
envvar = "LC_MESSAGES";
|
||||||
envbuf = lc_messages_envbuf;
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
result = IsoLocaleName(locale);
|
result = IsoLocaleName(locale);
|
||||||
if (result == NULL)
|
if (result == NULL)
|
||||||
@ -236,26 +218,19 @@ pg_perm_setlocale(int category, const char *locale)
|
|||||||
#endif /* LC_MESSAGES */
|
#endif /* LC_MESSAGES */
|
||||||
case LC_MONETARY:
|
case LC_MONETARY:
|
||||||
envvar = "LC_MONETARY";
|
envvar = "LC_MONETARY";
|
||||||
envbuf = lc_monetary_envbuf;
|
|
||||||
break;
|
break;
|
||||||
case LC_NUMERIC:
|
case LC_NUMERIC:
|
||||||
envvar = "LC_NUMERIC";
|
envvar = "LC_NUMERIC";
|
||||||
envbuf = lc_numeric_envbuf;
|
|
||||||
break;
|
break;
|
||||||
case LC_TIME:
|
case LC_TIME:
|
||||||
envvar = "LC_TIME";
|
envvar = "LC_TIME";
|
||||||
envbuf = lc_time_envbuf;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
elog(FATAL, "unrecognized LC category: %d", category);
|
elog(FATAL, "unrecognized LC category: %d", category);
|
||||||
envvar = NULL; /* keep compiler quiet */
|
return NULL; /* keep compiler quiet */
|
||||||
envbuf = NULL;
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(envbuf, LC_ENV_BUFSIZE - 1, "%s=%s", envvar, result);
|
if (setenv(envvar, result, 1) != 0)
|
||||||
|
|
||||||
if (putenv(envbuf))
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -2355,8 +2355,7 @@ check_need_password(const char *authmethodlocal, const char *authmethodhost)
|
|||||||
void
|
void
|
||||||
setup_pgdata(void)
|
setup_pgdata(void)
|
||||||
{
|
{
|
||||||
char *pgdata_get_env,
|
char *pgdata_get_env;
|
||||||
*pgdata_set_env;
|
|
||||||
|
|
||||||
if (!pg_data)
|
if (!pg_data)
|
||||||
{
|
{
|
||||||
@ -2386,8 +2385,11 @@ setup_pgdata(void)
|
|||||||
* need quotes otherwise on Windows because paths there are most likely to
|
* need quotes otherwise on Windows because paths there are most likely to
|
||||||
* have embedded spaces.
|
* have embedded spaces.
|
||||||
*/
|
*/
|
||||||
pgdata_set_env = psprintf("PGDATA=%s", pg_data);
|
if (setenv("PGDATA", pg_data, 1) != 0)
|
||||||
putenv(pgdata_set_env);
|
{
|
||||||
|
pg_log_error("could not set environment");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -889,11 +889,10 @@ do_start(void)
|
|||||||
*/
|
*/
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
{
|
{
|
||||||
static char env_var[32];
|
char env_var[32];
|
||||||
|
|
||||||
snprintf(env_var, sizeof(env_var), "PG_GRANDPARENT_PID=%d",
|
snprintf(env_var, sizeof(env_var), "%d", (int) getppid());
|
||||||
(int) getppid());
|
setenv("PG_GRANDPARENT_PID", env_var, 1);
|
||||||
putenv(env_var);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -2340,12 +2339,10 @@ main(int argc, char **argv)
|
|||||||
case 'D':
|
case 'D':
|
||||||
{
|
{
|
||||||
char *pgdata_D;
|
char *pgdata_D;
|
||||||
char *env_var;
|
|
||||||
|
|
||||||
pgdata_D = pg_strdup(optarg);
|
pgdata_D = pg_strdup(optarg);
|
||||||
canonicalize_path(pgdata_D);
|
canonicalize_path(pgdata_D);
|
||||||
env_var = psprintf("PGDATA=%s", pgdata_D);
|
setenv("PGDATA", pgdata_D, 1);
|
||||||
putenv(env_var);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We could pass PGDATA just in an environment
|
* We could pass PGDATA just in an environment
|
||||||
@ -2353,6 +2350,7 @@ main(int argc, char **argv)
|
|||||||
* 'ps' display
|
* 'ps' display
|
||||||
*/
|
*/
|
||||||
pgdata_opt = psprintf("-D \"%s\" ", pgdata_D);
|
pgdata_opt = psprintf("-D \"%s\" ", pgdata_D);
|
||||||
|
free(pgdata_D);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'e':
|
case 'e':
|
||||||
|
@ -97,20 +97,20 @@ get_control_data(ClusterInfo *cluster, bool live_check)
|
|||||||
if (getenv("LC_MESSAGES"))
|
if (getenv("LC_MESSAGES"))
|
||||||
lc_messages = pg_strdup(getenv("LC_MESSAGES"));
|
lc_messages = pg_strdup(getenv("LC_MESSAGES"));
|
||||||
|
|
||||||
pg_putenv("LC_COLLATE", NULL);
|
unsetenv("LC_COLLATE");
|
||||||
pg_putenv("LC_CTYPE", NULL);
|
unsetenv("LC_CTYPE");
|
||||||
pg_putenv("LC_MONETARY", NULL);
|
unsetenv("LC_MONETARY");
|
||||||
pg_putenv("LC_NUMERIC", NULL);
|
unsetenv("LC_NUMERIC");
|
||||||
pg_putenv("LC_TIME", NULL);
|
unsetenv("LC_TIME");
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
pg_putenv("LANG", NULL);
|
unsetenv("LANG");
|
||||||
#else
|
#else
|
||||||
/* On Windows the default locale may not be English, so force it */
|
/* On Windows the default locale may not be English, so force it */
|
||||||
pg_putenv("LANG", "en");
|
setenv("LANG", "en", 1);
|
||||||
#endif
|
#endif
|
||||||
pg_putenv("LANGUAGE", NULL);
|
unsetenv("LANGUAGE");
|
||||||
pg_putenv("LC_ALL", NULL);
|
unsetenv("LC_ALL");
|
||||||
pg_putenv("LC_MESSAGES", "C");
|
setenv("LC_MESSAGES", "C", 1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check for clean shutdown
|
* Check for clean shutdown
|
||||||
@ -490,17 +490,31 @@ get_control_data(ClusterInfo *cluster, bool live_check)
|
|||||||
pclose(output);
|
pclose(output);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Restore environment variables
|
* Restore environment variables. Note all but LANG and LC_MESSAGES were
|
||||||
|
* unset above.
|
||||||
*/
|
*/
|
||||||
pg_putenv("LC_COLLATE", lc_collate);
|
if (lc_collate)
|
||||||
pg_putenv("LC_CTYPE", lc_ctype);
|
setenv("LC_COLLATE", lc_collate, 1);
|
||||||
pg_putenv("LC_MONETARY", lc_monetary);
|
if (lc_ctype)
|
||||||
pg_putenv("LC_NUMERIC", lc_numeric);
|
setenv("LC_CTYPE", lc_ctype, 1);
|
||||||
pg_putenv("LC_TIME", lc_time);
|
if (lc_monetary)
|
||||||
pg_putenv("LANG", lang);
|
setenv("LC_MONETARY", lc_monetary, 1);
|
||||||
pg_putenv("LANGUAGE", language);
|
if (lc_numeric)
|
||||||
pg_putenv("LC_ALL", lc_all);
|
setenv("LC_NUMERIC", lc_numeric, 1);
|
||||||
pg_putenv("LC_MESSAGES", lc_messages);
|
if (lc_time)
|
||||||
|
setenv("LC_TIME", lc_time, 1);
|
||||||
|
if (lang)
|
||||||
|
setenv("LANG", lang, 1);
|
||||||
|
else
|
||||||
|
unsetenv("LANG");
|
||||||
|
if (language)
|
||||||
|
setenv("LANGUAGE", language, 1);
|
||||||
|
if (lc_all)
|
||||||
|
setenv("LC_ALL", lc_all, 1);
|
||||||
|
if (lc_messages)
|
||||||
|
setenv("LC_MESSAGES", lc_messages, 1);
|
||||||
|
else
|
||||||
|
unsetenv("LC_MESSAGES");
|
||||||
|
|
||||||
pg_free(lc_collate);
|
pg_free(lc_collate);
|
||||||
pg_free(lc_ctype);
|
pg_free(lc_ctype);
|
||||||
|
@ -193,7 +193,7 @@ parseCommandLine(int argc, char *argv[])
|
|||||||
* Push the user name into the environment so pre-9.1
|
* Push the user name into the environment so pre-9.1
|
||||||
* pg_ctl/libpq uses it.
|
* pg_ctl/libpq uses it.
|
||||||
*/
|
*/
|
||||||
pg_putenv("PGUSER", os_info.user);
|
setenv("PGUSER", os_info.user, 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'v':
|
case 'v':
|
||||||
@ -245,11 +245,11 @@ parseCommandLine(int argc, char *argv[])
|
|||||||
char *pgoptions = psprintf("%s %s", FIX_DEFAULT_READ_ONLY,
|
char *pgoptions = psprintf("%s %s", FIX_DEFAULT_READ_ONLY,
|
||||||
getenv("PGOPTIONS"));
|
getenv("PGOPTIONS"));
|
||||||
|
|
||||||
pg_putenv("PGOPTIONS", pgoptions);
|
setenv("PGOPTIONS", pgoptions, 1);
|
||||||
pfree(pgoptions);
|
pfree(pgoptions);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
pg_putenv("PGOPTIONS", FIX_DEFAULT_READ_ONLY);
|
setenv("PGOPTIONS", FIX_DEFAULT_READ_ONLY, 1);
|
||||||
|
|
||||||
/* Get values from env if not already set */
|
/* Get values from env if not already set */
|
||||||
check_required_directory(&old_cluster.bindir, "PGBINOLD", false,
|
check_required_directory(&old_cluster.bindir, "PGBINOLD", false,
|
||||||
|
@ -436,7 +436,6 @@ void end_progress_output(void);
|
|||||||
void prep_status(const char *fmt,...) pg_attribute_printf(1, 2);
|
void prep_status(const char *fmt,...) pg_attribute_printf(1, 2);
|
||||||
void check_ok(void);
|
void check_ok(void);
|
||||||
unsigned int str2uint(const char *str);
|
unsigned int str2uint(const char *str);
|
||||||
void pg_putenv(const char *var, const char *val);
|
|
||||||
|
|
||||||
|
|
||||||
/* version.c */
|
/* version.c */
|
||||||
|
@ -241,39 +241,3 @@ str2uint(const char *str)
|
|||||||
{
|
{
|
||||||
return strtoul(str, NULL, 10);
|
return strtoul(str, NULL, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* pg_putenv()
|
|
||||||
*
|
|
||||||
* This is like putenv(), but takes two arguments.
|
|
||||||
* It also does unsetenv() if val is NULL.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
pg_putenv(const char *var, const char *val)
|
|
||||||
{
|
|
||||||
if (val)
|
|
||||||
{
|
|
||||||
#ifndef WIN32
|
|
||||||
char *envstr;
|
|
||||||
|
|
||||||
envstr = psprintf("%s=%s", var, val);
|
|
||||||
putenv(envstr);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Do not free envstr because it becomes part of the environment on
|
|
||||||
* some operating systems. See port/unsetenv.c::unsetenv.
|
|
||||||
*/
|
|
||||||
#else
|
|
||||||
SetEnvironmentVariableA(var, val);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#ifndef WIN32
|
|
||||||
unsetenv(var);
|
|
||||||
#else
|
|
||||||
SetEnvironmentVariableA(var, "");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -2296,17 +2296,8 @@ exec_command_setenv(PsqlScanState scan_state, bool active_branch,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Set variable to the value of the next argument */
|
/* Set variable to the value of the next argument */
|
||||||
char *newval;
|
setenv(envvar, envval, 1);
|
||||||
|
|
||||||
newval = psprintf("%s=%s", envvar, envval);
|
|
||||||
putenv(newval);
|
|
||||||
success = true;
|
success = true;
|
||||||
|
|
||||||
/*
|
|
||||||
* Do not free newval here, it will screw up the environment if
|
|
||||||
* you do. See putenv man page for details. That means we leak a
|
|
||||||
* bit of memory here, but not enough to worry about.
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
free(envvar);
|
free(envvar);
|
||||||
free(envval);
|
free(envval);
|
||||||
|
@ -435,9 +435,6 @@ set_pglocale_pgservice(const char *argv0, const char *app)
|
|||||||
{
|
{
|
||||||
char path[MAXPGPATH];
|
char path[MAXPGPATH];
|
||||||
char my_exec_path[MAXPGPATH];
|
char my_exec_path[MAXPGPATH];
|
||||||
char env_path[MAXPGPATH + sizeof("PGSYSCONFDIR=")]; /* longer than
|
|
||||||
* PGLOCALEDIR */
|
|
||||||
char *dup_path;
|
|
||||||
|
|
||||||
/* don't set LC_ALL in the backend */
|
/* don't set LC_ALL in the backend */
|
||||||
if (strcmp(app, PG_TEXTDOMAIN("postgres")) != 0)
|
if (strcmp(app, PG_TEXTDOMAIN("postgres")) != 0)
|
||||||
@ -462,28 +459,15 @@ set_pglocale_pgservice(const char *argv0, const char *app)
|
|||||||
get_locale_path(my_exec_path, path);
|
get_locale_path(my_exec_path, path);
|
||||||
bindtextdomain(app, path);
|
bindtextdomain(app, path);
|
||||||
textdomain(app);
|
textdomain(app);
|
||||||
|
/* set for libpq to use, but don't override existing setting */
|
||||||
if (getenv("PGLOCALEDIR") == NULL)
|
setenv("PGLOCALEDIR", path, 0);
|
||||||
{
|
|
||||||
/* set for libpq to use */
|
|
||||||
snprintf(env_path, sizeof(env_path), "PGLOCALEDIR=%s", path);
|
|
||||||
canonicalize_path(env_path + 12);
|
|
||||||
dup_path = strdup(env_path);
|
|
||||||
if (dup_path)
|
|
||||||
putenv(dup_path);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (getenv("PGSYSCONFDIR") == NULL)
|
if (getenv("PGSYSCONFDIR") == NULL)
|
||||||
{
|
{
|
||||||
get_etc_path(my_exec_path, path);
|
get_etc_path(my_exec_path, path);
|
||||||
|
|
||||||
/* set for libpq to use */
|
/* set for libpq to use */
|
||||||
snprintf(env_path, sizeof(env_path), "PGSYSCONFDIR=%s", path);
|
setenv("PGSYSCONFDIR", path, 0);
|
||||||
canonicalize_path(env_path + 13);
|
|
||||||
dup_path = strdup(env_path);
|
|
||||||
if (dup_path)
|
|
||||||
putenv(dup_path);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,7 +171,7 @@ get_restricted_token(void)
|
|||||||
|
|
||||||
cmdline = pg_strdup(GetCommandLine());
|
cmdline = pg_strdup(GetCommandLine());
|
||||||
|
|
||||||
putenv("PG_RESTRICT_EXEC=1");
|
setenv("PG_RESTRICT_EXEC", "1", 1);
|
||||||
|
|
||||||
if ((restrictedToken = CreateRestrictedProcess(cmdline, &pi)) == 0)
|
if ((restrictedToken = CreateRestrictedProcess(cmdline, &pi)) == 0)
|
||||||
{
|
{
|
||||||
|
@ -473,6 +473,9 @@
|
|||||||
/* Define to 1 if you have the <security/pam_appl.h> header file. */
|
/* Define to 1 if you have the <security/pam_appl.h> header file. */
|
||||||
#undef HAVE_SECURITY_PAM_APPL_H
|
#undef HAVE_SECURITY_PAM_APPL_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `setenv' function. */
|
||||||
|
#undef HAVE_SETENV
|
||||||
|
|
||||||
/* Define to 1 if you have the `setproctitle' function. */
|
/* Define to 1 if you have the `setproctitle' function. */
|
||||||
#undef HAVE_SETPROCTITLE
|
#undef HAVE_SETPROCTITLE
|
||||||
|
|
||||||
|
@ -447,8 +447,12 @@ extern size_t strnlen(const char *str, size_t maxlen);
|
|||||||
extern long random(void);
|
extern long random(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE_SETENV
|
||||||
|
extern int setenv(const char *name, const char *value, int overwrite);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef HAVE_UNSETENV
|
#ifndef HAVE_UNSETENV
|
||||||
extern void unsetenv(const char *name);
|
extern int unsetenv(const char *name);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef HAVE_SRANDOM
|
#ifndef HAVE_SRANDOM
|
||||||
|
@ -490,7 +490,12 @@ extern void _dosmaperr(unsigned long);
|
|||||||
|
|
||||||
/* in port/win32env.c */
|
/* in port/win32env.c */
|
||||||
extern int pgwin32_putenv(const char *);
|
extern int pgwin32_putenv(const char *);
|
||||||
extern void pgwin32_unsetenv(const char *);
|
extern int pgwin32_setenv(const char *name, const char *value, int overwrite);
|
||||||
|
extern int pgwin32_unsetenv(const char *name);
|
||||||
|
|
||||||
|
#define putenv(x) pgwin32_putenv(x)
|
||||||
|
#define setenv(x,y,z) pgwin32_setenv(x,y,z)
|
||||||
|
#define unsetenv(x) pgwin32_unsetenv(x)
|
||||||
|
|
||||||
/* in port/win32security.c */
|
/* in port/win32security.c */
|
||||||
extern int pgwin32_is_service(void);
|
extern int pgwin32_is_service(void);
|
||||||
@ -499,9 +504,6 @@ extern int pgwin32_is_admin(void);
|
|||||||
/* Windows security token manipulation (in src/common/exec.c) */
|
/* Windows security token manipulation (in src/common/exec.c) */
|
||||||
extern BOOL AddUserToTokenDacl(HANDLE hToken);
|
extern BOOL AddUserToTokenDacl(HANDLE hToken);
|
||||||
|
|
||||||
#define putenv(x) pgwin32_putenv(x)
|
|
||||||
#define unsetenv(x) pgwin32_unsetenv(x)
|
|
||||||
|
|
||||||
/* Things that exist in MinGW headers, but need to be added to MSVC */
|
/* Things that exist in MinGW headers, but need to be added to MSVC */
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
|
||||||
|
@ -147,8 +147,9 @@ ecpg_start_test(const char *testname,
|
|||||||
outfile_stdout,
|
outfile_stdout,
|
||||||
outfile_stderr);
|
outfile_stderr);
|
||||||
|
|
||||||
appnameenv = psprintf("PGAPPNAME=ecpg/%s", testname_dash.data);
|
appnameenv = psprintf("ecpg/%s", testname_dash.data);
|
||||||
putenv(appnameenv);
|
setenv("PGAPPNAME", appnameenv, 1);
|
||||||
|
free(appnameenv);
|
||||||
|
|
||||||
pid = spawn_process(cmd);
|
pid = spawn_process(cmd);
|
||||||
|
|
||||||
@ -160,7 +161,6 @@ ecpg_start_test(const char *testname,
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsetenv("PGAPPNAME");
|
unsetenv("PGAPPNAME");
|
||||||
free(appnameenv);
|
|
||||||
|
|
||||||
free(testname_dash.data);
|
free(testname_dash.data);
|
||||||
|
|
||||||
|
48
src/port/setenv.c
Normal file
48
src/port/setenv.c
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* setenv.c
|
||||||
|
* setenv() emulation for machines without it
|
||||||
|
*
|
||||||
|
* Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
|
||||||
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* IDENTIFICATION
|
||||||
|
* src/port/setenv.c
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "c.h"
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
setenv(const char *name, const char *value, int overwrite)
|
||||||
|
{
|
||||||
|
char *envstr;
|
||||||
|
|
||||||
|
/* Error conditions, per POSIX */
|
||||||
|
if (name == NULL || name[0] == '\0' || strchr(name, '=') != NULL ||
|
||||||
|
value == NULL)
|
||||||
|
{
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No work if variable exists and we're not to replace it */
|
||||||
|
if (overwrite == 0 && getenv(name) != NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add or replace the value using putenv(). This will leak memory if the
|
||||||
|
* same variable is repeatedly redefined, but there's little we can do
|
||||||
|
* about that when sitting atop putenv().
|
||||||
|
*/
|
||||||
|
envstr = (char *) malloc(strlen(name) + strlen(value) + 2);
|
||||||
|
if (!envstr) /* not much we can do if no memory */
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
sprintf(envstr, "%s=%s", name, value);
|
||||||
|
|
||||||
|
return putenv(envstr);
|
||||||
|
}
|
@ -16,13 +16,20 @@
|
|||||||
#include "c.h"
|
#include "c.h"
|
||||||
|
|
||||||
|
|
||||||
void
|
int
|
||||||
unsetenv(const char *name)
|
unsetenv(const char *name)
|
||||||
{
|
{
|
||||||
char *envstr;
|
char *envstr;
|
||||||
|
|
||||||
|
/* Error conditions, per POSIX */
|
||||||
|
if (name == NULL || name[0] == '\0' || strchr(name, '=') != NULL)
|
||||||
|
{
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (getenv(name) == NULL)
|
if (getenv(name) == NULL)
|
||||||
return; /* no work */
|
return 0; /* no work */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The technique embodied here works if libc follows the Single Unix Spec
|
* The technique embodied here works if libc follows the Single Unix Spec
|
||||||
@ -40,11 +47,12 @@ unsetenv(const char *name)
|
|||||||
|
|
||||||
envstr = (char *) malloc(strlen(name) + 2);
|
envstr = (char *) malloc(strlen(name) + 2);
|
||||||
if (!envstr) /* not much we can do if no memory */
|
if (!envstr) /* not much we can do if no memory */
|
||||||
return;
|
return -1;
|
||||||
|
|
||||||
/* Override the existing setting by forcibly defining the var */
|
/* Override the existing setting by forcibly defining the var */
|
||||||
sprintf(envstr, "%s=", name);
|
sprintf(envstr, "%s=", name);
|
||||||
putenv(envstr);
|
if (putenv(envstr))
|
||||||
|
return -1;
|
||||||
|
|
||||||
/* Now we can clobber the variable definition this way: */
|
/* Now we can clobber the variable definition this way: */
|
||||||
strcpy(envstr, "=");
|
strcpy(envstr, "=");
|
||||||
@ -53,5 +61,5 @@ unsetenv(const char *name)
|
|||||||
* This last putenv cleans up if we have multiple zero-length names as a
|
* This last putenv cleans up if we have multiple zero-length names as a
|
||||||
* result of unsetting multiple things.
|
* result of unsetting multiple things.
|
||||||
*/
|
*/
|
||||||
putenv(envstr);
|
return putenv(envstr);
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
/*-------------------------------------------------------------------------
|
/*-------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* win32env.c
|
* win32env.c
|
||||||
* putenv() and unsetenv() for win32, which update both process environment
|
* putenv(), setenv(), and unsetenv() for win32.
|
||||||
* and caches in (potentially multiple) C run-time library (CRT) versions.
|
*
|
||||||
|
* These functions update both the process environment and caches in
|
||||||
|
* (potentially multiple) C run-time library (CRT) versions.
|
||||||
*
|
*
|
||||||
* Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
@ -16,6 +18,11 @@
|
|||||||
|
|
||||||
#include "c.h"
|
#include "c.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note that unlike POSIX putenv(), this doesn't use the passed-in string
|
||||||
|
* as permanent storage.
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
pgwin32_putenv(const char *envval)
|
pgwin32_putenv(const char *envval)
|
||||||
{
|
{
|
||||||
@ -64,7 +71,7 @@ pgwin32_putenv(const char *envval)
|
|||||||
}
|
}
|
||||||
*cp = '\0';
|
*cp = '\0';
|
||||||
cp++;
|
cp++;
|
||||||
if (strlen(cp))
|
if (*cp)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Only call SetEnvironmentVariable() when we are adding a variable,
|
* Only call SetEnvironmentVariable() when we are adding a variable,
|
||||||
@ -110,16 +117,47 @@ pgwin32_putenv(const char *envval)
|
|||||||
return _putenv(envval);
|
return _putenv(envval);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int
|
||||||
|
pgwin32_setenv(const char *name, const char *value, int overwrite)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
char *envstr;
|
||||||
|
|
||||||
|
/* Error conditions, per POSIX */
|
||||||
|
if (name == NULL || name[0] == '\0' || strchr(name, '=') != NULL ||
|
||||||
|
value == NULL)
|
||||||
|
{
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No work if variable exists and we're not to replace it */
|
||||||
|
if (overwrite == 0 && getenv(name) != NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
envstr = (char *) malloc(strlen(name) + strlen(value) + 2);
|
||||||
|
if (!envstr) /* not much we can do if no memory */
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
sprintf(envstr, "%s=%s", name, value);
|
||||||
|
|
||||||
|
res = pgwin32_putenv(envstr);
|
||||||
|
free(envstr);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
pgwin32_unsetenv(const char *name)
|
pgwin32_unsetenv(const char *name)
|
||||||
{
|
{
|
||||||
|
int res;
|
||||||
char *envbuf;
|
char *envbuf;
|
||||||
|
|
||||||
envbuf = (char *) malloc(strlen(name) + 2);
|
envbuf = (char *) malloc(strlen(name) + 2);
|
||||||
if (!envbuf)
|
if (!envbuf)
|
||||||
return;
|
return -1;
|
||||||
|
|
||||||
sprintf(envbuf, "%s=", name);
|
sprintf(envbuf, "%s=", name);
|
||||||
pgwin32_putenv(envbuf);
|
res = pgwin32_putenv(envbuf);
|
||||||
free(envbuf);
|
free(envbuf);
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -98,8 +98,9 @@ isolation_start_test(const char *testname,
|
|||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
appnameenv = psprintf("PGAPPNAME=isolation/%s", testname);
|
appnameenv = psprintf("isolation/%s", testname);
|
||||||
putenv(appnameenv);
|
setenv("PGAPPNAME", appnameenv, 1);
|
||||||
|
free(appnameenv);
|
||||||
|
|
||||||
pid = spawn_process(psql_cmd);
|
pid = spawn_process(psql_cmd);
|
||||||
|
|
||||||
@ -111,7 +112,6 @@ isolation_start_test(const char *testname,
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsetenv("PGAPPNAME");
|
unsetenv("PGAPPNAME");
|
||||||
free(appnameenv);
|
|
||||||
|
|
||||||
return pid;
|
return pid;
|
||||||
}
|
}
|
||||||
|
@ -724,18 +724,6 @@ get_expectfile(const char *testname, const char *file)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Handy subroutine for setting an environment variable "var" to "val"
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
doputenv(const char *var, const char *val)
|
|
||||||
{
|
|
||||||
char *s;
|
|
||||||
|
|
||||||
s = psprintf("%s=%s", var, val);
|
|
||||||
putenv(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Prepare environment variables for running regression tests
|
* Prepare environment variables for running regression tests
|
||||||
*/
|
*/
|
||||||
@ -746,7 +734,7 @@ initialize_environment(void)
|
|||||||
* Set default application_name. (The test_function may choose to
|
* Set default application_name. (The test_function may choose to
|
||||||
* override this, but if it doesn't, we have something useful in place.)
|
* override this, but if it doesn't, we have something useful in place.)
|
||||||
*/
|
*/
|
||||||
putenv("PGAPPNAME=pg_regress");
|
setenv("PGAPPNAME", "pg_regress", 1);
|
||||||
|
|
||||||
if (nolocale)
|
if (nolocale)
|
||||||
{
|
{
|
||||||
@ -769,7 +757,7 @@ initialize_environment(void)
|
|||||||
* variables unset; see PostmasterMain().
|
* variables unset; see PostmasterMain().
|
||||||
*/
|
*/
|
||||||
#if defined(WIN32) || defined(__CYGWIN__) || defined(__darwin__)
|
#if defined(WIN32) || defined(__CYGWIN__) || defined(__darwin__)
|
||||||
putenv("LANG=C");
|
setenv("LANG", "C", 1);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -781,21 +769,21 @@ initialize_environment(void)
|
|||||||
*/
|
*/
|
||||||
unsetenv("LANGUAGE");
|
unsetenv("LANGUAGE");
|
||||||
unsetenv("LC_ALL");
|
unsetenv("LC_ALL");
|
||||||
putenv("LC_MESSAGES=C");
|
setenv("LC_MESSAGES", "C", 1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set encoding as requested
|
* Set encoding as requested
|
||||||
*/
|
*/
|
||||||
if (encoding)
|
if (encoding)
|
||||||
doputenv("PGCLIENTENCODING", encoding);
|
setenv("PGCLIENTENCODING", encoding, 1);
|
||||||
else
|
else
|
||||||
unsetenv("PGCLIENTENCODING");
|
unsetenv("PGCLIENTENCODING");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set timezone and datestyle for datetime-related tests
|
* Set timezone and datestyle for datetime-related tests
|
||||||
*/
|
*/
|
||||||
putenv("PGTZ=PST8PDT");
|
setenv("PGTZ", "PST8PDT", 1);
|
||||||
putenv("PGDATESTYLE=Postgres, MDY");
|
setenv("PGDATESTYLE", "Postgres, MDY", 1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Likewise set intervalstyle to ensure consistent results. This is a bit
|
* Likewise set intervalstyle to ensure consistent results. This is a bit
|
||||||
@ -809,9 +797,10 @@ initialize_environment(void)
|
|||||||
|
|
||||||
if (!old_pgoptions)
|
if (!old_pgoptions)
|
||||||
old_pgoptions = "";
|
old_pgoptions = "";
|
||||||
new_pgoptions = psprintf("PGOPTIONS=%s %s",
|
new_pgoptions = psprintf("%s %s",
|
||||||
old_pgoptions, my_pgoptions);
|
old_pgoptions, my_pgoptions);
|
||||||
putenv(new_pgoptions);
|
setenv("PGOPTIONS", new_pgoptions, 1);
|
||||||
|
free(new_pgoptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (temp_instance)
|
if (temp_instance)
|
||||||
@ -832,17 +821,17 @@ initialize_environment(void)
|
|||||||
unsetenv("PGDATA");
|
unsetenv("PGDATA");
|
||||||
#ifdef HAVE_UNIX_SOCKETS
|
#ifdef HAVE_UNIX_SOCKETS
|
||||||
if (hostname != NULL)
|
if (hostname != NULL)
|
||||||
doputenv("PGHOST", hostname);
|
setenv("PGHOST", hostname, 1);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sockdir = getenv("PG_REGRESS_SOCK_DIR");
|
sockdir = getenv("PG_REGRESS_SOCK_DIR");
|
||||||
if (!sockdir)
|
if (!sockdir)
|
||||||
sockdir = make_temp_sockdir();
|
sockdir = make_temp_sockdir();
|
||||||
doputenv("PGHOST", sockdir);
|
setenv("PGHOST", sockdir, 1);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
Assert(hostname != NULL);
|
Assert(hostname != NULL);
|
||||||
doputenv("PGHOST", hostname);
|
setenv("PGHOST", hostname, 1);
|
||||||
#endif
|
#endif
|
||||||
unsetenv("PGHOSTADDR");
|
unsetenv("PGHOSTADDR");
|
||||||
if (port != -1)
|
if (port != -1)
|
||||||
@ -850,7 +839,7 @@ initialize_environment(void)
|
|||||||
char s[16];
|
char s[16];
|
||||||
|
|
||||||
sprintf(s, "%d", port);
|
sprintf(s, "%d", port);
|
||||||
doputenv("PGPORT", s);
|
setenv("PGPORT", s, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -864,7 +853,7 @@ initialize_environment(void)
|
|||||||
*/
|
*/
|
||||||
if (hostname != NULL)
|
if (hostname != NULL)
|
||||||
{
|
{
|
||||||
doputenv("PGHOST", hostname);
|
setenv("PGHOST", hostname, 1);
|
||||||
unsetenv("PGHOSTADDR");
|
unsetenv("PGHOSTADDR");
|
||||||
}
|
}
|
||||||
if (port != -1)
|
if (port != -1)
|
||||||
@ -872,10 +861,10 @@ initialize_environment(void)
|
|||||||
char s[16];
|
char s[16];
|
||||||
|
|
||||||
sprintf(s, "%d", port);
|
sprintf(s, "%d", port);
|
||||||
doputenv("PGPORT", s);
|
setenv("PGPORT", s, 1);
|
||||||
}
|
}
|
||||||
if (user != NULL)
|
if (user != NULL)
|
||||||
doputenv("PGUSER", user);
|
setenv("PGUSER", user, 1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* However, we *don't* honor PGDATABASE, since we certainly don't wish
|
* However, we *don't* honor PGDATABASE, since we certainly don't wish
|
||||||
@ -2431,7 +2420,7 @@ regression_main(int argc, char *argv[], init_function ifunc, test_function tfunc
|
|||||||
fprintf(stderr, _("port %d apparently in use, trying %d\n"), port, port + 1);
|
fprintf(stderr, _("port %d apparently in use, trying %d\n"), port, port + 1);
|
||||||
port++;
|
port++;
|
||||||
sprintf(s, "%d", port);
|
sprintf(s, "%d", port);
|
||||||
doputenv("PGPORT", s);
|
setenv("PGPORT", s, 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
|
@ -91,8 +91,9 @@ psql_start_test(const char *testname,
|
|||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
appnameenv = psprintf("PGAPPNAME=pg_regress/%s", testname);
|
appnameenv = psprintf("pg_regress/%s", testname);
|
||||||
putenv(appnameenv);
|
setenv("PGAPPNAME", appnameenv, 1);
|
||||||
|
free(appnameenv);
|
||||||
|
|
||||||
pid = spawn_process(psql_cmd);
|
pid = spawn_process(psql_cmd);
|
||||||
|
|
||||||
@ -104,7 +105,6 @@ psql_start_test(const char *testname,
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsetenv("PGAPPNAME");
|
unsetenv("PGAPPNAME");
|
||||||
free(appnameenv);
|
|
||||||
|
|
||||||
return pid;
|
return pid;
|
||||||
}
|
}
|
||||||
|
@ -624,22 +624,18 @@ make_tuple_indirect(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_POINTER(newtup->t_data);
|
PG_RETURN_POINTER(newtup->t_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
PG_FUNCTION_INFO_V1(regress_putenv);
|
PG_FUNCTION_INFO_V1(regress_setenv);
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
regress_putenv(PG_FUNCTION_ARGS)
|
regress_setenv(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
MemoryContext oldcontext;
|
char *envvar = text_to_cstring(PG_GETARG_TEXT_PP(0));
|
||||||
char *envbuf;
|
char *envval = text_to_cstring(PG_GETARG_TEXT_PP(1));
|
||||||
|
|
||||||
if (!superuser())
|
if (!superuser())
|
||||||
elog(ERROR, "must be superuser to change environment variables");
|
elog(ERROR, "must be superuser to change environment variables");
|
||||||
|
|
||||||
oldcontext = MemoryContextSwitchTo(TopMemoryContext);
|
if (setenv(envvar, envval, 1) != 0)
|
||||||
envbuf = text_to_cstring((text *) PG_GETARG_POINTER(0));
|
|
||||||
MemoryContextSwitchTo(oldcontext);
|
|
||||||
|
|
||||||
if (putenv(envbuf) != 0)
|
|
||||||
elog(ERROR, "could not set environment variable: %m");
|
elog(ERROR, "could not set environment variable: %m");
|
||||||
|
|
||||||
PG_RETURN_VOID();
|
PG_RETURN_VOID();
|
||||||
|
@ -348,6 +348,7 @@ sub GenerateFiles
|
|||||||
HAVE_RL_FILENAME_QUOTING_FUNCTION => undef,
|
HAVE_RL_FILENAME_QUOTING_FUNCTION => undef,
|
||||||
HAVE_RL_RESET_SCREEN_SIZE => undef,
|
HAVE_RL_RESET_SCREEN_SIZE => undef,
|
||||||
HAVE_SECURITY_PAM_APPL_H => undef,
|
HAVE_SECURITY_PAM_APPL_H => undef,
|
||||||
|
HAVE_SETENV => undef,
|
||||||
HAVE_SETPROCTITLE => undef,
|
HAVE_SETPROCTITLE => undef,
|
||||||
HAVE_SETPROCTITLE_FAST => undef,
|
HAVE_SETPROCTITLE_FAST => undef,
|
||||||
HAVE_SETSID => undef,
|
HAVE_SETSID => undef,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user