Commit 1068771a authored by Andrew Dunstan's avatar Andrew Dunstan

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.
parent a9ceaa53
...@@ -1043,6 +1043,17 @@ exec_command(const char *cmd, ...@@ -1043,6 +1043,17 @@ exec_command(const char *cmd,
char *fname = psql_scan_slash_option(scan_state, char *fname = psql_scan_slash_option(scan_state,
OT_NORMAL, NULL, true); 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); expand_tilde(&fname);
/* This scrolls off the screen when using /dev/tty */ /* This scrolls off the screen when using /dev/tty */
success = saveHistory(fname ? fname : DEVTTY, -1, false, false); success = saveHistory(fname ? fname : DEVTTY, -1, false, false);
......
...@@ -110,11 +110,8 @@ extern BOOL AddUserToTokenDacl(HANDLE hToken); ...@@ -110,11 +110,8 @@ extern BOOL AddUserToTokenDacl(HANDLE hToken);
#if defined(WIN32) && !defined(__CYGWIN__) #if defined(WIN32) && !defined(__CYGWIN__)
#define DEVNULL "nul" #define DEVNULL "nul"
/* "con" does not work from the Msys 1.0.10 console (part of MinGW). */
#define DEVTTY "con"
#else #else
#define DEVNULL "/dev/null" #define DEVNULL "/dev/null"
#define DEVTTY "/dev/tty"
#endif #endif
/* /*
......
...@@ -56,15 +56,42 @@ simple_prompt(const char *prompt, int maxlen, bool echo) ...@@ -56,15 +56,42 @@ simple_prompt(const char *prompt, int maxlen, bool echo)
if (!destination) if (!destination)
return NULL; 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 * Do not try to collapse these into one "w+" mode file. Doesn't work on
* some platforms (eg, HPUX 10.20). * some platforms (eg, HPUX 10.20).
*/ */
termin = fopen(DEVTTY, "r"); termin = fopen("/dev/tty", "r");
termout = fopen(DEVTTY, "w"); termout = fopen("/dev/tty", "w");
#endif
if (!termin || !termout if (!termin || !termout
#ifdef WIN32 #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) || (getenv("OSTYPE") && strcmp(getenv("OSTYPE"), "msys") == 0)
#endif #endif
) )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment