PostgreSQL Source Code  git master
sprompt.c File Reference
#include "c.h"
#include "common/fe_memutils.h"
#include "common/string.h"
Include dependency graph for sprompt.c:

Go to the source code of this file.

Functions

char * simple_prompt (const char *prompt, bool echo)
 

Function Documentation

◆ simple_prompt()

char* simple_prompt ( const char *  prompt,
bool  echo 
)

Definition at line 38 of file sprompt.c.

References _, pg_get_line(), pg_strdup(), and pg_strip_crlf().

Referenced by connectDatabase(), ConnectDatabase(), doConnect(), exec_command_password(), exec_command_prompt(), get_su_pwd(), GetConnection(), main(), prompt_for_password(), sql_conn(), vacuumlo(), and yesno_prompt().

39 {
40  char *result;
41  FILE *termin,
42  *termout;
43 #if defined(HAVE_TERMIOS_H)
44  struct termios t_orig,
45  t;
46 #elif defined(WIN32)
47  HANDLE t = NULL;
48  DWORD t_orig = 0;
49 #endif
50 
51 #ifdef WIN32
52 
53  /*
54  * A Windows console has an "input code page" and an "output code page";
55  * these usually match each other, but they rarely match the "Windows ANSI
56  * code page" defined at system boot and expected of "char *" arguments to
57  * Windows API functions. The Microsoft CRT write() implementation
58  * automatically converts text between these code pages when writing to a
59  * console. To identify such file descriptors, it calls GetConsoleMode()
60  * on the underlying HANDLE, which in turn requires GENERIC_READ access on
61  * the HANDLE. Opening termout in mode "w+" allows that detection to
62  * succeed. Otherwise, write() would not recognize the descriptor as a
63  * console, and non-ASCII characters would display incorrectly.
64  *
65  * XXX fgets() still receives text in the console's input code page. This
66  * makes non-ASCII credentials unportable.
67  *
68  * Unintuitively, we also open termin in mode "w+", even though we only
69  * read it; that's needed for SetConsoleMode() to succeed.
70  */
71  termin = fopen("CONIN$", "w+");
72  termout = fopen("CONOUT$", "w+");
73 #else
74 
75  /*
76  * Do not try to collapse these into one "w+" mode file. Doesn't work on
77  * some platforms (eg, HPUX 10.20).
78  */
79  termin = fopen("/dev/tty", "r");
80  termout = fopen("/dev/tty", "w");
81 #endif
82  if (!termin || !termout
83 #ifdef WIN32
84 
85  /*
86  * Direct console I/O does not work from the MSYS 1.0.10 console. Writes
87  * reach nowhere user-visible; reads block indefinitely. XXX This affects
88  * most Windows terminal environments, including rxvt, mintty, Cygwin
89  * xterm, Cygwin sshd, and PowerShell ISE. Switch to a more-generic test.
90  */
91  || (getenv("OSTYPE") && strcmp(getenv("OSTYPE"), "msys") == 0)
92 #endif
93  )
94  {
95  if (termin)
96  fclose(termin);
97  if (termout)
98  fclose(termout);
99  termin = stdin;
100  termout = stderr;
101  }
102 
103  if (!echo)
104  {
105 #if defined(HAVE_TERMIOS_H)
106  /* disable echo via tcgetattr/tcsetattr */
107  tcgetattr(fileno(termin), &t);
108  t_orig = t;
109  t.c_lflag &= ~ECHO;
110  tcsetattr(fileno(termin), TCSAFLUSH, &t);
111 #elif defined(WIN32)
112  /* need the file's HANDLE to turn echo off */
113  t = (HANDLE) _get_osfhandle(_fileno(termin));
114 
115  /* save the old configuration first */
116  GetConsoleMode(t, &t_orig);
117 
118  /* set to the new mode */
119  SetConsoleMode(t, ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT);
120 #endif
121  }
122 
123  if (prompt)
124  {
125  fputs(_(prompt), termout);
126  fflush(termout);
127  }
128 
129  result = pg_get_line(termin);
130 
131  /* If we failed to read anything, just return an empty string */
132  if (result == NULL)
133  result = pg_strdup("");
134 
135  /* strip trailing newline, including \r in case we're on Windows */
136  (void) pg_strip_crlf(result);
137 
138  if (!echo)
139  {
140  /* restore previous echo behavior, then echo \n */
141 #if defined(HAVE_TERMIOS_H)
142  tcsetattr(fileno(termin), TCSAFLUSH, &t_orig);
143  fputs("\n", termout);
144  fflush(termout);
145 #elif defined(WIN32)
146  SetConsoleMode(t, t_orig);
147  fputs("\n", termout);
148  fflush(termout);
149 #endif
150  }
151 
152  if (termin != stdin)
153  {
154  fclose(termin);
155  fclose(termout);
156  }
157 
158  return result;
159 }
int pg_strip_crlf(char *str)
Definition: string.c:105
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
char * pg_get_line(FILE *stream)
Definition: pg_get_line.c:52
#define _(x)
Definition: elog.c:88