|
4 | 4 | * controldata functions
|
5 | 5 | *
|
6 | 6 | * Copyright (c) 2010, PostgreSQL Global Development Group
|
7 |
| - * $PostgreSQL: pgsql/contrib/pg_upgrade/controldata.c,v 1.9 2010/07/06 19:18:55 momjian Exp $ |
| 7 | + * $PostgreSQL: pgsql/contrib/pg_upgrade/controldata.c,v 1.10 2010/09/07 14:10:30 momjian Exp $ |
8 | 8 | */
|
9 | 9 |
|
10 | 10 | #include "pg_upgrade.h"
|
11 | 11 |
|
12 | 12 | #include <ctype.h>
|
13 | 13 |
|
| 14 | +static void putenv2(migratorContext *ctx, const char *var, const char *val); |
14 | 15 |
|
15 | 16 | /*
|
16 | 17 | * get_control_data()
|
@@ -51,19 +52,55 @@ get_control_data(migratorContext *ctx, ClusterInfo *cluster, bool live_check)
|
51 | 52 | bool got_toast = false;
|
52 | 53 | bool got_date_is_int = false;
|
53 | 54 | bool got_float8_pass_by_value = false;
|
| 55 | + char *lc_collate = NULL; |
| 56 | + char *lc_ctype = NULL; |
| 57 | + char *lc_monetary = NULL; |
| 58 | + char *lc_numeric = NULL; |
| 59 | + char *lc_time = NULL; |
54 | 60 | char *lang = NULL;
|
| 61 | + char *language = NULL; |
| 62 | + char *lc_all = NULL; |
| 63 | + char *lc_messages = NULL; |
55 | 64 |
|
56 | 65 | /*
|
57 |
| - * Because we test the pg_resetxlog output strings, it has to be in |
58 |
| - * English. |
| 66 | + * Because we test the pg_resetxlog output as strings, it has to be in |
| 67 | + * English. Copied from pg_regress.c. |
59 | 68 | */
|
| 69 | + if (getenv("LC_COLLATE")) |
| 70 | + lc_collate = pg_strdup(ctx, getenv("LC_COLLATE")); |
| 71 | + if (getenv("LC_CTYPE")) |
| 72 | + lc_ctype = pg_strdup(ctx, getenv("LC_CTYPE")); |
| 73 | + if (getenv("LC_MONETARY")) |
| 74 | + lc_monetary = pg_strdup(ctx, getenv("LC_MONETARY")); |
| 75 | + if (getenv("LC_NUMERIC")) |
| 76 | + lc_numeric = pg_strdup(ctx, getenv("LC_NUMERIC")); |
| 77 | + if (getenv("LC_TIME")) |
| 78 | + lc_time = pg_strdup(ctx, getenv("LC_TIME")); |
60 | 79 | if (getenv("LANG"))
|
61 | 80 | lang = pg_strdup(ctx, getenv("LANG"));
|
| 81 | + if (getenv("LANGUAGE")) |
| 82 | + language = pg_strdup(ctx, getenv("LANGUAGE")); |
| 83 | + if (getenv("LC_ALL")) |
| 84 | + lc_all = pg_strdup(ctx, getenv("LC_ALL")); |
| 85 | + if (getenv("LC_MESSAGES")) |
| 86 | + lc_messages = pg_strdup(ctx, getenv("LC_MESSAGES")); |
| 87 | + |
| 88 | + putenv2(ctx, "LC_COLLATE", NULL); |
| 89 | + putenv2(ctx, "LC_CTYPE", NULL); |
| 90 | + putenv2(ctx, "LC_MONETARY", NULL); |
| 91 | + putenv2(ctx, "LC_NUMERIC", NULL); |
| 92 | + putenv2(ctx, "LC_TIME", NULL); |
| 93 | + putenv2(ctx, "LANG", |
62 | 94 | #ifndef WIN32
|
63 |
| - putenv(pg_strdup(ctx, "LANG=C")); |
| 95 | + NULL); |
64 | 96 | #else
|
65 |
| - SetEnvironmentVariableA("LANG", "C"); |
| 97 | + /* On Windows the default locale cannot be English, so force it */ |
| 98 | + "en"); |
66 | 99 | #endif
|
| 100 | + putenv2(ctx, "LANGUAGE", NULL); |
| 101 | + putenv2(ctx, "LC_ALL", NULL); |
| 102 | + putenv2(ctx, "LC_MESSAGES", "C"); |
| 103 | + |
67 | 104 | snprintf(cmd, sizeof(cmd), SYSTEMQUOTE "\"%s/%s \"%s\"" SYSTEMQUOTE,
|
68 | 105 | cluster->bindir,
|
69 | 106 | live_check ? "pg_controldata\"" : "pg_resetxlog\" -n",
|
@@ -334,28 +371,29 @@ get_control_data(migratorContext *ctx, ClusterInfo *cluster, bool live_check)
|
334 | 371 | if (output)
|
335 | 372 | pclose(output);
|
336 | 373 |
|
337 |
| - /* restore LANG */ |
338 |
| - if (lang) |
339 |
| - { |
340 |
| -#ifndef WIN32 |
341 |
| - char *envstr = (char *) pg_malloc(ctx, strlen(lang) + 6); |
342 |
| - |
343 |
| - sprintf(envstr, "LANG=%s", lang); |
344 |
| - putenv(envstr); |
345 |
| -#else |
346 |
| - SetEnvironmentVariableA("LANG", lang); |
347 |
| -#endif |
348 |
| - pg_free(lang); |
349 |
| - } |
350 |
| - else |
351 |
| - { |
352 |
| -#ifndef WIN32 |
353 |
| - unsetenv("LANG"); |
354 |
| -#else |
355 |
| - SetEnvironmentVariableA("LANG", ""); |
356 |
| -#endif |
357 |
| - } |
358 |
| - |
| 374 | + /* |
| 375 | + * Restore environment variables |
| 376 | + */ |
| 377 | + putenv2(ctx, "LC_COLLATE", lc_collate); |
| 378 | + putenv2(ctx, "LC_CTYPE", lc_ctype); |
| 379 | + putenv2(ctx, "LC_MONETARY", lc_monetary); |
| 380 | + putenv2(ctx, "LC_NUMERIC", lc_numeric); |
| 381 | + putenv2(ctx, "LC_TIME", lc_time); |
| 382 | + putenv2(ctx, "LANG", lang); |
| 383 | + putenv2(ctx, "LANGUAGE", language); |
| 384 | + putenv2(ctx, "LC_ALL", lc_all); |
| 385 | + putenv2(ctx, "LC_MESSAGES", lc_messages); |
| 386 | + |
| 387 | + pg_free(lc_collate); |
| 388 | + pg_free(lc_ctype); |
| 389 | + pg_free(lc_monetary); |
| 390 | + pg_free(lc_numeric); |
| 391 | + pg_free(lc_time); |
| 392 | + pg_free(lang); |
| 393 | + pg_free(language); |
| 394 | + pg_free(lc_all); |
| 395 | + pg_free(lc_messages); |
| 396 | + |
359 | 397 | /* verify that we got all the mandatory pg_control data */
|
360 | 398 | if (!got_xid || !got_oid ||
|
361 | 399 | (!live_check && !got_log_id) ||
|
@@ -492,3 +530,39 @@ rename_old_pg_control(migratorContext *ctx)
|
492 | 530 | pg_log(ctx, PG_FATAL, "Unable to rename %s to %s.\n", old_path, new_path);
|
493 | 531 | check_ok(ctx);
|
494 | 532 | }
|
| 533 | + |
| 534 | + |
| 535 | +/* |
| 536 | + * putenv2() |
| 537 | + * |
| 538 | + * This is like putenv(), but takes two arguments. |
| 539 | + * It also does unsetenv() if val is NULL. |
| 540 | + */ |
| 541 | +static void |
| 542 | +putenv2(migratorContext *ctx, const char *var, const char *val) |
| 543 | +{ |
| 544 | + if (val) |
| 545 | + { |
| 546 | +#ifndef WIN32 |
| 547 | + char *envstr = (char *) pg_malloc(ctx, strlen(var) + |
| 548 | + strlen(val) + 1); |
| 549 | + |
| 550 | + sprintf(envstr, "%s=%s", var, val); |
| 551 | + putenv(envstr); |
| 552 | + /* |
| 553 | + * Do not free envstr because it becomes part of the environment |
| 554 | + * on some operating systems. See port/unsetenv.c::unsetenv. |
| 555 | + */ |
| 556 | +#else |
| 557 | + SetEnvironmentVariableA(var, val); |
| 558 | +#endif |
| 559 | + } |
| 560 | + else |
| 561 | + { |
| 562 | +#ifndef WIN32 |
| 563 | + unsetenv(var); |
| 564 | +#else |
| 565 | + SetEnvironmentVariableA(var, ""); |
| 566 | +#endif |
| 567 | + } |
| 568 | +} |
0 commit comments