Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/winsup
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2009-07-20 19:44:55 +0400
committerCorinna Vinschen <corinna@vinschen.de>2009-07-20 19:44:55 +0400
commit20fc2f493621f1f159bbea354e32a1d30b5f428a (patch)
treea0943ce4f47141ac69bde03caf8085ed2353ea30 /winsup
parentcb8ee36ae8a617fc6fddc36d4c2e76e7593d2765 (diff)
* wincap.h (wincaps::has_always_all_codepages): New element.
* wincap.cc: Implement above element throughout. * wchar.h (__sjis_mbtowc): Declare. (__eucjp_mbtowc): Ditto. (__gbk_mbtowc): Ditto. (__kr_mbtowc): Ditto. (__big5_mbtowc): Ditto. * syscalls.cc (internal_setlocale): Convert to char * function. Return parameter by default. Return NULL if request to use a charset can't be satisfied due to missing codepage support in the underlying OS. Fix comment. (setlocale): Store original locale. Restore to original locale if internal_setlocale returns NULL.
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/ChangeLog16
-rw-r--r--winsup/cygwin/syscalls.cc43
-rw-r--r--winsup/cygwin/wchar.h5
-rw-r--r--winsup/cygwin/wincap.cc11
-rw-r--r--winsup/cygwin/wincap.h2
5 files changed, 71 insertions, 6 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 9e78d09dd..ebe1f7275 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,5 +1,21 @@
2009-07-20 Corinna Vinschen <corinna@vinschen.de>
+ * wincap.h (wincaps::has_always_all_codepages): New element.
+ * wincap.cc: Implement above element throughout.
+ * wchar.h (__sjis_mbtowc): Declare.
+ (__eucjp_mbtowc): Ditto.
+ (__gbk_mbtowc): Ditto.
+ (__kr_mbtowc): Ditto.
+ (__big5_mbtowc): Ditto.
+ * syscalls.cc (internal_setlocale): Convert to char * function.
+ Return parameter by default. Return NULL if request to use a
+ charset can't be satisfied due to missing codepage support in the
+ underlying OS. Fix comment.
+ (setlocale): Store original locale. Restore to original locale if
+ internal_setlocale returns NULL.
+
+2009-07-20 Corinna Vinschen <corinna@vinschen.de>
+
* fork.cc (fork): Create local tmp_pathbuf. Explain why.
2009-07-18 Christopher Faylor <me+cygwin@cgf.cx>
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index 6f2de057a..64d9001e3 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -24,6 +24,7 @@ details. */
#define pwrite __FOO_pwrite
#include "winsup.h"
+#include "winnls.h"
#include "miscfuncs.h"
#include <sys/stat.h>
#include <sys/vfs.h> /* needed for statfs */
@@ -36,6 +37,7 @@ details. */
#include <sys/uio.h>
#include <ctype.h>
#include <locale.h>
+#include <wchar.h>
#include <unistd.h>
#include <sys/wait.h>
#include <rpc.h>
@@ -4031,32 +4033,61 @@ unlinkat (int dirfd, const char *pathname, int flags)
return (flags & AT_REMOVEDIR) ? rmdir (path) : unlink (path);
}
-static void
-internal_setlocale ()
+static char *
+internal_setlocale (char *ret)
{
- if (*cygheap->locale.charset == 'A')
+ if (*__locale_charset () == 'A')
{
cygheap->locale.mbtowc = __utf8_mbtowc;
cygheap->locale.wctomb = __utf8_wctomb;
}
else
{
+ if (!wincap.has_always_all_codepages ())
+ {
+ /* Prior to Windows Vista, many codepages are not installed by
+ default, or can be deinstalled. The following codepages require
+ that the respective conversion tables are installed into the OS.
+ So we check if they are installed and if not, setlocale should
+ fail. */
+ CPINFO cpi;
+ UINT cp = 0;
+ if (__mbtowc == __sjis_mbtowc)
+ cp = 932;
+ else if (__mbtowc == __eucjp_mbtowc)
+ cp = 20932;
+ else if (__mbtowc == __gbk_mbtowc)
+ cp = 963;
+ else if (__mbtowc == __kr_mbtowc)
+ cp = 949;
+ else if (__mbtowc == __big5_mbtowc)
+ cp = 950;
+ if (cp && !GetCPInfo (cp, &cpi)
+ && GetLastError () == ERROR_INVALID_PARAMETER)
+ return NULL;
+ }
cygheap->locale.mbtowc = __mbtowc;
cygheap->locale.wctomb = __wctomb;
}
strcpy (cygheap->locale.charset, __locale_charset ());
/* Each setlocale potentially changes the multibyte representation
- of the CWD. Therefore we have to rest the CWD's posix path and
+ of the CWD. Therefore we have to reset the CWD's posix path and
reevaluate the next time it's used. */
/* FIXME: Other buffered paths might be affected as well. */
cygheap->cwd.reset_posix ();
+ return ret;
}
extern "C" char *
setlocale (int category, const char *locale)
{
+ char old[(LC_MESSAGES + 1) * (ENCODING_LEN + 1/*"/"*/ + 1)];
+ if (locale && (category == LC_ALL || category == LC_CTYPE)
+ && !wincap.has_always_all_codepages ())
+ stpcpy (old, _setlocale_r (_REENT, category, NULL));
char *ret = _setlocale_r (_REENT, category, locale);
- if (ret && locale && (category == LC_ALL || category == LC_CTYPE))
- internal_setlocale ();
+ if (ret && locale && (category == LC_ALL || category == LC_CTYPE)
+ && !(ret = internal_setlocale (ret)))
+ _setlocale_r (_REENT, category, old);
return ret;
}
diff --git a/winsup/cygwin/wchar.h b/winsup/cygwin/wchar.h
index fc8eb3858..f989b7d11 100644
--- a/winsup/cygwin/wchar.h
+++ b/winsup/cygwin/wchar.h
@@ -28,6 +28,11 @@ extern mbtowc_f __ascii_mbtowc;
extern mbtowc_f __utf8_mbtowc;
extern mbtowc_f __iso_mbtowc;
extern mbtowc_f __cp_mbtowc;
+extern mbtowc_f __sjis_mbtowc;
+extern mbtowc_f __eucjp_mbtowc;
+extern mbtowc_f __gbk_mbtowc;
+extern mbtowc_f __kr_mbtowc;
+extern mbtowc_f __big5_mbtowc;
typedef int wctomb_f (struct _reent *, char *, wchar_t, const char *,
mbstate_t *);
diff --git a/winsup/cygwin/wincap.cc b/winsup/cygwin/wincap.cc
index 774925ec7..84e530d3f 100644
--- a/winsup/cygwin/wincap.cc
+++ b/winsup/cygwin/wincap.cc
@@ -56,6 +56,7 @@ wincaps wincap_unknown __attribute__((section (".cygwin_dll_common"), shared)) =
has_broken_udf:false,
has_console_handle_problem:false,
has_broken_alloc_console:false,
+ has_always_all_codepages:false,
};
wincaps wincap_nt4 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -94,6 +95,7 @@ wincaps wincap_nt4 __attribute__((section (".cygwin_dll_common"), shared)) = {
has_broken_udf:false,
has_console_handle_problem:false,
has_broken_alloc_console:false,
+ has_always_all_codepages:false,
};
wincaps wincap_nt4sp4 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -132,6 +134,7 @@ wincaps wincap_nt4sp4 __attribute__((section (".cygwin_dll_common"), shared)) =
has_broken_udf:false,
has_console_handle_problem:false,
has_broken_alloc_console:false,
+ has_always_all_codepages:false,
};
wincaps wincap_2000 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -170,6 +173,7 @@ wincaps wincap_2000 __attribute__((section (".cygwin_dll_common"), shared)) = {
has_broken_udf:true,
has_console_handle_problem:false,
has_broken_alloc_console:false,
+ has_always_all_codepages:false,
};
wincaps wincap_2000sp4 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -208,6 +212,7 @@ wincaps wincap_2000sp4 __attribute__((section (".cygwin_dll_common"), shared)) =
has_broken_udf:true,
has_console_handle_problem:false,
has_broken_alloc_console:false,
+ has_always_all_codepages:false,
};
wincaps wincap_xp __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -246,6 +251,7 @@ wincaps wincap_xp __attribute__((section (".cygwin_dll_common"), shared)) = {
has_broken_udf:true,
has_console_handle_problem:false,
has_broken_alloc_console:false,
+ has_always_all_codepages:false,
};
wincaps wincap_xpsp1 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -284,6 +290,7 @@ wincaps wincap_xpsp1 __attribute__((section (".cygwin_dll_common"), shared)) = {
has_broken_udf:true,
has_console_handle_problem:false,
has_broken_alloc_console:false,
+ has_always_all_codepages:false,
};
wincaps wincap_xpsp2 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -322,6 +329,7 @@ wincaps wincap_xpsp2 __attribute__((section (".cygwin_dll_common"), shared)) = {
has_broken_udf:true,
has_console_handle_problem:false,
has_broken_alloc_console:false,
+ has_always_all_codepages:false,
};
wincaps wincap_2003 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -360,6 +368,7 @@ wincaps wincap_2003 __attribute__((section (".cygwin_dll_common"), shared)) = {
has_broken_udf:true,
has_console_handle_problem:false,
has_broken_alloc_console:false,
+ has_always_all_codepages:false,
};
wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -398,6 +407,7 @@ wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = {
has_broken_udf:false,
has_console_handle_problem:false,
has_broken_alloc_console:false,
+ has_always_all_codepages:true,
};
wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -436,6 +446,7 @@ wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = {
has_broken_udf:false,
has_console_handle_problem:true,
has_broken_alloc_console:true,
+ has_always_all_codepages:true,
};
wincapc wincap __attribute__((section (".cygwin_dll_common"), shared));
diff --git a/winsup/cygwin/wincap.h b/winsup/cygwin/wincap.h
index ed6eaa9c9..74955ff63 100644
--- a/winsup/cygwin/wincap.h
+++ b/winsup/cygwin/wincap.h
@@ -48,6 +48,7 @@ struct wincaps
unsigned has_broken_udf : 1;
unsigned has_console_handle_problem : 1;
unsigned has_broken_alloc_console : 1;
+ unsigned has_always_all_codepages : 1;
};
class wincapc
@@ -102,6 +103,7 @@ public:
bool IMPLEMENT (has_broken_udf)
bool IMPLEMENT (has_console_handle_problem)
bool IMPLEMENT (has_broken_alloc_console)
+ bool IMPLEMENT (has_always_all_codepages)
#undef IMPLEMENT
};