LCOV - differential code coverage report
Current view: top level - src/common - sprompt.c (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage HEAD vs 15 Lines: 65.7 % 35 23 12 23
Current Date: 2023-04-08 17:13:01 Functions: 50.0 % 2 1 1 1
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (240..) days: 65.7 % 35 23 12 23
Legend: Lines: hit not hit Function coverage date bins:
(240..) days: 50.0 % 2 1 1 1

 Age         Owner                  TLA  Line data    Source code
                                  1                 : /*-------------------------------------------------------------------------
                                  2                 :  *
                                  3                 :  * sprompt.c
                                  4                 :  *    simple_prompt() routine
                                  5                 :  *
                                  6                 :  * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
                                  7                 :  * Portions Copyright (c) 1994, Regents of the University of California
                                  8                 :  *
                                  9                 :  *
                                 10                 :  * IDENTIFICATION
                                 11                 :  *    src/common/sprompt.c
                                 12                 :  *
                                 13                 :  *-------------------------------------------------------------------------
                                 14                 :  */
                                 15                 : #include "c.h"
                                 16                 : 
                                 17                 : #include "common/fe_memutils.h"
                                 18                 : #include "common/string.h"
                                 19                 : 
                                 20                 : #ifdef HAVE_TERMIOS_H
                                 21                 : #include <termios.h>
                                 22                 : #endif
                                 23                 : 
                                 24                 : 
                                 25                 : /*
                                 26                 :  * simple_prompt
                                 27                 :  *
                                 28                 :  * Generalized function especially intended for reading in usernames and
                                 29                 :  * passwords interactively.  Reads from /dev/tty or stdin/stderr.
                                 30                 :  *
                                 31                 :  * prompt:      The prompt to print, or NULL if none (automatically localized)
                                 32                 :  * echo:        Set to false if you want to hide what is entered (for passwords)
                                 33                 :  *
                                 34                 :  * The input (without trailing newline) is returned as a malloc'd string.
                                 35                 :  * Caller is responsible for freeing it when done.
                                 36                 :  */
                                 37                 : char *
  948 tgl                        38 UBC           0 : simple_prompt(const char *prompt, bool echo)
                                 39                 : {
  508                            40               0 :     return simple_prompt_extended(prompt, echo, NULL);
                                 41                 : }
                                 42                 : 
                                 43                 : /*
                                 44                 :  * simple_prompt_extended
                                 45                 :  *
                                 46                 :  * This is the same as simple_prompt(), except that prompt_ctx can
                                 47                 :  * optionally be provided to allow this function to be canceled via an
                                 48                 :  * existing SIGINT signal handler that will longjmp to the specified place
                                 49                 :  * only when *(prompt_ctx->enabled) is true.  If canceled, this function
                                 50                 :  * returns an empty string, and prompt_ctx->canceled is set to true.
                                 51                 :  */
                                 52                 : char *
  508 tgl                        53 CBC           2 : simple_prompt_extended(const char *prompt, bool echo,
                                 54                 :                        PromptInterruptContext *prompt_ctx)
                                 55                 : {
                                 56                 :     char       *result;
                                 57                 :     FILE       *termin,
                                 58                 :                *termout;
                                 59                 : #if defined(HAVE_TERMIOS_H)
                                 60                 :     struct termios t_orig,
                                 61                 :                 t;
                                 62                 : #elif defined(WIN32)
                                 63                 :     HANDLE      t = NULL;
                                 64                 :     DWORD       t_orig = 0;
                                 65                 : #endif
                                 66                 : 
                                 67                 : #ifdef WIN32
                                 68                 : 
                                 69                 :     /*
                                 70                 :      * A Windows console has an "input code page" and an "output code page";
                                 71                 :      * these usually match each other, but they rarely match the "Windows ANSI
                                 72                 :      * code page" defined at system boot and expected of "char *" arguments to
                                 73                 :      * Windows API functions.  The Microsoft CRT write() implementation
                                 74                 :      * automatically converts text between these code pages when writing to a
                                 75                 :      * console.  To identify such file descriptors, it calls GetConsoleMode()
                                 76                 :      * on the underlying HANDLE, which in turn requires GENERIC_READ access on
                                 77                 :      * the HANDLE.  Opening termout in mode "w+" allows that detection to
                                 78                 :      * succeed.  Otherwise, write() would not recognize the descriptor as a
                                 79                 :      * console, and non-ASCII characters would display incorrectly.
                                 80                 :      *
                                 81                 :      * XXX fgets() still receives text in the console's input code page.  This
                                 82                 :      * makes non-ASCII credentials unportable.
                                 83                 :      *
                                 84                 :      * Unintuitively, we also open termin in mode "w+", even though we only
                                 85                 :      * read it; that's needed for SetConsoleMode() to succeed.
                                 86                 :      */
                                 87                 :     termin = fopen("CONIN$", "w+");
                                 88                 :     termout = fopen("CONOUT$", "w+");
                                 89                 : #else
                                 90                 : 
                                 91                 :     /*
                                 92                 :      * Do not try to collapse these into one "w+" mode file. Doesn't work on
                                 93                 :      * some platforms (eg, HPUX 10.20).
                                 94                 :      */
 3727 andrew                     95               2 :     termin = fopen("/dev/tty", "r");
                                 96               2 :     termout = fopen("/dev/tty", "w");
                                 97                 : #endif
 6244 bruce                      98               2 :     if (!termin || !termout
                                 99                 : #ifdef WIN32
                                100                 : 
                                101                 :     /*
                                102                 :      * Direct console I/O does not work from the MSYS 1.0.10 console.  Writes
                                103                 :      * reach nowhere user-visible; reads block indefinitely.  XXX This affects
                                104                 :      * most Windows terminal environments, including rxvt, mintty, Cygwin
                                105                 :      * xterm, Cygwin sshd, and PowerShell ISE.  Switch to a more-generic test.
                                106                 :      */
                                107                 :         || (getenv("OSTYPE") && strcmp(getenv("OSTYPE"), "msys") == 0)
                                108                 : #endif
                                109                 :         )
                                110                 :     {
 7582 bruce                     111 UBC           0 :         if (termin)
                                112               0 :             fclose(termin);
                                113               0 :         if (termout)
                                114               0 :             fclose(termout);
                                115               0 :         termin = stdin;
                                116               0 :         termout = stderr;
                                117                 :     }
                                118                 : 
 7582 bruce                     119 CBC           2 :     if (!echo)
                                120                 :     {
                                121                 : #if defined(HAVE_TERMIOS_H)
                                122                 :         /* disable echo via tcgetattr/tcsetattr */
                                123               2 :         tcgetattr(fileno(termin), &t);
                                124               2 :         t_orig = t;
                                125               2 :         t.c_lflag &= ~ECHO;
                                126               2 :         tcsetattr(fileno(termin), TCSAFLUSH, &t);
                                127                 : #elif defined(WIN32)
                                128                 :         /* need the file's HANDLE to turn echo off */
                                129                 :         t = (HANDLE) _get_osfhandle(_fileno(termin));
                                130                 : 
                                131                 :         /* save the old configuration first */
                                132                 :         GetConsoleMode(t, &t_orig);
                                133                 : 
                                134                 :         /* set to the new mode */
                                135                 :         SetConsoleMode(t, ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT);
                                136                 : #endif
                                137                 :     }
                                138                 : 
                                139               2 :     if (prompt)
                                140                 :     {
 6620                           141               2 :         fputs(_(prompt), termout);
 7582                           142               2 :         fflush(termout);
                                143                 :     }
                                144                 : 
  508 tgl                       145               2 :     result = pg_get_line(termin, prompt_ctx);
                                146                 : 
                                147                 :     /* If we failed to read anything, just return an empty string */
  948                           148               2 :     if (result == NULL)
  948 tgl                       149 UBC           0 :         result = pg_strdup("");
                                150                 : 
                                151                 :     /* strip trailing newline, including \r in case we're on Windows */
  948 tgl                       152 CBC           2 :     (void) pg_strip_crlf(result);
                                153                 : 
 7582 bruce                     154               2 :     if (!echo)
                                155                 :     {
                                156                 :         /* restore previous echo behavior, then echo \n */
                                157                 : #if defined(HAVE_TERMIOS_H)
                                158               2 :         tcsetattr(fileno(termin), TCSAFLUSH, &t_orig);
                                159               2 :         fputs("\n", termout);
                                160               2 :         fflush(termout);
                                161                 : #elif defined(WIN32)
                                162                 :         SetConsoleMode(t, t_orig);
                                163                 :         fputs("\n", termout);
                                164                 :         fflush(termout);
                                165                 : #endif
                                166                 :     }
  506 tgl                       167 UBC           0 :     else if (prompt_ctx && prompt_ctx->canceled)
                                168                 :     {
                                169                 :         /* also echo \n if prompt was canceled */
                                170               0 :         fputs("\n", termout);
                                171               0 :         fflush(termout);
                                172                 :     }
                                173                 : 
 7582 bruce                     174 CBC           2 :     if (termin != stdin)
                                175                 :     {
                                176               2 :         fclose(termin);
                                177               2 :         fclose(termout);
                                178                 :     }
                                179                 : 
  948 tgl                       180               2 :     return result;
                                181                 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a