1 /* Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
2 2001, 2003, 2004, 2005, 2006, 2007, 2009 Free Software Foundation,
5 This file is part of the GNU C Library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License along
18 with this program; if not, write to the Free Software Foundation,
19 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
29 #if !((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__)
33 #if HAVE_DECL___FSETLOCKING && HAVE___FSETLOCKING
35 # include <stdio_ext.h>
38 # define __fsetlocking(stream, type) /* empty */
46 # include "unlocked-io.h"
48 # if !HAVE_DECL_FFLUSH_UNLOCKED
49 # undef fflush_unlocked
50 # define fflush_unlocked(x) fflush (x)
52 # if !HAVE_DECL_FLOCKFILE
54 # define flockfile(x) ((void) 0)
56 # if !HAVE_DECL_FUNLOCKFILE
58 # define funlockfile(x) ((void) 0)
60 # if !HAVE_DECL_FPUTS_UNLOCKED
61 # undef fputs_unlocked
62 # define fputs_unlocked(str,stream) fputs (str, stream)
64 # if !HAVE_DECL_PUTC_UNLOCKED
66 # define putc_unlocked(c,stream) putc (c, stream)
70 /* It is desirable to use this bit on systems that have it.
71 The only bit of terminal state we want to twiddle is echoing, which is
72 done in software; there is no need to change the state of the terminal
80 call_fclose (void *arg)
87 getpass (const char *prompt)
92 bool tty_changed = false;
94 static size_t bufsize;
97 /* Try to write to and read from the terminal if we can.
98 If we can't open the terminal, use stderr and stdin. */
100 tty = fopen ("/dev/tty", "w+");
108 /* We do the locking ourselves. */
109 __fsetlocking (tty, FSETLOCKING_BYCALLER);
116 /* Turn echoing off if it is on now. */
118 if (tcgetattr (fileno (in), &t) == 0)
120 /* Save the old one. */
122 /* Tricky, tricky. */
123 t.c_lflag &= ~(ECHO | ISIG);
124 tty_changed = (tcsetattr (fileno (in), TCSAFLUSH | TCSASOFT, &t) == 0);
128 /* Write the prompt. */
129 fputs_unlocked (prompt, out);
130 fflush_unlocked (out);
132 /* Read the password. */
133 nread = getline (&buf, &bufsize, in);
135 /* According to the C standard, input may not be followed by output
136 on the same stream without an intervening call to a file
137 positioning function. Suppose in == out; then without this fseek
138 call, on Solaris, HP-UX, AIX, OSF/1, the previous input gets
139 echoed, whereas on IRIX, the following newline is not output as
140 it should be. POSIX imposes similar restrictions if fileno (in)
141 == fileno (out). The POSIX restrictions are tricky and change
142 from POSIX version to POSIX version, so play it safe and invoke
143 fseek even if in != out. */
144 fseeko (out, 0, SEEK_CUR);
150 else if (buf[nread - 1] == '\n')
152 /* Remove the newline. */
153 buf[nread - 1] = '\0';
156 /* Write the newline that was not echoed. */
157 putc_unlocked ('\n', out);
162 /* Restore the original setting. */
165 tcsetattr (fileno (in), TCSAFLUSH | TCSASOFT, &s);
175 #else /* W32 native */
177 /* Windows implementation by Martin Lambers <marlam@marlam.de>,
178 improved by Simon Josefsson. */
188 # define PASS_MAX 512
192 getpass (const char *prompt)
194 char getpassbuf[PASS_MAX + 1];
200 fputs (prompt, stderr);
209 getpassbuf[i] = '\0';
212 else if (i < PASS_MAX)
219 getpassbuf[i] = '\0';
226 fputs ("\r\n", stderr);
230 return strdup (getpassbuf);