]> git.ipfire.org Git - thirdparty/glibc.git/blame - misc/getpass.c
Update.
[thirdparty/glibc.git] / misc / getpass.c
CommitLineData
50304ef0 1/* Copyright (C) 1992, 93, 94, 95, 96, 97, 98 Free Software Foundation, Inc.
6d52618b 2 This file is part of the GNU C Library.
28f540f4 3
6d52618b
UD
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
28f540f4 8
6d52618b
UD
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
28f540f4 13
6d52618b
UD
14 You should have received a copy of the GNU Library General Public
15 License along with the GNU C Library; see the file COPYING.LIB. If not,
16 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA. */
28f540f4
RM
18
19#include <stdio.h>
20#include <termios.h>
21#include <unistd.h>
22
50304ef0
UD
23#ifdef USE_IN_LIBIO
24# define flockfile(s) _IO_flockfile (s)
25# define funlockfile(s) _IO_funlockfile (s)
26#endif
27
6d52618b 28/* It is desirable to use this bit on systems that have it.
28f540f4
RM
29 The only bit of terminal state we want to twiddle is echoing, which is
30 done in software; there is no need to change the state of the terminal
31 hardware. */
32
33#ifndef TCSASOFT
34#define TCSASOFT 0
35#endif
36
37char *
38getpass (prompt)
39 const char *prompt;
40{
41 FILE *in, *out;
df4ef2ab
UD
42 struct termios s, t;
43 int tty_changed;
28f540f4
RM
44 static char *buf = NULL;
45 static size_t bufsize = 0;
46 ssize_t nread;
47
48 /* Try to write to and read from the terminal if we can.
49 If we can't open the terminal, use stderr and stdin. */
50
51 in = fopen ("/dev/tty", "w+");
52 if (in == NULL)
53 {
54 in = stdin;
55 out = stderr;
56 }
57 else
58 out = in;
59
50304ef0
UD
60 flockfile (out);
61
28f540f4
RM
62 /* Turn echoing off if it is on now. */
63
50304ef0 64 if (__tcgetattr (fileno (in), &t) == 0)
28f540f4 65 {
df4ef2ab
UD
66 /* Save the old one. */
67 s = t;
68 /* Tricky, tricky. */
ceb2d9aa 69 t.c_lflag &= ~(ECHO|ISIG);
df4ef2ab 70 tty_changed = (tcsetattr (fileno (in), TCSAFLUSH|TCSASOFT, &t) == 0);
28f540f4
RM
71 }
72 else
df4ef2ab 73 tty_changed = 0;
28f540f4
RM
74
75 /* Write the prompt. */
50304ef0
UD
76 fputs_unlocked (prompt, out);
77 fflush_unlocked (out);
28f540f4
RM
78
79 /* Read the password. */
80 nread = __getline (&buf, &bufsize, in);
5ca8c0ba
MB
81 if (buf != NULL)
82 if (nread < 0)
83 buf[0] = '\0';
84 else if (buf[nread - 1] == '\n')
85 {
86 /* Remove the newline. */
87 buf[nread - 1] = '\0';
df4ef2ab 88 if (tty_changed)
5ca8c0ba 89 /* Write the newline that was not echoed. */
50304ef0 90 putc_unlocked ('\n', out);
5ca8c0ba 91 }
28f540f4 92
df4ef2ab
UD
93 /* Restore the original setting. */
94 if (tty_changed)
95 (void) tcsetattr (fileno (in), TCSAFLUSH|TCSASOFT, &s);
28f540f4 96
50304ef0
UD
97 funlockfile (out);
98
28f540f4
RM
99 if (in != stdin)
100 /* We opened the terminal; now close it. */
101 fclose (in);
102
103 return buf;
104}