aboutsummaryrefslogtreecommitdiff
path: root/libbb
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2022-01-17 03:02:40 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2022-01-17 11:46:23 +0100
commit12566e7f9b5e5c5d445bc4d36991d134b431dc6c (patch)
tree2571356a77f7d421da368e9b31dad182e83b2408 /libbb
parenta277506a64404e6c4472ff89c944c4f353db1c33 (diff)
downloadbusybox-w32-12566e7f9b5e5c5d445bc4d36991d134b431dc6c.tar.gz
busybox-w32-12566e7f9b5e5c5d445bc4d36991d134b431dc6c.tar.bz2
busybox-w32-12566e7f9b5e5c5d445bc4d36991d134b431dc6c.zip
ash,hush: fix handling of SIGINT while waiting for interactive input
function old new delta lineedit_read_key 160 237 +77 __pgetc 522 589 +67 fgetc_interactive 244 309 +65 safe_read_key - 39 +39 read_key 588 607 +19 record_pending_signo 23 32 +9 signal_handler 75 81 +6 .rodata 104312 104309 -3 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 6/1 up/down: 282/-3) Total: 279 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'libbb')
-rw-r--r--libbb/lineedit.c24
-rw-r--r--libbb/read_key.c16
2 files changed, 35 insertions, 5 deletions
diff --git a/libbb/lineedit.c b/libbb/lineedit.c
index e14c78707..f76afd37d 100644
--- a/libbb/lineedit.c
+++ b/libbb/lineedit.c
@@ -2161,12 +2161,30 @@ static int lineedit_read_key(char *read_key_buffer, int timeout)
2161 * insist on full MB_CUR_MAX buffer to declare input like 2161 * insist on full MB_CUR_MAX buffer to declare input like
2162 * "\xff\n",pause,"ls\n" invalid and thus won't lose "ls". 2162 * "\xff\n",pause,"ls\n" invalid and thus won't lose "ls".
2163 * 2163 *
2164 * If LI_INTERRUPTIBLE, return -1 if got EINTR in poll()
2165 * inside read_key, or if bb_got_signal != 0 (IOW: if signal
2166 * arrived before poll() is reached).
2167 *
2164 * Note: read_key sets errno to 0 on success. 2168 * Note: read_key sets errno to 0 on success.
2165 */ 2169 */
2166 IF_FEATURE_EDITING_WINCH(S.ok_to_redraw = 1;) 2170 do {
2167 ic = read_key(STDIN_FILENO, read_key_buffer, timeout); 2171 if ((state->flags & LI_INTERRUPTIBLE) && bb_got_signal) {
2168 IF_FEATURE_EDITING_WINCH(S.ok_to_redraw = 0;) 2172 errno = EINTR;
2173 return -1;
2174 }
2175//FIXME: still races here with signals, but small window to poll() inside read_key
2176 IF_FEATURE_EDITING_WINCH(S.ok_to_redraw = 1;)
2177 ic = read_key(STDIN_FILENO, read_key_buffer, timeout);
2178 IF_FEATURE_EDITING_WINCH(S.ok_to_redraw = 0;)
2179 } while (!(state->flags & LI_INTERRUPTIBLE) && errno == EINTR);
2180
2169 if (errno) { 2181 if (errno) {
2182 /* LI_INTERRUPTIBLE can bail out with EINTR here,
2183 * but nothing really guarantees that bb_got_signal
2184 * is nonzero. Follow the least surprise principle:
2185 */
2186 if (errno == EINTR && bb_got_signal == 0)
2187 bb_got_signal = 255; /* something nonzero */
2170#if ENABLE_UNICODE_SUPPORT 2188#if ENABLE_UNICODE_SUPPORT
2171 if (errno == EAGAIN && unicode_idx != 0) 2189 if (errno == EAGAIN && unicode_idx != 0)
2172 goto pushback; 2190 goto pushback;
diff --git a/libbb/read_key.c b/libbb/read_key.c
index 03b7da656..829ae215c 100644
--- a/libbb/read_key.c
+++ b/libbb/read_key.c
@@ -126,7 +126,10 @@ int64_t FAST_FUNC read_key(int fd, char *buffer, int timeout)
126 * if fd can be in non-blocking mode. 126 * if fd can be in non-blocking mode.
127 */ 127 */
128 if (timeout >= -1) { 128 if (timeout >= -1) {
129 if (safe_poll(&pfd, 1, timeout) == 0) { 129 n = poll(&pfd, 1, timeout);
130 if (n < 0 && errno == EINTR)
131 return n;
132 if (n == 0) {
130 /* Timed out */ 133 /* Timed out */
131 errno = EAGAIN; 134 errno = EAGAIN;
132 return -1; 135 return -1;
@@ -138,7 +141,7 @@ int64_t FAST_FUNC read_key(int fd, char *buffer, int timeout)
138 * When we were reading 3 bytes here, we were eating 141 * When we were reading 3 bytes here, we were eating
139 * "li" too, and cat was getting wrong input. 142 * "li" too, and cat was getting wrong input.
140 */ 143 */
141 n = safe_read(fd, buffer, 1); 144 n = read(fd, buffer, 1);
142 if (n <= 0) 145 if (n <= 0)
143 return -1; 146 return -1;
144 } 147 }
@@ -284,6 +287,15 @@ int64_t FAST_FUNC read_key(int fd, char *buffer, int timeout)
284 goto start_over; 287 goto start_over;
285} 288}
286 289
290int64_t FAST_FUNC safe_read_key(int fd, char *buffer, int timeout)
291{
292 int64_t r;
293 do {
294 r = read_key(fd, buffer, timeout);
295 } while (errno == EINTR);
296 return r;
297}
298
287void FAST_FUNC read_key_ungets(char *buffer, const char *str, unsigned len) 299void FAST_FUNC read_key_ungets(char *buffer, const char *str, unsigned len)
288{ 300{
289 unsigned cur_len = (unsigned char)buffer[0]; 301 unsigned cur_len = (unsigned char)buffer[0];