LCOV - code coverage report
Current view: top level - src/port - sprompt.c (source / functions) Hit Total Coverage
Test: PostgreSQL Lines: 0 36 0.0 %
Date: 2017-09-29 13:40:31 Functions: 0 1 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * sprompt.c
       4             :  *    simple_prompt() routine
       5             :  *
       6             :  * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
       7             :  * Portions Copyright (c) 1994, Regents of the University of California
       8             :  *
       9             :  *
      10             :  * IDENTIFICATION
      11             :  *    src/port/sprompt.c
      12             :  *
      13             :  *-------------------------------------------------------------------------
      14             :  */
      15             : #include "c.h"
      16             : 
      17             : #ifdef HAVE_TERMIOS_H
      18             : #include <termios.h>
      19             : #endif
      20             : 
      21             : 
      22             : /*
      23             :  * simple_prompt
      24             :  *
      25             :  * Generalized function especially intended for reading in usernames and
      26             :  * passwords interactively.  Reads from /dev/tty or stdin/stderr.
      27             :  *
      28             :  * prompt:      The prompt to print, or NULL if none (automatically localized)
      29             :  * destination: buffer in which to store result
      30             :  * destlen:     allocated length of destination
      31             :  * echo:        Set to false if you want to hide what is entered (for passwords)
      32             :  *
      33             :  * The input (without trailing newline) is returned in the destination buffer,
      34             :  * with a '\0' appended.
      35             :  */
      36             : void
      37           0 : simple_prompt(const char *prompt, char *destination, size_t destlen, bool echo)
      38             : {
      39             :     int         length;
      40             :     FILE       *termin,
      41             :                *termout;
      42             : 
      43             : #ifdef HAVE_TERMIOS_H
      44             :     struct termios t_orig,
      45             :                 t;
      46             : #else
      47             : #ifdef WIN32
      48             :     HANDLE      t = NULL;
      49             :     DWORD       t_orig = 0;
      50             : #endif
      51             : #endif
      52             : 
      53             : #ifdef WIN32
      54             : 
      55             :     /*
      56             :      * A Windows console has an "input code page" and an "output code page";
      57             :      * these usually match each other, but they rarely match the "Windows ANSI
      58             :      * code page" defined at system boot and expected of "char *" arguments to
      59             :      * Windows API functions.  The Microsoft CRT write() implementation
      60             :      * automatically converts text between these code pages when writing to a
      61             :      * console.  To identify such file descriptors, it calls GetConsoleMode()
      62             :      * on the underlying HANDLE, which in turn requires GENERIC_READ access on
      63             :      * the HANDLE.  Opening termout in mode "w+" allows that detection to
      64             :      * succeed.  Otherwise, write() would not recognize the descriptor as a
      65             :      * console, and non-ASCII characters would display incorrectly.
      66             :      *
      67             :      * XXX fgets() still receives text in the console's input code page.  This
      68             :      * makes non-ASCII credentials unportable.
      69             :      */
      70             :     termin = fopen("CONIN$", "r");
      71             :     termout = fopen("CONOUT$", "w+");
      72             : #else
      73             : 
      74             :     /*
      75             :      * Do not try to collapse these into one "w+" mode file. Doesn't work on
      76             :      * some platforms (eg, HPUX 10.20).
      77             :      */
      78           0 :     termin = fopen("/dev/tty", "r");
      79           0 :     termout = fopen("/dev/tty", "w");
      80             : #endif
      81           0 :     if (!termin || !termout
      82             : #ifdef WIN32
      83             : 
      84             :     /*
      85             :      * Direct console I/O does not work from the MSYS 1.0.10 console.  Writes
      86             :      * reach nowhere user-visible; reads block indefinitely.  XXX This affects
      87             :      * most Windows terminal environments, including rxvt, mintty, Cygwin
      88             :      * xterm, Cygwin sshd, and PowerShell ISE.  Switch to a more-generic test.
      89             :      */
      90             :         || (getenv("OSTYPE") && strcmp(getenv("OSTYPE"), "msys") == 0)
      91             : #endif
      92             :         )
      93             :     {
      94           0 :         if (termin)
      95           0 :             fclose(termin);
      96           0 :         if (termout)
      97           0 :             fclose(termout);
      98           0 :         termin = stdin;
      99           0 :         termout = stderr;
     100             :     }
     101             : 
     102             : #ifdef HAVE_TERMIOS_H
     103           0 :     if (!echo)
     104             :     {
     105           0 :         tcgetattr(fileno(termin), &t);
     106           0 :         t_orig = t;
     107           0 :         t.c_lflag &= ~ECHO;
     108           0 :         tcsetattr(fileno(termin), TCSAFLUSH, &t);
     109             :     }
     110             : #else
     111             : #ifdef WIN32
     112             :     if (!echo)
     113             :     {
     114             :         /* get a new handle to turn echo off */
     115             :         t = GetStdHandle(STD_INPUT_HANDLE);
     116             : 
     117             :         /* save the old configuration first */
     118             :         GetConsoleMode(t, &t_orig);
     119             : 
     120             :         /* set to the new mode */
     121             :         SetConsoleMode(t, ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT);
     122             :     }
     123             : #endif
     124             : #endif
     125             : 
     126           0 :     if (prompt)
     127             :     {
     128           0 :         fputs(_(prompt), termout);
     129           0 :         fflush(termout);
     130             :     }
     131             : 
     132           0 :     if (fgets(destination, destlen, termin) == NULL)
     133           0 :         destination[0] = '\0';
     134             : 
     135           0 :     length = strlen(destination);
     136           0 :     if (length > 0 && destination[length - 1] != '\n')
     137             :     {
     138             :         /* eat rest of the line */
     139             :         char        buf[128];
     140             :         int         buflen;
     141             : 
     142             :         do
     143             :         {
     144           0 :             if (fgets(buf, sizeof(buf), termin) == NULL)
     145           0 :                 break;
     146           0 :             buflen = strlen(buf);
     147           0 :         } while (buflen > 0 && buf[buflen - 1] != '\n');
     148             :     }
     149             : 
     150           0 :     if (length > 0 && destination[length - 1] == '\n')
     151             :         /* remove trailing newline */
     152           0 :         destination[length - 1] = '\0';
     153             : 
     154             : #ifdef HAVE_TERMIOS_H
     155           0 :     if (!echo)
     156             :     {
     157           0 :         tcsetattr(fileno(termin), TCSAFLUSH, &t_orig);
     158           0 :         fputs("\n", termout);
     159           0 :         fflush(termout);
     160             :     }
     161             : #else
     162             : #ifdef WIN32
     163             :     if (!echo)
     164             :     {
     165             :         /* reset to the original console mode */
     166             :         SetConsoleMode(t, t_orig);
     167             :         fputs("\n", termout);
     168             :         fflush(termout);
     169             :     }
     170             : #endif
     171             : #endif
     172             : 
     173           0 :     if (termin != stdin)
     174             :     {
     175           0 :         fclose(termin);
     176           0 :         fclose(termout);
     177             :     }
     178           0 : }

Generated by: LCOV version 1.11