From 6bc82919a69f637e184ff3c64882eafff05bbb5c Mon Sep 17 00:00:00 2001 From: Simon Josefsson Date: Thu, 25 Aug 2005 21:18:50 +0000 Subject: [PATCH] * getpass.c: Add WIN32 implementation. Conditionalize use of termios.h, tcgetattr, tcsetattr and __fsetlocking. Remove some GLIBC specific code. --- lib/ChangeLog | 6 ++ lib/getpass.c | 149 ++++++++++++++++++++++++++------------------------ 2 files changed, 85 insertions(+), 70 deletions(-) diff --git a/lib/ChangeLog b/lib/ChangeLog index 193184d74c..527a593b81 100644 --- a/lib/ChangeLog +++ b/lib/ChangeLog @@ -1,3 +1,9 @@ +2005-08-24 Simon Josefsson + + * getpass.c: Add WIN32 implementation. Conditionalize use of + termios.h, tcgetattr, tcsetattr and __fsetlocking. Remove some + GLIBC specific code. + 2005-08-25 Paul Eggert Make regex safe for g++. This fixes one real bug (an "err" diff --git a/lib/getpass.c b/lib/getpass.c index 7367251e27..cdf90ca57d 100644 --- a/lib/getpass.c +++ b/lib/getpass.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1992-2001, 2003, 2004 Free Software Foundation, Inc. +/* Copyright (C) 1992-2001, 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. This program is free software; you can redistribute it and/or modify @@ -19,43 +19,28 @@ # include #endif -#if !_LIBC -# include "getpass.h" -#endif +#include "getpass.h" -#if _LIBC -# define HAVE_STDIO_EXT_H 1 -#endif +#include + +#if !defined WIN32 #include -#include #if HAVE_STDIO_EXT_H # include -#else -# define __fsetlocking(stream, type) /* empty */ #endif -#if !_LIBC -# include "getline.h" +#if !HAVE___FSETLOCKING +# define __fsetlocking(stream, type) /* empty */ #endif -#include -#include - -#if _LIBC -# include +#if HAVE_TERMIOS_H +# include #endif -#if _LIBC -# define NOTCANCEL_MODE "c" -#else -# define NOTCANCEL_MODE -#endif +#include "getline.h" -#if _LIBC -# define flockfile(s) _IO_flockfile (s) -# define funlockfile(s) _IO_funlockfile (s) -#elif USE_UNLOCKED_IO +#if USE_UNLOCKED_IO # include "unlocked-io.h" #else # if !HAVE_DECL_FFLUSH_UNLOCKED @@ -80,18 +65,6 @@ # endif #endif -#if _LIBC -# include -#else -# define __libc_cleanup_push(function, arg) /* empty */ -# define __libc_cleanup_pop(execute) /* empty */ -#endif - -#if !_LIBC -# define __getline getline -# define __tcgetattr tcgetattr -#endif - /* It is desirable to use this bit on systems that have it. The only bit of terminal state we want to twiddle is echoing, which is done in software; there is no need to change the state of the terminal @@ -114,7 +87,7 @@ getpass (const char *prompt) FILE *tty; FILE *in, *out; struct termios s, t; - bool tty_changed; + bool tty_changed = false; static char *buf; static size_t bufsize; ssize_t nread; @@ -122,7 +95,7 @@ getpass (const char *prompt) /* Try to write to and read from the terminal if we can. If we can't open the terminal, use stderr and stdin. */ - tty = fopen ("/dev/tty", "w+" NOTCANCEL_MODE); + tty = fopen ("/dev/tty", "w+"); if (tty == NULL) { in = stdin; @@ -136,39 +109,26 @@ getpass (const char *prompt) out = in = tty; } - /* Make sure the stream we opened is closed even if the thread is - canceled. */ - __libc_cleanup_push (call_fclose, tty); - flockfile (out); /* Turn echoing off if it is on now. */ - - if (__tcgetattr (fileno (in), &t) == 0) +#if HAVE_TCGETATTR + if (tcgetattr (fileno (in), &t) == 0) { /* Save the old one. */ s = t; /* Tricky, tricky. */ - t.c_lflag &= ~(ECHO|ISIG); - tty_changed = (tcsetattr (fileno (in), TCSAFLUSH|TCSASOFT, &t) == 0); + t.c_lflag &= ~(ECHO | ISIG); + tty_changed = (tcsetattr (fileno (in), TCSAFLUSH | TCSASOFT, &t) == 0); } - else - tty_changed = false; +#endif /* Write the prompt. */ -#ifdef USE_IN_LIBIO - if (_IO_fwide (out, 0) > 0) - __fwprintf (out, L"%s", prompt); - else -#endif - fputs_unlocked (prompt, out); + fputs_unlocked (prompt, out); fflush_unlocked (out); /* Read the password. */ - nread = __getline (&buf, &bufsize, in); - -#if !_LIBC - /* As far as is known, glibc doesn't need this no-op fseek. */ + nread = getline (&buf, &bufsize, in); /* According to the C standard, input may not be followed by output on the same stream without an intervening call to a file @@ -180,7 +140,6 @@ getpass (const char *prompt) from POSIX version to POSIX version, so play it safe and invoke fseek even if in != out. */ fseek (out, 0, SEEK_CUR); -#endif if (buf != NULL) { @@ -193,25 +152,75 @@ getpass (const char *prompt) if (tty_changed) { /* Write the newline that was not echoed. */ -#ifdef USE_IN_LIBIO - if (_IO_fwide (out, 0) > 0) - putwc_unlocked (L'\n', out); - else -#endif - putc_unlocked ('\n', out); + putc_unlocked ('\n', out); } } } /* Restore the original setting. */ +#if TCSETATTR if (tty_changed) - (void) tcsetattr (fileno (in), TCSAFLUSH|TCSASOFT, &s); + tcsetattr (fileno (in), TCSAFLUSH | TCSASOFT, &s); +#endif funlockfile (out); - __libc_cleanup_pop (0); - call_fclose (tty); return buf; } + +#else /* WIN32 */ + +/* Windows implementation by Martin Lambers , + improved by Simon Josefsson. */ + +/* For PASS_MAX. */ +#include + +#ifndef PASS_MAX +# define PASS_MAX 512 +#endif + +char * +getpass (const char *prompt) +{ + char getpassbuf[PASS_MAX + 1]; + size_t i = 0; + int c; + + if (prompt) + { + fputs (prompt, stderr); + fflush (stderr); + } + + for (;;) + { + c = _getch (); + if (c == '\r') + { + getpassbuf[i] = '\0'; + break; + } + else if (i < PASS_MAX) + { + getpassbuf[i++] = c; + } + + if (i >= PASS_MAX) + { + getpassbuf[i] = '\0'; + break; + } + } + + if (prompt) + { + fputs ("\r\n", stderr); + fflush (stderr); + } + + return strdup (getpassbuf); +} +#endif -- 2.30.2