summaryrefslogtreecommitdiff
path: root/libc/unistd
diff options
context:
space:
mode:
authorDenys Vlasenko <dvlasenk@redhat.com>2011-12-23 14:24:12 +0100
committerDenys Vlasenko <dvlasenk@redhat.com>2011-12-23 14:24:12 +0100
commit38b3cd5f04f3a0c38941146b81e8292ec3abbcac (patch)
tree8486c0e717f126d5f889e69e8d682a8cefd60d8e /libc/unistd
parent8a8434b367e0b94b9fda72c99f1c646737725403 (diff)
getpass: several fixes
fixes bogus fgets error check fixes bogus strlen() < 0 check switches off buffering regardless of tcgetattr() success prints newline even on error or if there was no '\n' on input uses sizeof(buf) instead of PWD_BUFFER_SIZE Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
Diffstat (limited to 'libc/unistd')
-rw-r--r--libc/unistd/getpass.c46
1 files changed, 19 insertions, 27 deletions
diff --git a/libc/unistd/getpass.c b/libc/unistd/getpass.c
index 8d8018231..dd927ab87 100644
--- a/libc/unistd/getpass.c
+++ b/libc/unistd/getpass.c
@@ -45,17 +45,22 @@ char * 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. */
- in = fopen ("/dev/tty", "r+");
+ out = in = fopen ("/dev/tty", "r+");
if (in == NULL)
{
in = stdin;
out = stderr;
}
else
- out = in;
+ {
+ /* Disable buffering for read/write FILE to prevent problems with
+ * fseek and buffering for read/write auto-transitioning. */
+ setvbuf(in, NULL, _IONBF, 0);
+ }
/* Turn echoing off if it is on now. */
+ tty_changed = 0;
if (tcgetattr (fileno (in), &t) == 0)
{
/* Save the old one. */
@@ -63,41 +68,28 @@ char * getpass (const char *prompt)
/* Tricky, tricky. */
t.c_lflag &= ~(ECHO|ISIG);
tty_changed = (tcsetattr (fileno (in), TCSAFLUSH|TCSASOFT, &t) == 0);
- if (in != stdin) {
- /* Disable buffering for read/write FILE to prevent problems with
- * fseek and buffering for read/write auto-transitioning. */
- setvbuf(in, NULL, _IONBF, 0);
- }
}
- else
- tty_changed = 0;
/* Write the prompt. */
fputs(prompt, out);
fflush(out);
/* Read the password. */
- fgets (buf, PWD_BUFFER_SIZE-1, in);
- if (buf != NULL)
+ if (!fgets (buf, sizeof(buf)-1, in))
+ buf[0] = '\0';
+ nread = strlen(buf);
+ if (nread > 0 && buf[nread - 1] == '\n')
+ /* Remove the newline. */
+ buf[nread - 1] = '\0';
+
+ if (tty_changed)
{
- nread = strlen(buf);
- if (nread < 0)
- buf[0] = '\0';
- else if (buf[nread - 1] == '\n')
- {
- /* Remove the newline. */
- buf[nread - 1] = '\0';
- if (tty_changed)
- /* Write the newline that was not echoed. */
- putc('\n', out);
- }
+ /* Write the newline that was not echoed. */
+ putc('\n', out);
+ /* Restore the original setting. */
+ (void) tcsetattr (fileno (in), TCSAFLUSH|TCSASOFT, &s);
}
- /* Restore the original setting. */
- if (tty_changed) {
- (void) tcsetattr (fileno (in), TCSAFLUSH|TCSASOFT, &s);
- }
-
if (in != stdin)
/* We opened the terminal; now close it. */
fclose (in);