Module Name: src Committed By: christos Date: Thu Apr 12 20:08:01 UTC 2012
Modified Files: src/lib/libc/gen: getpass.c Log Message: raise signals for the tty characters that do. To generate a diff of this commit: cvs rdiff -u -r1.17 -r1.18 src/lib/libc/gen/getpass.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/lib/libc/gen/getpass.c diff -u src/lib/libc/gen/getpass.c:1.17 src/lib/libc/gen/getpass.c:1.18 --- src/lib/libc/gen/getpass.c:1.17 Thu Apr 12 15:36:19 2012 +++ src/lib/libc/gen/getpass.c Thu Apr 12 16:08:01 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: getpass.c,v 1.17 2012/04/12 19:36:19 christos Exp $ */ +/* $NetBSD: getpass.c,v 1.18 2012/04/12 20:08:01 christos Exp $ */ /*- * Copyright (c) 2012 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> #if defined(LIBC_SCCS) && !defined(lint) -__RCSID("$NetBSD: getpass.c,v 1.17 2012/04/12 19:36:19 christos Exp $"); +__RCSID("$NetBSD: getpass.c,v 1.18 2012/04/12 20:08:01 christos Exp $"); #endif /* LIBC_SCCS and not lint */ #include "namespace.h" @@ -40,6 +40,7 @@ __RCSID("$NetBSD: getpass.c,v 1.17 2012/ #include <stdio.h> #endif #include <errno.h> +#include <signal.h> #include <string.h> #include <paths.h> #include <stdbool.h> @@ -64,20 +65,21 @@ __weak_alias(getpass,_getpass) * off echo failed, we provide a tunable DONT_WORK_AND_ECHO to * disable this. * - Some implementations say that on interrupt the program shall - * receive an interrupt signal before the function returns. This - * does not sound useful, but it could be easy to implement using - * raise(3). + * receive an interrupt signal before the function returns. We + * send all the tty signals before we return, but we don't expect + * suspend to do something useful unless the caller calls us again. */ char * getpass_r(const char *prompt, char *ret, size_t len) { struct termios gt; char c; - int infd, outfd; + int infd, outfd, sig; bool lnext, havetty; _DIAGASSERT(prompt != NULL); + sig = 0; /* * Try to use /dev/tty if possible; otherwise read from stdin and * write to stderr. @@ -156,24 +158,33 @@ getpass_r(const char *prompt, char *ret, continue; } - /* EOF or tty signal characters */ - if ( + /* tty signal characters */ + if (c == C(VINTR, CTRL('c'))) { + sig = SIGINT; + goto out; + } + if (c == C(VQUIT, CTRL('\\'))) { + sig = SIGQUIT; + goto out; + } + if (c == C(VSUSP, CTRL('z')) || c == C(VDSUSP, CTRL('y'))) { + sig = SIGTSTP; + goto out; + } + + /* EOF */ + if (c == C(VEOF, CTRL('d'))) { #ifdef DONT_TREAT_EOF_AS_EOL - c == C(VEOF, CTRL('d')) || -#endif - c == C(VINTR, CTRL('c')) || - c == C(VQUIT, CTRL('\\')) || c == C(VSUSP, CTRL('z')) || - c == C(VDSUSP, CTRL('y'))) { - errno = EINTR; + errno = ENODATA; goto out; +#else + c = '\0'; + goto add; +#endif } /* End of line */ - if ( -#ifndef DONT_TREAT_EOF_AS_EOL - c == C(VEOF, CTRL('d')) || -#endif - c == C(VEOL, CTRL('j')) || c == C(VEOL2, CTRL('l'))) + if (c == C(VEOL, CTRL('j')) || c == C(VEOL2, CTRL('l'))) c = '\0'; add: if (l >= len) { @@ -199,6 +210,10 @@ restore: (void)tcsetattr(infd, TCSAFLUSH|TCSASOFT, >); errno = c; out: + if (sig) { + (void)raise(sig); + errno = EINTR; + } return NULL; }