Re: psql: default base and password reading
| От | Bruce Momjian |
|---|---|
| Тема | Re: psql: default base and password reading |
| Дата | |
| Msg-id | 200110131714.f9DHEWA21586@candle.pha.pa.us обсуждение исходный текст |
| Ответ на | Re: psql: default base and password reading (Tom Lane <tgl@sss.pgh.pa.us>) |
| Список | pgsql-patches |
> Bruce Momjian <pgman@candle.pha.pa.us> writes:
> >> On second thought --- are we creating any portability problems if we
> >> assume /dev/tty exists? In particular, what about the Windows port
> >> of psql? Will it still work?
>
> > I am sure cygwin takes care of this.
>
> Please recall that we have a *native* port of psql ... cygwin doesn't
> help.
OK, I read up on how BSD/OS does this and found getpass():
The getpass() function displays a prompt to, and reads in a password
from, /dev/tty. If this file is not accessible, getpass displays the
prompt on the standard error output and reads from the standard
input.
So even it tries for /dev/tty and falls back to stdin/stderr. The
attached patch does this.
--
Bruce Momjian | http://candle.pha.pa.us
pgman@candle.pha.pa.us | (610) 853-3000
+ If your life is a hard drive, | 830 Blythe Avenue
+ Christ can be your backup. | Drexel Hill, Pennsylvania 19026
Index: src/bin/pg_dump/pg_backup_db.c
===================================================================
RCS file: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_db.c,v
retrieving revision 1.26
diff -c -r1.26 pg_backup_db.c
*** src/bin/pg_dump/pg_backup_db.c 2001/09/21 21:58:30 1.26
--- src/bin/pg_dump/pg_backup_db.c 2001/10/13 17:10:07
***************
*** 49,55 ****
* simple_prompt
*
* Generalized function especially intended for reading in usernames and
! * password interactively. Reads from stdin.
*
* prompt: The prompt to print
* maxlen: How many characters to accept
--- 49,55 ----
* simple_prompt
*
* Generalized function especially intended for reading in usernames and
! * password interactively. Reads from /dev/tty or stdin/stderr.
*
* prompt: The prompt to print
* maxlen: How many characters to accept
***************
*** 57,101 ****
*
* Returns a malloc()'ed string with the input (w/o trailing newline).
*/
char *
simple_prompt(const char *prompt, int maxlen, bool echo)
{
int length;
char *destination;
#ifdef HAVE_TERMIOS_H
struct termios t_orig,
t;
-
#endif
destination = (char *) malloc(maxlen + 2);
if (!destination)
return NULL;
if (prompt)
! fputs(gettext(prompt), stderr);
#ifdef HAVE_TERMIOS_H
if (!echo)
{
! tcgetattr(0, &t);
t_orig = t;
t.c_lflag &= ~ECHO;
! tcsetattr(0, TCSADRAIN, &t);
}
#endif
! if (fgets(destination, maxlen, stdin) == NULL)
destination[0] = '\0';
#ifdef HAVE_TERMIOS_H
if (!echo)
{
! tcsetattr(0, TCSADRAIN, &t_orig);
! fputs("\n", stderr);
}
#endif
length = strlen(destination);
if (length > 0 && destination[length - 1] != '\n')
{
--- 57,121 ----
*
* Returns a malloc()'ed string with the input (w/o trailing newline).
*/
+ static bool prompt_state;
+
char *
simple_prompt(const char *prompt, int maxlen, bool echo)
{
int length;
char *destination;
+ static FILE *termin = NULL, *termout;
#ifdef HAVE_TERMIOS_H
struct termios t_orig,
t;
#endif
destination = (char *) malloc(maxlen + 2);
if (!destination)
return NULL;
+
+ prompt_state = true;
+
+ /* initialize the streams */
+ if (!termin)
+ {
+ if ((termin = termout = fopen("/dev/tty", "w+")) == NULL)
+ {
+ termin = stdin;
+ termout = stderr;
+ }
+ }
+
if (prompt)
! {
! fputs(gettext(prompt), termout);
! rewind(termout); /* does flush too */
! }
#ifdef HAVE_TERMIOS_H
if (!echo)
{
! tcgetattr(fileno(termin), &t);
t_orig = t;
t.c_lflag &= ~ECHO;
! tcsetattr(fileno(termin), TCSADRAIN, &t);
}
#endif
! if (fgets(destination, maxlen, termin) == NULL)
destination[0] = '\0';
#ifdef HAVE_TERMIOS_H
if (!echo)
{
! tcsetattr(fileno(termin), TCSADRAIN, &t_orig);
! fputs("\n", termout);
}
#endif
+ prompt_state = false;
+
length = strlen(destination);
if (length > 0 && destination[length - 1] != '\n')
{
***************
*** 105,121 ****
do
{
! if (fgets(buf, sizeof(buf), stdin) == NULL)
break;
buflen = strlen(buf);
} while (buflen > 0 && buf[buflen - 1] != '\n');
}
if (length > 0 && destination[length - 1] == '\n')
/* remove trailing newline */
destination[length - 1] = '\0';
return destination;
}
static int
--- 125,143 ----
do
{
! if (fgets(buf, sizeof(buf), termin) == NULL)
break;
buflen = strlen(buf);
} while (buflen > 0 && buf[buflen - 1] != '\n');
}
+
if (length > 0 && destination[length - 1] == '\n')
/* remove trailing newline */
destination[length - 1] = '\0';
return destination;
}
+
static int
Index: src/bin/psql/common.c
===================================================================
RCS file: /cvsroot/pgsql/src/bin/psql/common.c,v
retrieving revision 1.34
diff -c -r1.34 common.c
*** src/bin/psql/common.c 2001/06/08 23:53:48 1.34
--- src/bin/psql/common.c 2001/10/13 17:10:11
***************
*** 161,167 ****
* simple_prompt
*
* Generalized function especially intended for reading in usernames and
! * password interactively. Reads from stdin.
*
* prompt: The prompt to print
* maxlen: How many characters to accept
--- 161,167 ----
* simple_prompt
*
* Generalized function especially intended for reading in usernames and
! * password interactively. Reads from /dev/tty or stdin/stderr.
*
* prompt: The prompt to print
* maxlen: How many characters to accept
***************
*** 176,214 ****
{
int length;
char *destination;
#ifdef HAVE_TERMIOS_H
struct termios t_orig,
t;
-
#endif
destination = (char *) malloc(maxlen + 2);
if (!destination)
return NULL;
- if (prompt)
- fputs(gettext(prompt), stderr);
prompt_state = true;
#ifdef HAVE_TERMIOS_H
if (!echo)
{
! tcgetattr(0, &t);
t_orig = t;
t.c_lflag &= ~ECHO;
! tcsetattr(0, TCSADRAIN, &t);
}
#endif
! if (fgets(destination, maxlen, stdin) == NULL)
destination[0] = '\0';
#ifdef HAVE_TERMIOS_H
if (!echo)
{
! tcsetattr(0, TCSADRAIN, &t_orig);
! fputs("\n", stderr);
}
#endif
--- 176,228 ----
{
int length;
char *destination;
+ static FILE *termin = NULL, *termout;
#ifdef HAVE_TERMIOS_H
struct termios t_orig,
t;
#endif
destination = (char *) malloc(maxlen + 2);
if (!destination)
return NULL;
prompt_state = true;
+ /* initialize the streams */
+ if (!termin)
+ {
+ if ((termin = termout = fopen("/dev/tty", "w+")) == NULL)
+ {
+ termin = stdin;
+ termout = stderr;
+ }
+ }
+
+ if (prompt)
+ {
+ fputs(gettext(prompt), termout);
+ rewind(termout); /* does flush too */
+ }
+
#ifdef HAVE_TERMIOS_H
if (!echo)
{
! tcgetattr(fileno(termin), &t);
t_orig = t;
t.c_lflag &= ~ECHO;
! tcsetattr(fileno(termin), TCSADRAIN, &t);
}
#endif
! if (fgets(destination, maxlen, termin) == NULL)
destination[0] = '\0';
#ifdef HAVE_TERMIOS_H
if (!echo)
{
! tcsetattr(fileno(termin), TCSADRAIN, &t_orig);
! fputs("\n", termout);
}
#endif
***************
*** 223,229 ****
do
{
! if (fgets(buf, sizeof(buf), stdin) == NULL)
break;
buflen = strlen(buf);
} while (buflen > 0 && buf[buflen - 1] != '\n');
--- 237,243 ----
do
{
! if (fgets(buf, sizeof(buf), termin) == NULL)
break;
buflen = strlen(buf);
} while (buflen > 0 && buf[buflen - 1] != '\n');
В списке pgsql-patches по дате отправления: