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

Go to the source code of this file.

Functions

void simple_prompt (const char *prompt, char *destination, size_t destlen, bool echo)
 

Function Documentation

◆ simple_prompt()

void simple_prompt ( const char *  prompt,
char *  destination,
size_t  destlen,
bool  echo 
)

Definition at line 37 of file sprompt.c.

References _, buf, and length().

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

38 {
39  int length;
40  FILE *termin,
41  *termout;
42 
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  if (fgets(destination, destlen, termin) == NULL)
130  destination[0] = '\0';
131 
132  length = strlen(destination);
133  if (length > 0 && destination[length - 1] != '\n')
134  {
135  /* eat rest of the line */
136  char buf[128];
137  int buflen;
138 
139  do
140  {
141  if (fgets(buf, sizeof(buf), termin) == NULL)
142  break;
143  buflen = strlen(buf);
144  } while (buflen > 0 && buf[buflen - 1] != '\n');
145  }
146 
147  if (length > 0 && destination[length - 1] == '\n')
148  /* remove trailing newline */
149  destination[length - 1] = '\0';
150 
151  if (!echo)
152  {
153  /* restore previous echo behavior, then echo \n */
154 #if defined(HAVE_TERMIOS_H)
155  tcsetattr(fileno(termin), TCSAFLUSH, &t_orig);
156  fputs("\n", termout);
157  fflush(termout);
158 #elif defined(WIN32)
159  SetConsoleMode(t, t_orig);
160  fputs("\n", termout);
161  fflush(termout);
162 #endif
163  }
164 
165  if (termin != stdin)
166  {
167  fclose(termin);
168  fclose(termout);
169  }
170 }
int length(const List *list)
Definition: list.c:1333
static char * buf
Definition: pg_test_fsync.c:67
#define _(x)
Definition: elog.c:84