diff options
author | Darren Tucker <dtucker@zip.com.au> | 2016-10-13 04:04:44 +1100 |
---|---|---|
committer | Darren Tucker <dtucker@zip.com.au> | 2016-10-13 04:04:44 +1100 |
commit | 12069e56221de207ed666c2449dedb431a2a7ca2 (patch) | |
tree | 4e4d7fb0071ec4c2d2d2c083f7e9c6ddb77c97d2 | |
parent | 7508d83eff89af069760b4cc587305588a64e415 (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.c | 84 |
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); |