4153167: separate between ANSI and OEM code pages on Windows
authorsherman
Thu, 16 Feb 2012 22:13:10 -0800
changeset 11906 dc984e35d8a6
parent 11905 646e7e50c2d7
child 11907 c021db66251d
4153167: separate between ANSI and OEM code pages on Windows Summary: To use OEM code page for System.out&err when not redirected Reviewed-by: alanb
jdk/src/share/classes/java/lang/System.java
jdk/src/share/native/java/lang/System.c
jdk/src/share/native/java/lang/java_props.h
jdk/src/windows/native/java/lang/java_props_md.c
--- a/jdk/src/share/classes/java/lang/System.java	Thu Feb 16 11:43:20 2012 -0800
+++ b/jdk/src/share/classes/java/lang/System.java	Thu Feb 16 22:13:10 2012 -0800
@@ -1100,6 +1100,19 @@
     public static native String mapLibraryName(String libname);
 
     /**
+     * Create PrintStream for stdout/err based on encoding.
+     */
+    private static PrintStream newPrintStream(FileOutputStream fos, String enc) {
+       if (enc != null) {
+            try {
+                return new PrintStream(new BufferedOutputStream(fos, 128), true, enc);
+            } catch (UnsupportedEncodingException uee) {}
+        }
+        return new PrintStream(new BufferedOutputStream(fos, 128), true);
+    }
+
+
+    /**
      * Initialize the system class.  Called after thread initialization.
      */
     private static void initializeSystemClass() {
@@ -1139,8 +1152,9 @@
         FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);
         FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err);
         setIn0(new BufferedInputStream(fdIn));
-        setOut0(new PrintStream(new BufferedOutputStream(fdOut, 128), true));
-        setErr0(new PrintStream(new BufferedOutputStream(fdErr, 128), true));
+        setOut0(newPrintStream(fdOut, props.getProperty("sun.stdout.encoding")));
+        setErr0(newPrintStream(fdErr, props.getProperty("sun.stderr.encoding")));
+
         // Load the zip library now in order to keep java.util.zip.ZipFile
         // from trying to use itself to load this library later.
         loadLibrary("zip");
--- a/jdk/src/share/native/java/lang/System.c	Thu Feb 16 11:43:20 2012 -0800
+++ b/jdk/src/share/native/java/lang/System.c	Thu Feb 16 22:13:10 2012 -0800
@@ -235,7 +235,14 @@
     }
     PUTPROP(props, "file.encoding", sprops->encoding);
     PUTPROP(props, "sun.jnu.encoding", sprops->sun_jnu_encoding);
+    if (sprops->sun_stdout_encoding != NULL) {
+        PUTPROP(props, "sun.stdout.encoding", sprops->sun_stdout_encoding);
+    }
+    if (sprops->sun_stderr_encoding != NULL) {
+        PUTPROP(props, "sun.stderr.encoding", sprops->sun_stderr_encoding);
+    }
     PUTPROP(props, "file.encoding.pkg", "sun.io");
+
     /* unicode_encoding specifies the default endianness */
     PUTPROP(props, "sun.io.unicode.encoding", sprops->unicode_encoding);
     PUTPROP(props, "sun.cpu.isalist",
--- a/jdk/src/share/native/java/lang/java_props.h	Thu Feb 16 11:43:20 2012 -0800
+++ b/jdk/src/share/native/java/lang/java_props.h	Thu Feb 16 22:13:10 2012 -0800
@@ -66,6 +66,8 @@
     char *display_variant;
     char *encoding;
     char *sun_jnu_encoding;
+    char *sun_stdout_encoding;
+    char *sun_stderr_encoding;
     char *timezone;
 
     char *printerJob;
--- a/jdk/src/windows/native/java/lang/java_props_md.c	Thu Feb 16 11:43:20 2012 -0800
+++ b/jdk/src/windows/native/java/lang/java_props_md.c	Thu Feb 16 22:13:10 2012 -0800
@@ -31,6 +31,9 @@
 #include <sys/timeb.h>
 #include <tchar.h>
 
+#include <stdlib.h>
+#include <Wincon.h>
+
 #include "locale_str.h"
 #include "java_props.h"
 
@@ -123,6 +126,17 @@
     return ret;
 }
 
+static char* getConsoleEncoding()
+{
+    char* buf = malloc(16);
+    int cp = GetConsoleCP();
+    if (cp >= 874 && cp <= 950)
+        sprintf(buf, "ms%d", cp);
+    else
+        sprintf(buf, "cp%d", cp);
+    return buf;
+}
+
 // Exported entries for AWT
 DllExport const char *
 getEncodingFromLangID(LANGID langID)
@@ -562,6 +576,7 @@
 
         {
             char * display_encoding;
+            HANDLE hStdOutErr;
 
             // Windows UI Language selection list only cares "language"
             // information of the UI Language. For example, the list
@@ -606,6 +621,20 @@
                 sprops.encoding = "MS950_HKSCS";
                 sprops.sun_jnu_encoding = "MS950_HKSCS";
             }
+
+            hStdOutErr = GetStdHandle(STD_OUTPUT_HANDLE);
+            if (hStdOutErr != INVALID_HANDLE_VALUE &&
+                GetFileType(hStdOutErr) == FILE_TYPE_CHAR) {
+                sprops.sun_stdout_encoding = getConsoleEncoding();
+            }
+            hStdOutErr = GetStdHandle(STD_ERROR_HANDLE);
+            if (hStdOutErr != INVALID_HANDLE_VALUE &&
+                GetFileType(hStdOutErr) == FILE_TYPE_CHAR) {
+                if (sprops.sun_stdout_encoding != NULL)
+                    sprops.sun_stderr_encoding = sprops.sun_stdout_encoding;
+                else
+                    sprops.sun_stderr_encoding = getConsoleEncoding();
+            }
         }
     }