Re: BUG #6510: A simple prompt is displayed using wrong charset

From: Noah Misch <noah(at)leadboat(dot)com>
To: Alexander LAW <exclusion(at)gmail(dot)com>
Cc: Alvaro Herrera <alvherre(at)commandprompt(dot)com>, Pg Bugs <pgsql-bugs(at)postgresql(dot)org>
Subject: Re: BUG #6510: A simple prompt is displayed using wrong charset
Date: 2012-10-10 11:05:55
Message-ID: 20121010110555.GA21405@tornado.leadboat.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs pgsql-general pgsql-hackers

Hi Alexander,

I was able to reproduce the problem based on your description and test case,
and your change does resolve it for me.

On Tue, Mar 20, 2012 at 11:50:14PM +0400, Alexander LAW wrote:
> Thanks, I've understood your point.
> Please look at the patch. It implements the first way and it makes psql
> work too.

> 20.03.2012 00:05, Alvaro Herrera ??????????:
>> Excerpts from Alexander LAW's message of dom mar 18 06:04:51 -0300 2012:
>>> I see two ways to resolve the issue.
>>> First is to use CharToOemBuff when writing a string to the "con" and
>>> OemToCharBuff when reading an input from it.
>>> The other is to always use stderr/stdin for Win32 as it was done for
>>> msys before. I think it's more straightforward.
>> Using console directly instead of stdin/out/err is more appropriate when
>> asking for passwords and reading them back, because you can redirect the
>> rest of the output to/from files or pipes, without the prompt
>> interfering with that. This also explains why stderr is used instead of
>> stdout.

The console output code page will usually match the OEM code page, but this is
not guaranteed. For example, one can change it with chcp.exe before starting
psql. The conversion should be to the actual console output code page. After
"chcp 869", notice how printing to stdout yields question marks while your
code yields unrelated characters.

It would be nicer still to find a way to make the output routines treat this
explicitly-opened console like stdout to a console. I could not find any
documentation around this. Digging into the CRT source code, I see that the
automatic code page conversion happens in write(). One of tests write() uses
to determine whether the destination is a console is to call GetConsoleMode()
on the HANDLE underlying the CRT file descriptor. If that call fails, write()
assumes the target is not a console. GetConsoleMode() requires GENERIC_READ
access on its subject HANDLE, but the HANDLE resulting from our fopen("con",
"w") has only GENERIC_WRITE. Therefore, write() wrongly concludes that it's
writing to a non-console. fopen("con", "w+") fails, but fopen("CONOUT$",
"w+") seems to give the outcome we need. write() recognizes that it's writing
to a console and applies the code page conversion. Let's use that.

This gave me occasion to look at the special case for MSYS that you mentioned.
I observe the same behavior when running a native psql in a Cygwin xterm;
writes to the console succeed but do not appear anywhere. Instead of guessing
at console visibility based on an environment variable witnessing a particular
platform, let's check IsWindowVisible(GetConsoleWindow()).

What do you think of taking that approach?

Thanks,
nm

In response to

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message Heikki Linnakangas 2012-10-10 15:44:34 Re: BUG #7534: walreceiver takes long time to detect n/w breakdown
Previous Message Piotr Czachur 2012-10-10 10:17:16 Re: BUG #7557: Transaction sees outdated grants.

Browse pgsql-general by date

  From Date Subject
Next Message Lars Helge Øverland 2012-10-10 12:03:57 Index only scan
Previous Message Albe Laurenz 2012-10-10 10:31:27 Re: libpq-how to add a schema to search path

Browse pgsql-hackers by date

  From Date Subject
Next Message Peter Geoghegan 2012-10-10 11:34:07 Re: Hash id in pg_stat_statements
Previous Message Peter Geoghegan 2012-10-10 10:54:54 Re: Hash id in pg_stat_statements