summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main/main.c6
-rw-r--r--win32/codepage.c57
2 files changed, 53 insertions, 10 deletions
diff --git a/main/main.c b/main/main.c
index da96e7789d..193d88bc44 100644
--- a/main/main.c
+++ b/main/main.c
@@ -430,6 +430,9 @@ static PHP_INI_MH(OnUpdateInputEncoding)
{
if (new_value) {
OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
+#ifdef PHP_WIN32
+ php_win32_cp_do_update(NULL);
+#endif
}
return SUCCESS;
}
@@ -441,6 +444,9 @@ static PHP_INI_MH(OnUpdateOutputEncoding)
{
if (new_value) {
OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
+#ifdef PHP_WIN32
+ php_win32_cp_do_update(NULL);
+#endif
}
return SUCCESS;
}
diff --git a/win32/codepage.c b/win32/codepage.c
index cddd94687d..511e42843c 100644
--- a/win32/codepage.c
+++ b/win32/codepage.c
@@ -21,8 +21,12 @@
#include "php.h"
#include "SAPI.h"
-ZEND_TLS const struct php_win32_cp *cur_cp = NULL;
+ZEND_TLS const struct php_win32_cp *cur_cp = NULL;
ZEND_TLS const struct php_win32_cp *orig_cp = NULL;
+ZEND_TLS const struct php_win32_cp *cur_out_cp = NULL;
+ZEND_TLS const struct php_win32_cp *orig_out_cp = NULL;
+ZEND_TLS const struct php_win32_cp *cur_in_cp = NULL;
+ZEND_TLS const struct php_win32_cp *orig_in_cp = NULL;
#include "cp_enc_map.c"
@@ -291,7 +295,6 @@ PW32CP const struct php_win32_cp *php_win32_cp_get_by_enc(const char *enc)
}
if (0 == zend_binary_strcasecmp(enc, enc_len, cp->name, strlen(cp->name))) {
- cur_cp = cp;
return cp;
}
@@ -302,7 +305,6 @@ PW32CP const struct php_win32_cp *php_win32_cp_get_by_enc(const char *enc)
while (NULL != idx) {
if (0 == zend_binary_strcasecmp(enc, enc_len, start, idx - start)) {
- cur_cp = cp;
return cp;
}
start = idx + 1;
@@ -310,7 +312,6 @@ PW32CP const struct php_win32_cp *php_win32_cp_get_by_enc(const char *enc)
}
/* Last in the list, or single charset specified. */
if (0 == zend_binary_strcasecmp(enc, enc_len, start, strlen(start))) {
- cur_cp = cp;
return cp;
}
}
@@ -381,18 +382,54 @@ PW32CP wchar_t *php_win32_cp_env_any_to_w(const char* env)
return envw;
}/*}}}*/
+static BOOL php_win32_cp_cli_io_setup(void)
+{
+ if (PG(input_encoding) && PG(input_encoding)[0]) {
+ cur_in_cp = php_win32_cp_get_by_enc(PG(input_encoding));
+ if (!cur_in_cp) {
+ cur_in_cp = cur_cp;
+ }
+ } else {
+ cur_in_cp = cur_cp;
+ }
+
+ if (PG(output_encoding) && PG(output_encoding)[0]) {
+ cur_out_cp = php_win32_cp_get_by_enc(PG(output_encoding));
+ if (!cur_out_cp) {
+ cur_out_cp = cur_cp;
+ }
+ } else {
+ cur_out_cp = cur_cp;
+ }
+
+ return SetConsoleCP(cur_in_cp->id) && SetConsoleOutputCP(cur_out_cp->id);
+}
+
PW32CP const struct php_win32_cp *php_win32_cp_do_setup(const char *enc)
{/*{{{*/
if (!enc) {
enc = php_win32_cp_get_enc();
}
- if (!strcmp(sapi_module.name, "cli")) {
- orig_cp = php_win32_cp_get_by_id(GetConsoleCP());
- } else {
+ cur_cp = php_win32_cp_get_by_enc(enc);
+ if (!orig_cp) {
orig_cp = php_win32_cp_get_by_id(GetACP());
}
- cur_cp = php_win32_cp_get_by_enc(enc);
+ if (!strcmp(sapi_module.name, "cli")) {
+ if (!orig_in_cp) {
+ orig_in_cp = php_win32_cp_get_by_id(GetConsoleCP());
+ if (!orig_in_cp) {
+ orig_in_cp = orig_cp;
+ }
+ }
+ if (!orig_out_cp) {
+ orig_out_cp = php_win32_cp_get_by_id(GetConsoleOutputCP());
+ if (!orig_out_cp) {
+ orig_out_cp = orig_cp;
+ }
+ }
+ php_win32_cp_cli_io_setup();
+ }
return cur_cp;
}/*}}}*/
@@ -435,7 +472,7 @@ PW32CP const struct php_win32_cp *php_win32_cp_cli_do_setup(DWORD id)
return NULL;
}
- if (SetConsoleOutputCP(cp->id) && SetConsoleCP(cp->id)) {
+ if (php_win32_cp_cli_io_setup()) {
return cp;
}
@@ -448,7 +485,7 @@ PW32CP const struct php_win32_cp *php_win32_cp_cli_do_restore(DWORD id)
id = orig_cp->id;
}
- if (SetConsoleOutputCP(id) && SetConsoleCP(id)) {
+ if (SetConsoleCP(orig_in_cp->id) && SetConsoleOutputCP(orig_out_cp->id)) {
if (orig_cp) {
return orig_cp;
} else {