From e5387a0574a4da88411753c4df959a03629063c9 Mon Sep 17 00:00:00 2001
From: Denis Vlasenko <vda.linux@googlemail.com>
Date: Sat, 20 Oct 2007 19:20:22 +0000
Subject: bb_askpass: handle Ctrl-C, restore termoios on Ctrl-C. sulogin:
 remove alarm handling, as it is redundant there. code shrink. After all
 differences cancel out:

   text    data     bss     dec     hex filename
 777543    1000    9532  788075   c066b busybox_old
 777543    1000    9532  788075   c066b busybox_unstripped
---
 libbb/bb_askpass.c | 36 +++++++++++++++++++-----------------
 1 file changed, 19 insertions(+), 17 deletions(-)

(limited to 'libbb')

diff --git a/libbb/bb_askpass.c b/libbb/bb_askpass.c
index 435314ea0..fd12f92dc 100644
--- a/libbb/bb_askpass.c
+++ b/libbb/bb_askpass.c
@@ -17,7 +17,7 @@ static void askpass_timeout(int ATTRIBUTE_UNUSED ignore)
 {
 }
 
-char *bb_askpass(int timeout, const char * prompt)
+char *bb_askpass(int timeout, const char *prompt)
 {
 	/* Was static char[BIGNUM] */
 	enum { sizeof_passwd = 128 };
@@ -25,35 +25,36 @@ char *bb_askpass(int timeout, const char * prompt)
 
 	char *ret;
 	int i;
-	struct sigaction sa;
-	struct termios old, new;
+	struct sigaction sa, oldsa;
+	struct termios tio, oldtio;
 
 	if (!passwd)
 		passwd = xmalloc(sizeof_passwd);
 	memset(passwd, 0, sizeof_passwd);
 
-	tcgetattr(STDIN_FILENO, &old);
+	tcgetattr(STDIN_FILENO, &oldtio);
 	tcflush(STDIN_FILENO, TCIFLUSH);
+	tio = oldtio;
+	tio.c_iflag &= ~(IUCLC|IXON|IXOFF|IXANY);
+	tio.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|TOSTOP);
+	tcsetattr(STDIN_FILENO, TCSANOW, &tio);
 
-	fputs(prompt, stdout);
-	fflush(stdout);
-
-	tcgetattr(STDIN_FILENO, &new);
-	new.c_iflag &= ~(IUCLC|IXON|IXOFF|IXANY);
-	new.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|TOSTOP);
-	tcsetattr(STDIN_FILENO, TCSANOW, &new);
-
+	memset(&sa, 0, sizeof(sa));
+	/* sa.sa_flags = 0; - no SA_RESTART! */
+	/* SIGINT and SIGALRM will interrupt read below */
+	sa.sa_handler = askpass_timeout;
+	sigaction(SIGINT, &sa, &oldsa);
 	if (timeout) {
-		sa.sa_flags = 0;
-		sa.sa_handler = askpass_timeout;
 		sigaction(SIGALRM, &sa, NULL);
 		alarm(timeout);
 	}
 
+	fputs(prompt, stdout);
+	fflush(stdout);
 	ret = NULL;
-	/* On timeout, read will hopefully be interrupted by SIGALRM,
+	/* On timeout or Ctrl-C, read will hopefully be interrupted,
 	 * and we return NULL */
-	if (read(STDIN_FILENO, passwd, sizeof_passwd-1) > 0) {
+	if (read(STDIN_FILENO, passwd, sizeof_passwd - 1) > 0) {
 		ret = passwd;
 		i = 0;
 		/* Last byte is guaranteed to be 0
@@ -67,8 +68,9 @@ char *bb_askpass(int timeout, const char * prompt)
 	if (timeout) {
 		alarm(0);
 	}
+	sigaction(SIGINT, &oldsa, NULL);
 
-	tcsetattr(STDIN_FILENO, TCSANOW, &old);
+	tcsetattr(STDIN_FILENO, TCSANOW, &oldtio);
 	bb_putchar('\n');
 	fflush(stdout);
 	return ret;
-- 
cgit v1.2.3-55-g6feb