Skip to content

Commit 9619608

Browse files
committed
bugfix: cross-platform setenv and getenv
1 parent 84e6397 commit 9619608

File tree

3 files changed

+67
-6
lines changed

3 files changed

+67
-6
lines changed

src/pg_probackup.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1158,6 +1158,9 @@ extern void fio_list_dir(parray *files, const char *root, bool exclude, bool fol
11581158

11591159
extern bool pgut_rmtree(const char *path, bool rmtopdir, bool strict);
11601160

1161+
extern void pgut_setenv(const char *key, const char *val);
1162+
extern void pgut_unsetenv(const char *key);
1163+
11611164
extern PageState *fio_get_checksum_map(const char *fullpath, uint32 checksum_version, int n_blocks,
11621165
XLogRecPtr dest_stop_lsn, BlockNumber segmentno, fio_location location);
11631166

src/utils/configuration.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1229,16 +1229,16 @@ parse_time(const char *value, time_t *result, bool utc_default)
12291229
*/
12301230
if (tz_set || utc_default)
12311231
/* set timezone to UTC */
1232-
setenv("TZ", "UTC", 1);
1232+
pgut_setenv("TZ", "UTC");
12331233

12341234
/* convert time to utc unix time */
12351235
*result = mktime(&tm);
12361236

12371237
/* return old timezone back if any */
12381238
if (local_tz)
1239-
setenv("TZ", local_tz, 1);
1239+
pgut_setenv("TZ", local_tz);
12401240
else
1241-
unsetenv("TZ");
1241+
pgut_unsetenv("TZ");
12421242

12431243
/* adjust time zone */
12441244
if (tz_set || utc_default)
@@ -1480,7 +1480,7 @@ time2iso(char *buf, size_t len, time_t time, bool utc)
14801480

14811481
/* set timezone to UTC if requested */
14821482
if (utc)
1483-
setenv("TZ", "UTC", 1);
1483+
pgut_setenv("TZ", "UTC");
14841484

14851485
ptm = gmtime(&time);
14861486
gmt = mktime(ptm);
@@ -1490,9 +1490,9 @@ time2iso(char *buf, size_t len, time_t time, bool utc)
14901490
{
14911491
/* return old timezone back if any */
14921492
if (local_tz)
1493-
setenv("TZ", local_tz, 1);
1493+
pgut_setenv("TZ", local_tz);
14941494
else
1495-
unsetenv("TZ");
1495+
pgut_unsetenv("TZ");
14961496
}
14971497

14981498
/* adjust timezone offset */

src/utils/pgut.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1213,3 +1213,61 @@ pgut_rmtree(const char *path, bool rmtopdir, bool strict)
12131213

12141214
return result;
12151215
}
1216+
1217+
/* cross-platform setenv */
1218+
void
1219+
pgut_setenv(const char *key, const char *val)
1220+
{
1221+
#ifdef WIN32
1222+
char *envstr = NULL;
1223+
envstr = psprintf("%s=%s", key, val);
1224+
putenv(envstr);
1225+
#else
1226+
setenv(key, val, 1);
1227+
#endif
1228+
}
1229+
1230+
/* stolen from unsetenv.c */
1231+
void
1232+
pgut_unsetenv(const char *key)
1233+
{
1234+
#ifdef WIN32
1235+
char *envstr = NULL;
1236+
1237+
if (getenv(key) == NULL)
1238+
return; /* no work */
1239+
1240+
/*
1241+
* The technique embodied here works if libc follows the Single Unix Spec
1242+
* and actually uses the storage passed to putenv() to hold the environ
1243+
* entry. When we clobber the entry in the second step we are ensuring
1244+
* that we zap the actual environ member. However, there are some libc
1245+
* implementations (notably recent BSDs) that do not obey SUS but copy the
1246+
* presented string. This method fails on such platforms. Hopefully all
1247+
* such platforms have unsetenv() and thus won't be using this hack. See:
1248+
* http://www.greenend.org.uk/rjk/2008/putenv.html
1249+
*
1250+
* Note that repeatedly setting and unsetting a var using this code will
1251+
* leak memory.
1252+
*/
1253+
1254+
envstr = (char *) malloc(strlen(key) + 2);
1255+
if (!envstr) /* not much we can do if no memory */
1256+
return;
1257+
1258+
/* Override the existing setting by forcibly defining the var */
1259+
sprintf(envstr, "%s=", key);
1260+
putenv(envstr);
1261+
1262+
/* Now we can clobber the variable definition this way: */
1263+
strcpy(envstr, "=");
1264+
1265+
/*
1266+
* This last putenv cleans up if we have multiple zero-length names as a
1267+
* result of unsetting multiple things.
1268+
*/
1269+
putenv(envstr);
1270+
#else
1271+
unsetenv(key);
1272+
#endif
1273+
}

0 commit comments

Comments
 (0)