/[cvs]/ccvs/lib/getpass.c
ViewVC logotype

Diff of /ccvs/lib/getpass.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.8 by dprice, Mon May 23 17:44:31 2005 UTC revision 1.9 by dprice, Sun Sep 4 05:58:56 2005 UTC
# Line 1  Line 1 
1  /* Copyright (C) 1992-2001, 2003, 2004 Free Software Foundation, Inc.  /* Copyright (C) 1992-2001, 2003, 2004, 2005 Free Software Foundation, Inc.
2     This file is part of the GNU C Library.     This file is part of the GNU C Library.
3    
4     This program is free software; you can redistribute it and/or modify     This program is free software; you can redistribute it and/or modify
# Line 19  Line 19 
19  # include <config.h>  # include <config.h>
20  #endif  #endif
21    
22  #if !_LIBC  #include "getpass.h"
 # include "getpass.h"  
 #endif  
23    
24  #if _LIBC  #include <stdio.h>
25  # define HAVE_STDIO_EXT_H 1  
26  #endif  #if !defined _WIN32
27    
28  #include <stdbool.h>  #include <stdbool.h>
29    
 #include <stdio.h>  
30  #if HAVE_STDIO_EXT_H  #if HAVE_STDIO_EXT_H
31  # include <stdio_ext.h>  # include <stdio_ext.h>
 #else  
 # define __fsetlocking(stream, type) /* empty */  
32  #endif  #endif
33  #if !_LIBC  #if !HAVE___FSETLOCKING
34  # include "getline.h"  # define __fsetlocking(stream, type)    /* empty */
35  #endif  #endif
36    
37  #include <termios.h>  #if HAVE_TERMIOS_H
38  #include <unistd.h>  # include <termios.h>
   
 #if _LIBC  
 # include <wchar.h>  
39  #endif  #endif
40    
41  #if _LIBC  #include "getline.h"
 # define NOTCANCEL_MODE "c"  
 #else  
 # define NOTCANCEL_MODE  
 #endif  
42    
43  #if _LIBC  #if USE_UNLOCKED_IO
 # define flockfile(s) _IO_flockfile (s)  
 # define funlockfile(s) _IO_funlockfile (s)  
 #elif USE_UNLOCKED_IO  
44  # include "unlocked-io.h"  # include "unlocked-io.h"
45  #else  #else
46  # if !HAVE_DECL_FFLUSH_UNLOCKED  # if !HAVE_DECL_FFLUSH_UNLOCKED
# Line 80  Line 65 
65  # endif  # endif
66  #endif  #endif
67    
 #if _LIBC  
 # include <bits/libc-lock.h>  
 #else  
 # define __libc_cleanup_push(function, arg) /* empty */  
 # define __libc_cleanup_pop(execute) /* empty */  
 #endif  
   
 #if !_LIBC  
 # define __getline getline  
 # define __tcgetattr tcgetattr  
 #endif  
   
68  /* It is desirable to use this bit on systems that have it.  /* It is desirable to use this bit on systems that have it.
69     The only bit of terminal state we want to twiddle is echoing, which is     The only bit of terminal state we want to twiddle is echoing, which is
70     done in software; there is no need to change the state of the terminal     done in software; there is no need to change the state of the terminal
# Line 114  getpass (const char *prompt) Line 87  getpass (const char *prompt)
87    FILE *tty;    FILE *tty;
88    FILE *in, *out;    FILE *in, *out;
89    struct termios s, t;    struct termios s, t;
90    bool tty_changed;    bool tty_changed = false;
91    static char *buf;    static char *buf;
92    static size_t bufsize;    static size_t bufsize;
93    ssize_t nread;    ssize_t nread;
# Line 122  getpass (const char *prompt) Line 95  getpass (const char *prompt)
95    /* Try to write to and read from the terminal if we can.    /* Try to write to and read from the terminal if we can.
96       If we can't open the terminal, use stderr and stdin.  */       If we can't open the terminal, use stderr and stdin.  */
97    
98    tty = fopen ("/dev/tty", "w+" NOTCANCEL_MODE);    tty = fopen ("/dev/tty", "w+");
99    if (tty == NULL)    if (tty == NULL)
100      {      {
101        in = stdin;        in = stdin;
# Line 136  getpass (const char *prompt) Line 109  getpass (const char *prompt)
109        out = in = tty;        out = in = tty;
110      }      }
111    
   /* Make sure the stream we opened is closed even if the thread is  
      canceled.  */  
   __libc_cleanup_push (call_fclose, tty);  
   
112    flockfile (out);    flockfile (out);
113    
114    /* Turn echoing off if it is on now.  */    /* Turn echoing off if it is on now.  */
115    #if HAVE_TCGETATTR
116    if (__tcgetattr (fileno (in), &t) == 0)    if (tcgetattr (fileno (in), &t) == 0)
117      {      {
118        /* Save the old one. */        /* Save the old one. */
119        s = t;        s = t;
120        /* Tricky, tricky. */        /* Tricky, tricky. */
121        t.c_lflag &= ~(ECHO|ISIG);        t.c_lflag &= ~(ECHO | ISIG);
122        tty_changed = (tcsetattr (fileno (in), TCSAFLUSH|TCSASOFT, &t) == 0);        tty_changed = (tcsetattr (fileno (in), TCSAFLUSH | TCSASOFT, &t) == 0);
123      }      }
124    else  #endif
     tty_changed = false;  
125    
126    /* Write the prompt.  */    /* Write the prompt.  */
127  #ifdef USE_IN_LIBIO    fputs_unlocked (prompt, out);
   if (_IO_fwide (out, 0) > 0)  
     __fwprintf (out, L"%s", prompt);  
   else  
 #endif  
     fputs_unlocked (prompt, out);  
128    fflush_unlocked (out);    fflush_unlocked (out);
129    
130    /* Read the password.  */    /* Read the password.  */
131    nread = __getline (&buf, &bufsize, in);    nread = getline (&buf, &bufsize, in);
   
 #if !_LIBC  
   /* As far as is known, glibc doesn't need this no-op fseek.  */  
132    
133    /* According to the C standard, input may not be followed by output    /* According to the C standard, input may not be followed by output
134       on the same stream without an intervening call to a file       on the same stream without an intervening call to a file
# Line 180  getpass (const char *prompt) Line 140  getpass (const char *prompt)
140       from POSIX version to POSIX version, so play it safe and invoke       from POSIX version to POSIX version, so play it safe and invoke
141       fseek even if in != out.  */       fseek even if in != out.  */
142    fseek (out, 0, SEEK_CUR);    fseek (out, 0, SEEK_CUR);
 #endif  
143    
144    if (buf != NULL)    if (buf != NULL)
145      {      {
# Line 193  getpass (const char *prompt) Line 152  getpass (const char *prompt)
152            if (tty_changed)            if (tty_changed)
153              {              {
154                /* Write the newline that was not echoed.  */                /* Write the newline that was not echoed.  */
155  #ifdef USE_IN_LIBIO                putc_unlocked ('\n', out);
               if (_IO_fwide (out, 0) > 0)  
                 putwc_unlocked (L'\n', out);  
               else  
 #endif  
                 putc_unlocked ('\n', out);  
156              }              }
157          }          }
158      }      }
159    
160    /* Restore the original setting.  */    /* Restore the original setting.  */
161    #if TCSETATTR
162    if (tty_changed)    if (tty_changed)
163      (void) tcsetattr (fileno (in), TCSAFLUSH|TCSASOFT, &s);      tcsetattr (fileno (in), TCSAFLUSH | TCSASOFT, &s);
164    #endif
165    
166    funlockfile (out);    funlockfile (out);
167    
   __libc_cleanup_pop (0);  
   
168    call_fclose (tty);    call_fclose (tty);
169    
170    return buf;    return buf;
171  }  }
172    
173    #else /* WIN32 */
174    
175    /* Windows implementation by Martin Lambers <marlam@marlam.de>,
176       improved by Simon Josefsson. */
177    
178    /* For PASS_MAX. */
179    #include <limits.h>
180    
181    #ifndef PASS_MAX
182    # define PASS_MAX 512
183    #endif
184    
185    char *
186    getpass (const char *prompt)
187    {
188      char getpassbuf[PASS_MAX + 1];
189      size_t i = 0;
190      int c;
191    
192      if (prompt)
193        {
194          fputs (prompt, stderr);
195          fflush (stderr);
196        }
197    
198      for (;;)
199        {
200          c = _getch ();
201          if (c == '\r')
202            {
203              getpassbuf[i] = '\0';
204              break;
205            }
206          else if (i < PASS_MAX)
207            {
208              getpassbuf[i++] = c;
209            }
210    
211          if (i >= PASS_MAX)
212            {
213              getpassbuf[i] = '\0';
214              break;
215            }
216        }
217    
218      if (prompt)
219        {
220          fputs ("\r\n", stderr);
221          fflush (stderr);
222        }
223    
224      return strdup (getpassbuf);
225    }
226    #endif

Legend:
Removed from v.1.8  
changed lines
  Added in v.1.9

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26