diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2021-09-06 17:38:18 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2021-09-06 17:38:18 +0200 |
commit | 4b032a4d6c4a9e24e66c262d6350e6499d0facb3 (patch) | |
tree | 7f5f59f04dce1d02c8ae1a805917675f3830dec4 | |
parent | 7d06d6e18651cb183a3723fa21ef62935ea08647 (diff) | |
download | busybox-w32-4b032a4d6c4a9e24e66c262d6350e6499d0facb3.tar.gz busybox-w32-4b032a4d6c4a9e24e66c262d6350e6499d0facb3.tar.bz2 busybox-w32-4b032a4d6c4a9e24e66c262d6350e6499d0facb3.zip |
chat: hopefully fix infinite spinning on input EOF
function old new delta
chat_main 1295 1303 +8
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | miscutils/chat.c | 64 |
1 files changed, 34 insertions, 30 deletions
diff --git a/miscutils/chat.c b/miscutils/chat.c index f9e12a4ac..83aac37de 100644 --- a/miscutils/chat.c +++ b/miscutils/chat.c | |||
@@ -201,6 +201,9 @@ int chat_main(int argc UNUSED_PARAM, char **argv) | |||
201 | DIR_RECORD, | 201 | DIR_RECORD, |
202 | }; | 202 | }; |
203 | 203 | ||
204 | #define inbuf bb_common_bufsiz1 | ||
205 | setup_common_bufsiz(); | ||
206 | |||
204 | // make x* functions fail with correct exitcode | 207 | // make x* functions fail with correct exitcode |
205 | xfunc_error_retval = ERR_IO; | 208 | xfunc_error_retval = ERR_IO; |
206 | 209 | ||
@@ -361,35 +364,36 @@ int chat_main(int argc UNUSED_PARAM, char **argv) | |||
361 | // get reply | 364 | // get reply |
362 | pfd.fd = STDIN_FILENO; | 365 | pfd.fd = STDIN_FILENO; |
363 | pfd.events = POLLIN; | 366 | pfd.events = POLLIN; |
364 | while (!exitcode | 367 | while (exitcode == ERR_OK |
365 | && poll(&pfd, 1, timeout) > 0 | 368 | && poll(&pfd, 1, timeout) > 0 |
366 | && (pfd.revents & POLLIN) | 369 | /* && (pfd.revents & POLLIN) - may be untrue (e.g. only POLLERR set) */ |
367 | ) { | 370 | ) { |
368 | llist_t *l; | 371 | llist_t *l; |
369 | ssize_t delta; | 372 | ssize_t delta; |
370 | #define buf bb_common_bufsiz1 | ||
371 | setup_common_bufsiz(); | ||
372 | 373 | ||
373 | // read next char from device | 374 | // read next char from device |
374 | if (safe_read(STDIN_FILENO, buf+buf_len, 1) > 0) { | 375 | if (safe_read(STDIN_FILENO, inbuf + buf_len, 1) <= 0) { |
375 | // dump device input if RECORD fname | 376 | exitcode = ERR_IO; |
376 | if (record_fd > 0) { | 377 | goto expect_done; |
377 | full_write(record_fd, buf+buf_len, 1); | 378 | } |
378 | } | 379 | |
379 | // dump device input if ECHO ON | 380 | // dump device input if RECORD fname |
380 | if (echo) { | 381 | if (record_fd > 0) { |
381 | // if (buf[buf_len] < ' ') { | 382 | full_write(record_fd, inbuf + buf_len, 1); |
382 | // full_write2_str("^"); | 383 | } |
383 | // buf[buf_len] += '@'; | 384 | // dump device input if ECHO ON |
384 | // } | 385 | if (echo) { |
385 | full_write(STDERR_FILENO, buf+buf_len, 1); | 386 | // if (inbuf[buf_len] < ' ') { |
386 | } | 387 | // full_write2_str("^"); |
387 | buf_len++; | 388 | // inbuf[buf_len] += '@'; |
388 | // move input frame if we've reached higher bound | 389 | // } |
389 | if (buf_len > COMMON_BUFSIZE) { | 390 | full_write(STDERR_FILENO, inbuf + buf_len, 1); |
390 | memmove(buf, buf+buf_len-max_len, max_len); | 391 | } |
391 | buf_len = max_len; | 392 | buf_len++; |
392 | } | 393 | // move input frame if we've reached higher bound |
394 | if (buf_len > COMMON_BUFSIZE) { | ||
395 | memmove(inbuf, inbuf + buf_len - max_len, max_len); | ||
396 | buf_len = max_len; | ||
393 | } | 397 | } |
394 | // N.B. rule of thumb: values being looked for can | 398 | // N.B. rule of thumb: values being looked for can |
395 | // be found only at the end of input buffer | 399 | // be found only at the end of input buffer |
@@ -399,20 +403,20 @@ int chat_main(int argc UNUSED_PARAM, char **argv) | |||
399 | // abort condition is met? -> bail out | 403 | // abort condition is met? -> bail out |
400 | for (l = aborts, exitcode = ERR_ABORT; l; l = l->link, ++exitcode) { | 404 | for (l = aborts, exitcode = ERR_ABORT; l; l = l->link, ++exitcode) { |
401 | size_t len = strlen(l->data); | 405 | size_t len = strlen(l->data); |
402 | delta = buf_len-len; | 406 | delta = buf_len - len; |
403 | if (delta >= 0 && !memcmp(buf+delta, l->data, len)) | 407 | if (delta >= 0 && !memcmp(inbuf + delta, l->data, len)) |
404 | goto expect_done; | 408 | goto expect_done; |
405 | } | 409 | } |
406 | exitcode = ERR_OK; | 410 | exitcode = ERR_OK; |
407 | 411 | ||
408 | // expected reply received? -> goto next command | 412 | // expected reply received? -> goto next command |
409 | delta = buf_len - expect_len; | 413 | delta = buf_len - expect_len; |
410 | if (delta >= 0 && !memcmp(buf+delta, expect, expect_len)) | 414 | if (delta >= 0 && memcmp(inbuf + delta, expect, expect_len) == 0) |
411 | goto expect_done; | 415 | goto expect_done; |
412 | #undef buf | ||
413 | } /* while (have data) */ | 416 | } /* while (have data) */ |
414 | 417 | ||
415 | // device timed out or unexpected reply received | 418 | // device timed out, or unexpected reply received, |
419 | // or we got a signal (poll() returned -1 with EINTR). | ||
416 | exitcode = ERR_TIMEOUT; | 420 | exitcode = ERR_TIMEOUT; |
417 | expect_done: | 421 | expect_done: |
418 | #if ENABLE_FEATURE_CHAT_NOFAIL | 422 | #if ENABLE_FEATURE_CHAT_NOFAIL |
@@ -434,7 +438,7 @@ int chat_main(int argc UNUSED_PARAM, char **argv) | |||
434 | } | 438 | } |
435 | #endif | 439 | #endif |
436 | // bail out unless we expected successfully | 440 | // bail out unless we expected successfully |
437 | if (exitcode) | 441 | if (exitcode != ERR_OK) |
438 | break; | 442 | break; |
439 | 443 | ||
440 | //----------------------- | 444 | //----------------------- |
@@ -478,7 +482,7 @@ int chat_main(int argc UNUSED_PARAM, char **argv) | |||
478 | continue; | 482 | continue; |
479 | } | 483 | } |
480 | if ('p' == c) { | 484 | if ('p' == c) { |
481 | usleep(10000); | 485 | msleep(10); |
482 | len--; | 486 | len--; |
483 | continue; | 487 | continue; |
484 | } | 488 | } |