summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-03-15 03:57:02 +0000
committerusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-03-15 03:57:02 +0000
commitfcaee4bd64eb06ec4d0afd4e7e32ccf57acb5dc8 (patch)
tree79915a498af26746f5f1b1be60b90b7b1230b58d
parentc6671f1005a19ee755c066fd882271afb86ccbbf (diff)
* win32/win32.c, include/ruby/win32.h (rb_w32_ugetenv): new API to
accept and to return UTF-8 strings. * win32/win32.c (rb_w32_getenv): follow above change. * win32/win32.c (rb_w32_get_environ): returns UTF-8 environment area. * hash.c (env_str_new, rb_f_getenv, env_fetch): follow above changes. [Bug #5570] [ruby-core:40737] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@35030 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog12
-rw-r--r--hash.c14
-rw-r--r--include/ruby/win32.h1
-rw-r--r--win32/win32.c67
4 files changed, 86 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index 76bbe927b1..4247852ec6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+Thu Mar 15 12:44:50 2012 NAKAMURA Usaku <usa@ruby-lang.org>
+
+ * win32/win32.c, include/ruby/win32.h (rb_w32_ugetenv): new API to
+ accept and to return UTF-8 strings.
+
+ * win32/win32.c (rb_w32_getenv): follow above change.
+
+ * win32/win32.c (rb_w32_get_environ): returns UTF-8 environment area.
+
+ * hash.c (env_str_new, rb_f_getenv, env_fetch): follow above changes.
+ [Bug #5570] [ruby-core:40737]
+
Thu Mar 15 10:57:27 2012 Shugo Maeda <shugo@ruby-lang.org>
* enumerator.c (lazy_cycle): add Enumerable::Lazy#cycle.
diff --git a/hash.c b/hash.c
index 84a80bd086..ee703f59d4 100644
--- a/hash.c
+++ b/hash.c
@@ -2008,6 +2008,8 @@ static char **origenviron;
static char **my_environ;
#undef environ
#define environ my_environ
+#undef getenv
+#define getenv(n) rb_w32_ugetenv(n)
#elif defined(__APPLE__)
#undef environ
#define environ (*_NSGetEnviron())
@@ -2029,7 +2031,11 @@ extern char **environ;
static VALUE
env_str_new(const char *ptr, long len)
{
+#ifdef _WIN32
+ VALUE str = rb_str_encode(rb_enc_str_new(ptr, len, rb_utf8_encoding()), rb_enc_from_encoding(rb_locale_encoding()), 0, Qnil);
+#else
VALUE str = rb_locale_str_new(ptr, len);
+#endif
rb_obj_freeze(str);
return str;
@@ -2108,7 +2114,11 @@ rb_f_getenv(VALUE obj, VALUE name)
env = getenv(nam);
if (env) {
if (ENVMATCH(nam, PATH_ENV) && !env_path_tainted(env)) {
+#ifdef _WIN32
+ VALUE str = rb_str_encode(rb_enc_str_new(env, strlen(env), rb_utf8_encoding()), rb_enc_from_encoding(rb_filesystem_encoding()), 0, Qnil);
+#else
VALUE str = rb_filesystem_str_new_cstr(env);
+#endif
rb_obj_freeze(str);
return str;
@@ -2159,7 +2169,11 @@ env_fetch(int argc, VALUE *argv)
return if_none;
}
if (ENVMATCH(nam, PATH_ENV) && !env_path_tainted(env))
+#ifdef _WIN32
+ return rb_str_encode(rb_enc_str_new(env, strlen(env), rb_utf8_encoding()), rb_enc_from_encoding(rb_filesystem_encoding()), 0, Qnil);
+#else
return rb_filesystem_str_new_cstr(env);
+#endif
return env_str_new2(env);
}
diff --git a/include/ruby/win32.h b/include/ruby/win32.h
index d49a9b4f71..807d388ed9 100644
--- a/include/ruby/win32.h
+++ b/include/ruby/win32.h
@@ -268,6 +268,7 @@ extern struct servent *WSAAPI rb_w32_getservbyname(const char *, const char *);
extern struct servent *WSAAPI rb_w32_getservbyport(int, const char *);
extern int rb_w32_socketpair(int, int, int, int *);
extern char * rb_w32_getcwd(char *, int);
+extern char * rb_w32_ugetenv(const char *);
extern char * rb_w32_getenv(const char *);
extern int rb_w32_rename(const char *, const char *);
extern int rb_w32_urename(const char *, const char *);
diff --git a/win32/win32.c b/win32/win32.c
index 744c61489e..37b3943036 100644
--- a/win32/win32.c
+++ b/win32/win32.c
@@ -630,6 +630,7 @@ static CRITICAL_SECTION select_mutex;
static int NtSocketsInitialized = 0;
static st_table *socklist = NULL;
static char *envarea;
+static char *uenvarea;
/* License: Ruby's */
static void
@@ -648,6 +649,10 @@ exit_handler(void)
FreeEnvironmentStrings(envarea);
envarea = NULL;
}
+ if (uenvarea) {
+ free(uenvarea);
+ uenvarea = NULL;
+ }
}
/* License: Artistic or GPL */
@@ -4236,13 +4241,58 @@ wait(int *status)
/* License: Ruby's */
char *
+rb_w32_ugetenv(const char *name)
+{
+ WCHAR *wenvarea, *wenv;
+ int len = strlen(name);
+ char *env;
+ int wlen;
+
+ if (len == 0) return NULL;
+
+ if (uenvarea) {
+ free(uenvarea);
+ uenvarea = NULL;
+ }
+ if (envarea) {
+ FreeEnvironmentStrings(envarea);
+ envarea = NULL;
+ }
+ wenvarea = GetEnvironmentStringsW();
+ if (!wenvarea) {
+ map_errno(GetLastError());
+ return NULL;
+ }
+ for (wenv = wenvarea, wlen = 1; *wenv; wenv += lstrlenW(wenv) + 1)
+ wlen += lstrlenW(wenv) + 1;
+ uenvarea = wstr_to_mbstr(CP_UTF8, wenvarea, wlen, NULL);
+ FreeEnvironmentStringsW(wenvarea);
+ if (!uenvarea)
+ return NULL;
+
+ for (env = uenvarea; *env; env += strlen(env) + 1)
+ if (strncasecmp(env, name, len) == 0 && *(env + len) == '=')
+ return env + len + 1;
+
+ return NULL;
+}
+
+/* License: Ruby's */
+char *
rb_w32_getenv(const char *name)
{
int len = strlen(name);
char *env;
if (len == 0) return NULL;
- if (envarea) FreeEnvironmentStrings(envarea);
+ if (uenvarea) {
+ free(uenvarea);
+ uenvarea = NULL;
+ }
+ if (envarea) {
+ FreeEnvironmentStrings(envarea);
+ envarea = NULL;
+ }
envarea = GetEnvironmentStrings();
if (!envarea) {
map_errno(GetLastError());
@@ -5011,7 +5061,7 @@ rb_w32_asynchronize(asynchronous_func_t func, uintptr_t self,
char **
rb_w32_get_environ(void)
{
- char *envtop, *env;
+ WCHAR *envtop, *env;
char **myenvtop, **myenv;
int num;
@@ -5022,23 +5072,24 @@ rb_w32_get_environ(void)
* CygWin deals these values by changing first `=' to '!'. But we don't
* use such trick and follow cmd.exe's way that just doesn't show these
* values.
- * (U.N. 2001-11-15)
+ *
+ * This function returns UTF-8 strings.
*/
- envtop = GetEnvironmentStrings();
- for (env = envtop, num = 0; *env; env += strlen(env) + 1)
+ envtop = GetEnvironmentStringsW();
+ for (env = envtop, num = 0; *env; env += lstrlenW(env) + 1)
if (*env != '=') num++;
myenvtop = (char **)malloc(sizeof(char *) * (num + 1));
- for (env = envtop, myenv = myenvtop; *env; env += strlen(env) + 1) {
+ for (env = envtop, myenv = myenvtop; *env; env += lstrlenW(env) + 1) {
if (*env != '=') {
- if (!(*myenv = strdup(env))) {
+ if (!(*myenv = wstr_to_utf8(env, NULL))) {
break;
}
myenv++;
}
}
*myenv = NULL;
- FreeEnvironmentStrings(envtop);
+ FreeEnvironmentStringsW(envtop);
return myenvtop;
}