Fix obsolete comment regarding FSM truncation.
[PostgreSQL.git] / src / port / sprompt.c
blob8bab765d24c3eed0d4b58f086c8b5c6255d44e05
1 /*-------------------------------------------------------------------------
3 * sprompt.c
4 * simple_prompt() routine
6 * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
10 * IDENTIFICATION
11 * $PostgreSQL$
13 *-------------------------------------------------------------------------
18 * simple_prompt
20 * Generalized function especially intended for reading in usernames and
21 * password interactively. Reads from /dev/tty or stdin/stderr.
23 * prompt: The prompt to print
24 * maxlen: How many characters to accept
25 * echo: Set to false if you want to hide what is entered (for passwords)
27 * Returns a malloc()'ed string with the input (w/o trailing newline).
29 #include "c.h"
31 #ifdef HAVE_TERMIOS_H
32 #include <termios.h>
33 #endif
35 extern char *simple_prompt(const char *prompt, int maxlen, bool echo);
37 char *
38 simple_prompt(const char *prompt, int maxlen, bool echo)
40 int length;
41 char *destination;
42 FILE *termin,
43 *termout;
45 #ifdef HAVE_TERMIOS_H
46 struct termios t_orig,
48 #else
49 #ifdef WIN32
50 HANDLE t = NULL;
51 LPDWORD t_orig = NULL;
52 #endif
53 #endif
55 destination = (char *) malloc(maxlen + 1);
56 if (!destination)
57 return NULL;
60 * Do not try to collapse these into one "w+" mode file. Doesn't work on
61 * some platforms (eg, HPUX 10.20).
63 termin = fopen(DEVTTY, "r");
64 termout = fopen(DEVTTY, "w");
65 if (!termin || !termout
66 #ifdef WIN32
67 /* See DEVTTY comment for msys */
68 || (getenv("OSTYPE") && strcmp(getenv("OSTYPE"), "msys") == 0)
69 #endif
72 if (termin)
73 fclose(termin);
74 if (termout)
75 fclose(termout);
76 termin = stdin;
77 termout = stderr;
80 #ifdef HAVE_TERMIOS_H
81 if (!echo)
83 tcgetattr(fileno(termin), &t);
84 t_orig = t;
85 t.c_lflag &= ~ECHO;
86 tcsetattr(fileno(termin), TCSAFLUSH, &t);
88 #else
89 #ifdef WIN32
90 if (!echo)
92 /* get a new handle to turn echo off */
93 t_orig = (LPDWORD) malloc(sizeof(DWORD));
94 t = GetStdHandle(STD_INPUT_HANDLE);
96 /* save the old configuration first */
97 GetConsoleMode(t, t_orig);
99 /* set to the new mode */
100 SetConsoleMode(t, ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT);
102 #endif
103 #endif
105 if (prompt)
107 fputs(_(prompt), termout);
108 fflush(termout);
111 if (fgets(destination, maxlen + 1, termin) == NULL)
112 destination[0] = '\0';
114 length = strlen(destination);
115 if (length > 0 && destination[length - 1] != '\n')
117 /* eat rest of the line */
118 char buf[128];
119 int buflen;
123 if (fgets(buf, sizeof(buf), termin) == NULL)
124 break;
125 buflen = strlen(buf);
126 } while (buflen > 0 && buf[buflen - 1] != '\n');
129 if (length > 0 && destination[length - 1] == '\n')
130 /* remove trailing newline */
131 destination[length - 1] = '\0';
133 #ifdef HAVE_TERMIOS_H
134 if (!echo)
136 tcsetattr(fileno(termin), TCSAFLUSH, &t_orig);
137 fputs("\n", termout);
138 fflush(termout);
140 #else
141 #ifdef WIN32
142 if (!echo)
144 /* reset to the original console mode */
145 SetConsoleMode(t, *t_orig);
146 fputs("\n", termout);
147 fflush(termout);
148 free(t_orig);
150 #endif
151 #endif
153 if (termin != stdin)
155 fclose(termin);
156 fclose(termout);
159 return destination;