]> granicus.if.org Git - postgresql/blobdiff - src/port/sprompt.c
Fix whitespace
[postgresql] / src / port / sprompt.c
index 57df748e1584c2ac0c8ead77265a77ef8e505589..c549a6f0bd87809da7dc58fbdefd6a88174e0bdd 100644 (file)
@@ -3,12 +3,12 @@
  * sprompt.c
  *       simple_prompt() routine
  *
- * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/port/sprompt.c,v 1.3 2003/11/11 23:52:45 momjian Exp $
+ *       src/port/sprompt.c
  *
  *-------------------------------------------------------------------------
  */
  *
  * Returns a malloc()'ed string with the input (w/o trailing newline).
  */
-#include "postgres.h"
+#include "c.h"
 
 #ifdef HAVE_TERMIOS_H
 #include <termios.h>
-#else
-#ifdef WIN32
-#include <windows.h>
-#undef ERROR
-#endif
 #endif
 
-bool           prompt_state = false;
 extern char *simple_prompt(const char *prompt, int maxlen, bool echo);
 
 char *
@@ -51,11 +45,10 @@ simple_prompt(const char *prompt, int maxlen, bool echo)
 #ifdef HAVE_TERMIOS_H
        struct termios t_orig,
                                t;
-
 #else
 #ifdef WIN32
-       HANDLE          t;
-       LPDWORD         t_orig;
+       HANDLE          t = NULL;
+       LPDWORD         t_orig = NULL;
 #endif
 #endif
 
@@ -63,15 +56,46 @@ simple_prompt(const char *prompt, int maxlen, bool echo)
        if (!destination)
                return NULL;
 
-       prompt_state = true;            /* disable SIGINT */
+#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).
+        * Do not try to collapse these into one "w+" mode file. Doesn't work on
+        * some platforms (eg, HPUX 10.20).
         */
        termin = fopen("/dev/tty", "r");
        termout = fopen("/dev/tty", "w");
-       if (!termin || !termout)
+#endif
+       if (!termin || !termout
+#ifdef WIN32
+
+       /*
+        * 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
+               )
        {
                if (termin)
                        fclose(termin);
@@ -108,7 +132,7 @@ simple_prompt(const char *prompt, int maxlen, bool echo)
 
        if (prompt)
        {
-               fputs(gettext(prompt), termout);
+               fputs(_(prompt), termout);
                fflush(termout);
        }
 
@@ -160,7 +184,5 @@ simple_prompt(const char *prompt, int maxlen, bool echo)
                fclose(termout);
        }
 
-       prompt_state = false;           /* SIGINT okay again */
-
        return destination;
 }