Skip to content

Commit 57d294a

Browse files
committed
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.
1 parent 62b9e3a commit 57d294a

File tree

3 files changed

+41
-6
lines changed

3 files changed

+41
-6
lines changed

src/bin/psql/command.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,6 +1046,17 @@ exec_command(const char *cmd,
10461046
char *fname = psql_scan_slash_option(scan_state,
10471047
OT_NORMAL, NULL, true);
10481048

1049+
#if defined(WIN32) && !defined(__CYGWIN__)
1050+
1051+
/*
1052+
* XXX This does not work for all terminal environments or for output
1053+
* containing non-ASCII characters; see comments in simple_prompt().
1054+
*/
1055+
#define DEVTTY "con"
1056+
#else
1057+
#define DEVTTY "/dev/tty"
1058+
#endif
1059+
10491060
expand_tilde(&fname);
10501061
/* This scrolls off the screen when using /dev/tty */
10511062
success = saveHistory(fname ? fname : DEVTTY, -1, false, false);

src/include/port.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,11 +109,8 @@ extern BOOL AddUserToTokenDacl(HANDLE hToken);
109109

110110
#if defined(WIN32) && !defined(__CYGWIN__)
111111
#define DEVNULL "nul"
112-
/* "con" does not work from the Msys 1.0.10 console (part of MinGW). */
113-
#define DEVTTY "con"
114112
#else
115113
#define DEVNULL "/dev/null"
116-
#define DEVTTY "/dev/tty"
117114
#endif
118115

119116
/*

src/port/sprompt.c

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,42 @@ simple_prompt(const char *prompt, int maxlen, bool echo)
5656
if (!destination)
5757
return NULL;
5858

59+
#ifdef WIN32
60+
61+
/*
62+
* A Windows console has an "input code page" and an "output code page";
63+
* these usually match each other, but they rarely match the "Windows ANSI
64+
* code page" defined at system boot and expected of "char *" arguments to
65+
* Windows API functions. The Microsoft CRT write() implementation
66+
* automatically converts text between these code pages when writing to a
67+
* console. To identify such file descriptors, it calls GetConsoleMode()
68+
* on the underlying HANDLE, which in turn requires GENERIC_READ access on
69+
* the HANDLE. Opening termout in mode "w+" allows that detection to
70+
* succeed. Otherwise, write() would not recognize the descriptor as a
71+
* console, and non-ASCII characters would display incorrectly.
72+
*
73+
* XXX fgets() still receives text in the console's input code page. This
74+
* makes non-ASCII credentials unportable.
75+
*/
76+
termin = fopen("CONIN$", "r");
77+
termout = fopen("CONOUT$", "w+");
78+
#else
79+
5980
/*
6081
* Do not try to collapse these into one "w+" mode file. Doesn't work on
6182
* some platforms (eg, HPUX 10.20).
6283
*/
63-
termin = fopen(DEVTTY, "r");
64-
termout = fopen(DEVTTY, "w");
84+
termin = fopen("/dev/tty", "r");
85+
termout = fopen("/dev/tty", "w");
86+
#endif
6587
if (!termin || !termout
6688
#ifdef WIN32
67-
/* See DEVTTY comment for msys */
89+
/*
90+
* Direct console I/O does not work from the MSYS 1.0.10 console. Writes
91+
* reach nowhere user-visible; reads block indefinitely. XXX This affects
92+
* most Windows terminal environments, including rxvt, mintty, Cygwin
93+
* xterm, Cygwin sshd, and PowerShell ISE. Switch to a more-generic test.
94+
*/
6895
|| (getenv("OSTYPE") && strcmp(getenv("OSTYPE"), "msys") == 0)
6996
#endif
7097
)

0 commit comments

Comments
 (0)