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;
}