aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Dunstan <andrew@dunslane.net>2013-01-24 16:01:31 -0500
committerAndrew Dunstan <andrew@dunslane.net>2013-01-24 16:01:31 -0500
commit57d294a18891ef843c9c24f3f9f3076fa2cfcc23 (patch)
tree417c320ea54a366d7f8222772426115afb404a88 /src
parent62b9e3a0ff2d9964e30635ceca825340e71087e1 (diff)
downloadpostgresql-57d294a18891ef843c9c24f3f9f3076fa2cfcc23.tar.gz
postgresql-57d294a18891ef843c9c24f3f9f3076fa2cfcc23.zip
Use correct output device for Windows prompts.
This ensures that mapping of non-ascii prompts to the correct code page occurs. Bug report and original patch from Alexander Law, reviewed and reworked by Noah Misch. Backpatch to all live branches.
Diffstat (limited to 'src')
-rw-r--r--src/bin/psql/command.c11
-rw-r--r--src/include/port.h3
-rw-r--r--src/port/sprompt.c33
3 files changed, 41 insertions, 6 deletions
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index a451c2b8ea1..e6e7f844327 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -1046,6 +1046,17 @@ exec_command(const char *cmd,
char *fname = psql_scan_slash_option(scan_state,
OT_NORMAL, NULL, true);
+#if defined(WIN32) && !defined(__CYGWIN__)
+
+ /*
+ * XXX This does not work for all terminal environments or for output
+ * containing non-ASCII characters; see comments in simple_prompt().
+ */
+#define DEVTTY "con"
+#else
+#define DEVTTY "/dev/tty"
+#endif
+
expand_tilde(&fname);
/* This scrolls off the screen when using /dev/tty */
success = saveHistory(fname ? fname : DEVTTY, -1, false, false);
diff --git a/src/include/port.h b/src/include/port.h
index 088e02e7809..39d37c9a8c5 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -109,11 +109,8 @@ extern BOOL AddUserToTokenDacl(HANDLE hToken);
#if defined(WIN32) && !defined(__CYGWIN__)
#define DEVNULL "nul"
-/* "con" does not work from the Msys 1.0.10 console (part of MinGW). */
-#define DEVTTY "con"
#else
#define DEVNULL "/dev/null"
-#define DEVTTY "/dev/tty"
#endif
/*
diff --git a/src/port/sprompt.c b/src/port/sprompt.c
index c917f91e007..65414614601 100644
--- a/src/port/sprompt.c
+++ b/src/port/sprompt.c
@@ -56,15 +56,42 @@ simple_prompt(const char *prompt, int maxlen, bool echo)
if (!destination)
return NULL;
+#ifdef WIN32
+
+ /*
+ * A Windows console has an "input code page" and an "output code page";
+ * these usually match each other, but they rarely match the "Windows ANSI
+ * code page" defined at system boot and expected of "char *" arguments to
+ * Windows API functions. The Microsoft CRT write() implementation
+ * automatically converts text between these code pages when writing to a
+ * console. To identify such file descriptors, it calls GetConsoleMode()
+ * on the underlying HANDLE, which in turn requires GENERIC_READ access on
+ * the HANDLE. Opening termout in mode "w+" allows that detection to
+ * succeed. Otherwise, write() would not recognize the descriptor as a
+ * console, and non-ASCII characters would display incorrectly.
+ *
+ * XXX fgets() still receives text in the console's input code page. This
+ * makes non-ASCII credentials unportable.
+ */
+ termin = fopen("CONIN$", "r");
+ termout = fopen("CONOUT$", "w+");
+#else
+
/*
* Do not try to collapse these into one "w+" mode file. Doesn't work on
* some platforms (eg, HPUX 10.20).
*/
- termin = fopen(DEVTTY, "r");
- termout = fopen(DEVTTY, "w");
+ termin = fopen("/dev/tty", "r");
+ termout = fopen("/dev/tty", "w");
+#endif
if (!termin || !termout
#ifdef WIN32
- /* See DEVTTY comment for msys */
+ /*
+ * Direct console I/O does not work from the MSYS 1.0.10 console. Writes
+ * reach nowhere user-visible; reads block indefinitely. XXX This affects
+ * most Windows terminal environments, including rxvt, mintty, Cygwin
+ * xterm, Cygwin sshd, and PowerShell ISE. Switch to a more-generic test.
+ */
|| (getenv("OSTYPE") && strcmp(getenv("OSTYPE"), "msys") == 0)
#endif
)