summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarren Tucker <dtucker@zip.com.au>2016-10-13 04:04:44 +1100
committerDarren Tucker <dtucker@zip.com.au>2016-10-13 04:04:44 +1100
commit12069e56221de207ed666c2449dedb431a2a7ca2 (patch)
tree4e4d7fb0071ec4c2d2d2c083f7e9c6ddb77c97d2
parent7508d83eff89af069760b4cc587305588a64e415 (diff)
Import rev 1.23 from OpenBSD. Fixes bz#2619.
revision 1.23 date: 2010/05/14 13:30:34; author: millert; state: Exp; lines: +41 -39; Defer installing signal handlers until echo is disabled so that we get suspended normally when not the foreground process. Fix potential infinite loop when restoring terminal settings if process is in the background when restore occurs. OK miod@
-rw-r--r--openbsd-compat/readpassphrase.c84
1 files changed, 43 insertions, 41 deletions
diff --git a/openbsd-compat/readpassphrase.c b/openbsd-compat/readpassphrase.c
index 81c4c2fa1..82a0b7239 100644
--- a/openbsd-compat/readpassphrase.c
+++ b/openbsd-compat/readpassphrase.c
@@ -1,7 +1,8 @@
1/* $OpenBSD: readpassphrase.c,v 1.22 2010/01/13 10:20:54 dtucker Exp $ */ 1/* $OpenBSD: readpassphrase.c,v 1.23 2010/05/14 13:30:34 millert Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000-2002, 2007 Todd C. Miller <Todd.Miller@courtesan.com> 4 * Copyright (c) 2000-2002, 2007, 2010
5 * Todd C. Miller <Todd.Miller@courtesan.com>
5 * 6 *
6 * Permission to use, copy, modify, and distribute this software for any 7 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above 8 * purpose with or without fee is hereby granted, provided that the above
@@ -94,24 +95,10 @@ restart:
94 } 95 }
95 96
96 /* 97 /*
97 * Catch signals that would otherwise cause the user to end 98 * Turn off echo if possible.
98 * up with echo turned off in the shell. Don't worry about 99 * If we are using a tty but are not the foreground pgrp this will
99 * things like SIGXCPU and SIGVTALRM for now. 100 * generate SIGTTOU, so do it *before* installing the signal handlers.
100 */ 101 */
101 sigemptyset(&sa.sa_mask);
102 sa.sa_flags = 0; /* don't restart system calls */
103 sa.sa_handler = handler;
104 (void)sigaction(SIGALRM, &sa, &savealrm);
105 (void)sigaction(SIGHUP, &sa, &savehup);
106 (void)sigaction(SIGINT, &sa, &saveint);
107 (void)sigaction(SIGPIPE, &sa, &savepipe);
108 (void)sigaction(SIGQUIT, &sa, &savequit);
109 (void)sigaction(SIGTERM, &sa, &saveterm);
110 (void)sigaction(SIGTSTP, &sa, &savetstp);
111 (void)sigaction(SIGTTIN, &sa, &savettin);
112 (void)sigaction(SIGTTOU, &sa, &savettou);
113
114 /* Turn off echo if possible. */
115 if (input != STDIN_FILENO && tcgetattr(input, &oterm) == 0) { 102 if (input != STDIN_FILENO && tcgetattr(input, &oterm) == 0) {
116 memcpy(&term, &oterm, sizeof(term)); 103 memcpy(&term, &oterm, sizeof(term));
117 if (!(flags & RPP_ECHO_ON)) 104 if (!(flags & RPP_ECHO_ON))
@@ -128,35 +115,50 @@ restart:
128 oterm.c_lflag |= ECHO; 115 oterm.c_lflag |= ECHO;
129 } 116 }
130 117
131 /* No I/O if we are already backgrounded. */ 118 /*
132 if (signo[SIGTTOU] != 1 && signo[SIGTTIN] != 1) { 119 * Catch signals that would otherwise cause the user to end
133 if (!(flags & RPP_STDIN)) 120 * up with echo turned off in the shell. Don't worry about
134 (void)write(output, prompt, strlen(prompt)); 121 * things like SIGXCPU and SIGVTALRM for now.
135 end = buf + bufsiz - 1; 122 */
136 p = buf; 123 sigemptyset(&sa.sa_mask);
137 while ((nr = read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r') { 124 sa.sa_flags = 0; /* don't restart system calls */
138 if (p < end) { 125 sa.sa_handler = handler;
139 if ((flags & RPP_SEVENBIT)) 126 (void)sigaction(SIGALRM, &sa, &savealrm);
140 ch &= 0x7f; 127 (void)sigaction(SIGHUP, &sa, &savehup);
141 if (isalpha(ch)) { 128 (void)sigaction(SIGINT, &sa, &saveint);
142 if ((flags & RPP_FORCELOWER)) 129 (void)sigaction(SIGPIPE, &sa, &savepipe);
143 ch = (char)tolower(ch); 130 (void)sigaction(SIGQUIT, &sa, &savequit);
144 if ((flags & RPP_FORCEUPPER)) 131 (void)sigaction(SIGTERM, &sa, &saveterm);
145 ch = (char)toupper(ch); 132 (void)sigaction(SIGTSTP, &sa, &savetstp);
146 } 133 (void)sigaction(SIGTTIN, &sa, &savettin);
147 *p++ = ch; 134 (void)sigaction(SIGTTOU, &sa, &savettou);
135
136 if (!(flags & RPP_STDIN))
137 (void)write(output, prompt, strlen(prompt));
138 end = buf + bufsiz - 1;
139 p = buf;
140 while ((nr = read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r') {
141 if (p < end) {
142 if ((flags & RPP_SEVENBIT))
143 ch &= 0x7f;
144 if (isalpha(ch)) {
145 if ((flags & RPP_FORCELOWER))
146 ch = (char)tolower(ch);
147 if ((flags & RPP_FORCEUPPER))
148 ch = (char)toupper(ch);
148 } 149 }
150 *p++ = ch;
149 } 151 }
150 *p = '\0';
151 save_errno = errno;
152 if (!(term.c_lflag & ECHO))
153 (void)write(output, "\n", 1);
154 } 152 }
153 *p = '\0';
154 save_errno = errno;
155 if (!(term.c_lflag & ECHO))
156 (void)write(output, "\n", 1);
155 157
156 /* Restore old terminal settings and signals. */ 158 /* Restore old terminal settings and signals. */
157 if (memcmp(&term, &oterm, sizeof(term)) != 0) { 159 if (memcmp(&term, &oterm, sizeof(term)) != 0) {
158 while (tcsetattr(input, TCSAFLUSH|TCSASOFT, &oterm) == -1 && 160 while (tcsetattr(input, TCSAFLUSH|TCSASOFT, &oterm) == -1 &&
159 errno == EINTR) 161 errno == EINTR && !signo[SIGTTOU])
160 continue; 162 continue;
161 } 163 }
162 (void)sigaction(SIGALRM, &savealrm, NULL); 164 (void)sigaction(SIGALRM, &savealrm, NULL);