]> sourceware.org Git - newlib-cygwin.git/commitdiff
* passwd.cc (_getpass_close_fd): New static pthread cleanup handler.
authorCorinna Vinschen <corinna@vinschen.de>
Wed, 4 Apr 2012 09:57:17 +0000 (09:57 +0000)
committerCorinna Vinschen <corinna@vinschen.de>
Wed, 4 Apr 2012 09:57:17 +0000 (09:57 +0000)
(getpass): Rework to use /dev/tty in the first place.  Install
_getpass_close_fd as pthread cleanup handler.  Flush prompt explicitely.
Lock input and switch off signal input handling when reading password.

winsup/cygwin/ChangeLog
winsup/cygwin/passwd.cc

index 80cf8643b8a543799cf78c5900f74e0966dc5245..3ac3e33c9aa9908f124d94c636a585b9d2e70a1c 100644 (file)
@@ -1,3 +1,10 @@
+2012-04-04  Corinna Vinschen  <corinna@vinschen.de>
+
+       * passwd.cc (_getpass_close_fd): New static pthread cleanup handler.
+       (getpass): Rework to use /dev/tty in the first place.  Install
+       _getpass_close_fd as pthread cleanup handler.  Flush prompt explicitely.
+       Lock input and switch off signal input handling when reading password.
+
 2012-04-03  Corinna Vinschen  <corinna@vinschen.de>
 
        * include/cygwin/version.h (CYGWIN_VERSION_DLL_MINOR): Bump to 13.
index 962bf776efec742945a5233b6a8b73e34613b948..74b8020b83aabb6713dd24d1699efa18f39b1b6b 100644 (file)
@@ -269,29 +269,50 @@ setpassent ()
   return 0;
 }
 
+static void
+_getpass_close_fd (void *arg)
+{
+  if (arg)
+    fclose ((FILE *) arg);
+}
+
 extern "C" char *
 getpass (const char * prompt)
 {
   char *pass = _my_tls.locals.pass;
   struct termios ti, newti;
 
-  cygheap_fdget fhstdin (0);
+  /* Try to use controlling tty in the first place.  Use stdin and stderr
+     only as fallback. */
+  FILE *in = stdin, *err = stderr;
+  FILE *tty = fopen ("/dev/tty", "w+b");
+  pthread_cleanup_push  (_getpass_close_fd, tty);
+  if (tty)
+    {
+      /* Set close-on-exec for obvious reasons. */
+      fcntl (fileno (tty), F_SETFD, fcntl (fileno (tty), F_GETFD) | FD_CLOEXEC);
+      in = err = tty;
+    }
 
-  if (fhstdin < 0)
+  /* Make sure to notice if stdin is closed. */
+  if (tcgetattr (fileno (in), &ti) == -1)
     pass[0] = '\0';
   else
     {
-      fhstdin->tcgetattr (&ti);
+      flockfile (in);
       newti = ti;
-      newti.c_lflag &= ~ECHO;
-      fhstdin->tcsetattr (TCSANOW, &newti);
-      fputs (prompt, stderr);
-      fgets (pass, _PASSWORD_LEN, stdin);
-      fprintf (stderr, "\n");
-      for (int i=0; pass[i]; i++)
-       if (pass[i] == '\r' || pass[i] == '\n')
-         pass[i] = '\0';
-      fhstdin->tcsetattr (TCSANOW, &ti);
+      newti.c_lflag &= ~(ECHO | ISIG); /* No echo, no signal handling. */
+      tcsetattr (fileno (in), TCSANOW, &newti);
+      fputs (prompt, err);
+      fflush (err);
+      fgets (pass, _PASSWORD_LEN, in);
+      fprintf (err, "\n");
+      tcsetattr (fileno (in), TCSANOW, &ti);
+      funlockfile (in);
+      char *crlf = strpbrk (pass, "\r\n");
+      if (crlf)
+       *crlf = '\0';
     }
+  pthread_cleanup_pop (1);
   return pass;
 }
This page took 0.036901 seconds and 5 git commands to generate.