diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-02 16:32:36 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-05 15:43:35 +0100 |
commit | ab3c568fd869e84a7862f3450a4690d3d7b60704 (patch) | |
tree | 01090c4a6808a7e65515fb026c235c54a99e2155 | |
parent | 6d9146ab56018b232a178b8fa463338cf731a832 (diff) | |
download | busybox-w32-ab3c568fd869e84a7862f3450a4690d3d7b60704.tar.gz busybox-w32-ab3c568fd869e84a7862f3450a4690d3d7b60704.tar.bz2 busybox-w32-ab3c568fd869e84a7862f3450a4690d3d7b60704.zip |
bc: simplify ^C handling
It's still buggy: if SIGINT would interrupt e.g. output write(),
the result would not be as intended:
>>> while ( 1 ) print 1
...
11111111111111111111111111111111111111111111111111111111111111111111\
11111111111111111111111111111111111111111111111111111111111111111111\
^Cready for more input
interrupt (type "quit" to exit)
>>> bc: output error
function old new delta
dc_parse_parse 58 53 -5
bc_parse_parse 476 471 -5
bc_num_d 609 604 -5
bc_num_cmp 299 294 -5
bc_num_compare 90 84 -6
bc_parse_expr 2222 2215 -7
bc_num_subArrays 82 74 -8
dc_main 72 62 -10
bc_main 72 62 -10
bc_program_exec 4413 4401 -12
bc_num_a 491 474 -17
bc_read_line 364 344 -20
bc_num_p 540 518 -22
bc_program_reset 192 168 -24
bc_num_k 1031 1005 -26
bc_vm_run 2382 2317 -65
bc_vm_sig 97 - -97
------------------------------------------------------------------------------
(add/remove: 0/1 grow/shrink: 0/16 up/down: 0/-344) Total: -344 bytes
text data bss dec hex filename
989372 485 7296 997153 f3721 busybox_old
989028 485 7296 996809 f35c9 busybox_unstripped
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | miscutils/bc.c | 139 |
1 files changed, 59 insertions, 80 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c index e13b2283c..72afb6808 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c | |||
@@ -826,16 +826,8 @@ struct globals { | |||
826 | 826 | ||
827 | char *env_args; | 827 | char *env_args; |
828 | 828 | ||
829 | unsigned sig; //counter? | ||
830 | unsigned sigc; //counter? | ||
831 | smallint signe; //flag | ||
832 | |||
833 | smallint tty; | 829 | smallint tty; |
834 | smallint ttyin; | 830 | smallint ttyin; |
835 | |||
836 | #if ENABLE_FEATURE_BC_SIGNALS | ||
837 | const char *sig_msg; | ||
838 | #endif | ||
839 | } FIX_ALIASING; | 831 | } FIX_ALIASING; |
840 | #define G (*ptr_to_globals) | 832 | #define G (*ptr_to_globals) |
841 | #define INIT_G() do { \ | 833 | #define INIT_G() do { \ |
@@ -844,6 +836,7 @@ struct globals { | |||
844 | #define G_posix (ENABLE_BC && (G.flags & BC_FLAG_S)) | 836 | #define G_posix (ENABLE_BC && (G.flags & BC_FLAG_S)) |
845 | #define G_warn (ENABLE_BC && (G.flags & BC_FLAG_W)) | 837 | #define G_warn (ENABLE_BC && (G.flags & BC_FLAG_W)) |
846 | #define G_exreg (ENABLE_DC && (G.flags & BC_FLAG_X)) | 838 | #define G_exreg (ENABLE_DC && (G.flags & BC_FLAG_X)) |
839 | #define G_interrupt (ENABLE_FEATURE_BC_SIGNALS ? bb_got_signal : 0) | ||
847 | 840 | ||
848 | 841 | ||
849 | #define IS_BC (ENABLE_BC && (!ENABLE_DC || applet_name[0] == 'b')) | 842 | #define IS_BC (ENABLE_BC && (!ENABLE_DC || applet_name[0] == 'b')) |
@@ -1349,36 +1342,47 @@ static BcStatus bc_read_line(BcVec *vec, const char *prompt) | |||
1349 | int i; | 1342 | int i; |
1350 | signed char c; | 1343 | signed char c; |
1351 | 1344 | ||
1352 | if (G.ttyin && !G_posix) { | ||
1353 | fputs(prompt, stderr); | ||
1354 | fflush(stderr); | ||
1355 | } | ||
1356 | |||
1357 | bc_vec_npop(vec, vec->len); | 1345 | bc_vec_npop(vec, vec->len); |
1358 | 1346 | ||
1347 | fflush(stdout); | ||
1348 | #if ENABLE_FEATURE_BC_SIGNALS | ||
1349 | if (bb_got_signal) { /* ^C was pressed */ | ||
1350 | intr: | ||
1351 | fputs(IS_BC | ||
1352 | ? "\ninterrupt (type \"quit\" to exit)\n" | ||
1353 | : "\ninterrupt (type \"q\" to exit)\n" | ||
1354 | , stderr); | ||
1355 | } | ||
1356 | bb_got_signal = 0; /* resets G_interrupt to zero */ | ||
1357 | #endif | ||
1358 | if (G.ttyin && !G_posix) | ||
1359 | fputs(prompt, stderr); | ||
1360 | fflush(stderr); | ||
1361 | |||
1362 | #if ENABLE_FEATURE_BC_SIGNALS | ||
1363 | again: | ||
1364 | errno = 0; | ||
1365 | #endif | ||
1359 | do { | 1366 | do { |
1360 | if (ferror(stdout) || ferror(stderr)) | 1367 | if (ferror(stdout) || ferror(stderr)) |
1361 | bb_perror_msg_and_die("output error"); | 1368 | bb_perror_msg_and_die("output error"); |
1362 | 1369 | ||
1363 | errno = 0; | ||
1364 | i = fgetc(stdin); | 1370 | i = fgetc(stdin); |
1365 | 1371 | ||
1372 | #if ENABLE_FEATURE_BC_SIGNALS | ||
1373 | if (bb_got_signal) /* ^C was pressed */ | ||
1374 | goto intr; | ||
1375 | #endif | ||
1376 | |||
1366 | if (i == EOF) { | 1377 | if (i == EOF) { |
1367 | #if ENABLE_FEATURE_BC_SIGNALS | 1378 | #if ENABLE_FEATURE_BC_SIGNALS |
1368 | if (errno == EINTR) { | 1379 | if (errno == EINTR) { |
1369 | G.sigc = G.sig; | ||
1370 | G.signe = 0; | ||
1371 | if (G.ttyin) { | ||
1372 | fputs(bc_program_ready_msg, stderr); | ||
1373 | if (!G_posix) fputs(prompt, stderr); | ||
1374 | fflush(stderr); | ||
1375 | } | ||
1376 | clearerr(stdin); | 1380 | clearerr(stdin); |
1377 | continue; | 1381 | goto again; |
1378 | } | 1382 | } |
1383 | #endif | ||
1379 | if (ferror(stdin)) | 1384 | if (ferror(stdin)) |
1380 | bb_perror_msg_and_die("input error"); | 1385 | bb_perror_msg_and_die("input error"); |
1381 | #endif | ||
1382 | return BC_STATUS_INPUT_EOF; | 1386 | return BC_STATUS_INPUT_EOF; |
1383 | } | 1387 | } |
1384 | 1388 | ||
@@ -1471,20 +1475,20 @@ static BcStatus bc_num_subArrays(BcDig *restrict a, BcDig *restrict b, | |||
1471 | size_t len) | 1475 | size_t len) |
1472 | { | 1476 | { |
1473 | size_t i, j; | 1477 | size_t i, j; |
1474 | for (i = 0; !G.signe && i < len; ++i) { | 1478 | for (i = 0; !G_interrupt && i < len; ++i) { |
1475 | for (a[i] -= b[i], j = 0; !G.signe && a[i + j] < 0;) { | 1479 | for (a[i] -= b[i], j = 0; !G_interrupt && a[i + j] < 0;) { |
1476 | a[i + j++] += 10; | 1480 | a[i + j++] += 10; |
1477 | a[i + j] -= 1; | 1481 | a[i + j] -= 1; |
1478 | } | 1482 | } |
1479 | } | 1483 | } |
1480 | return G.signe ? BC_STATUS_EXEC_SIGNAL : BC_STATUS_SUCCESS; | 1484 | return G_interrupt ? BC_STATUS_EXEC_SIGNAL : BC_STATUS_SUCCESS; |
1481 | } | 1485 | } |
1482 | 1486 | ||
1483 | static ssize_t bc_num_compare(BcDig *restrict a, BcDig *restrict b, size_t len) | 1487 | static ssize_t bc_num_compare(BcDig *restrict a, BcDig *restrict b, size_t len) |
1484 | { | 1488 | { |
1485 | size_t i; | 1489 | size_t i; |
1486 | int c = 0; | 1490 | int c = 0; |
1487 | for (i = len - 1; !G.signe && i < len && !(c = a[i] - b[i]); --i); | 1491 | for (i = len - 1; !G_interrupt && i < len && !(c = a[i] - b[i]); --i); |
1488 | return BC_NUM_NEG(i + 1, c < 0); | 1492 | return BC_NUM_NEG(i + 1, c < 0); |
1489 | } | 1493 | } |
1490 | 1494 | ||
@@ -1530,7 +1534,7 @@ static ssize_t bc_num_cmp(BcNum *a, BcNum *b) | |||
1530 | cmp = bc_num_compare(max_num, min_num, b_int + min); | 1534 | cmp = bc_num_compare(max_num, min_num, b_int + min); |
1531 | if (cmp != 0) return BC_NUM_NEG(cmp, (!a_max) != neg); | 1535 | if (cmp != 0) return BC_NUM_NEG(cmp, (!a_max) != neg); |
1532 | 1536 | ||
1533 | for (max_num -= diff, i = diff - 1; !G.signe && i < diff; --i) { | 1537 | for (max_num -= diff, i = diff - 1; !G_interrupt && i < diff; --i) { |
1534 | if (max_num[i]) return BC_NUM_NEG(1, (!a_max) != neg); | 1538 | if (max_num[i]) return BC_NUM_NEG(1, (!a_max) != neg); |
1535 | } | 1539 | } |
1536 | 1540 | ||
@@ -1689,13 +1693,13 @@ static BcStatus bc_num_a(BcNum *a, BcNum *b, BcNum *restrict c, size_t sub) | |||
1689 | ptr = ptr_b; | 1693 | ptr = ptr_b; |
1690 | } | 1694 | } |
1691 | 1695 | ||
1692 | for (carry = 0, i = 0; !G.signe && i < min_rdx + min_int; ++i, ++c->len) { | 1696 | for (carry = 0, i = 0; !G_interrupt && i < min_rdx + min_int; ++i, ++c->len) { |
1693 | in = ((int) ptr_a[i]) + ((int) ptr_b[i]) + carry; | 1697 | in = ((int) ptr_a[i]) + ((int) ptr_b[i]) + carry; |
1694 | carry = in / 10; | 1698 | carry = in / 10; |
1695 | ptr_c[i] = (BcDig)(in % 10); | 1699 | ptr_c[i] = (BcDig)(in % 10); |
1696 | } | 1700 | } |
1697 | 1701 | ||
1698 | for (; !G.signe && i < max + min_rdx; ++i, ++c->len) { | 1702 | for (; !G_interrupt && i < max + min_rdx; ++i, ++c->len) { |
1699 | in = ((int) ptr[i]) + carry; | 1703 | in = ((int) ptr[i]) + carry; |
1700 | carry = in / 10; | 1704 | carry = in / 10; |
1701 | ptr_c[i] = (BcDig)(in % 10); | 1705 | ptr_c[i] = (BcDig)(in % 10); |
@@ -1703,7 +1707,7 @@ static BcStatus bc_num_a(BcNum *a, BcNum *b, BcNum *restrict c, size_t sub) | |||
1703 | 1707 | ||
1704 | if (carry != 0) c->num[c->len++] = (BcDig) carry; | 1708 | if (carry != 0) c->num[c->len++] = (BcDig) carry; |
1705 | 1709 | ||
1706 | return G.signe ? BC_STATUS_EXEC_SIGNAL : BC_STATUS_SUCCESS; | 1710 | return G_interrupt ? BC_STATUS_EXEC_SIGNAL : BC_STATUS_SUCCESS; |
1707 | } | 1711 | } |
1708 | 1712 | ||
1709 | static BcStatus bc_num_s(BcNum *a, BcNum *b, BcNum *restrict c, size_t sub) | 1713 | static BcStatus bc_num_s(BcNum *a, BcNum *b, BcNum *restrict c, size_t sub) |
@@ -1778,7 +1782,7 @@ static BcStatus bc_num_k(BcNum *restrict a, BcNum *restrict b, | |||
1778 | BcNum l1, h1, l2, h2, m2, m1, z0, z1, z2, temp; | 1782 | BcNum l1, h1, l2, h2, m2, m1, z0, z1, z2, temp; |
1779 | bool aone = BC_NUM_ONE(a); | 1783 | bool aone = BC_NUM_ONE(a); |
1780 | 1784 | ||
1781 | if (G.signe) return BC_STATUS_EXEC_SIGNAL; | 1785 | if (G_interrupt) return BC_STATUS_EXEC_SIGNAL; |
1782 | if (a->len == 0 || b->len == 0) { | 1786 | if (a->len == 0 || b->len == 0) { |
1783 | bc_num_zero(c); | 1787 | bc_num_zero(c); |
1784 | return BC_STATUS_SUCCESS; | 1788 | return BC_STATUS_SUCCESS; |
@@ -1796,9 +1800,9 @@ static BcStatus bc_num_k(BcNum *restrict a, BcNum *restrict b, | |||
1796 | memset(c->num, 0, sizeof(BcDig) * c->cap); | 1800 | memset(c->num, 0, sizeof(BcDig) * c->cap); |
1797 | c->len = carry = len = 0; | 1801 | c->len = carry = len = 0; |
1798 | 1802 | ||
1799 | for (i = 0; !G.signe && i < b->len; ++i) { | 1803 | for (i = 0; !G_interrupt && i < b->len; ++i) { |
1800 | 1804 | ||
1801 | for (j = 0; !G.signe && j < a->len; ++j) { | 1805 | for (j = 0; !G_interrupt && j < a->len; ++j) { |
1802 | int in = (int) c->num[i + j]; | 1806 | int in = (int) c->num[i + j]; |
1803 | in += ((int) a->num[j]) * ((int) b->num[i]) + carry; | 1807 | in += ((int) a->num[j]) * ((int) b->num[i]) + carry; |
1804 | carry = in / 10; | 1808 | carry = in / 10; |
@@ -1812,7 +1816,7 @@ static BcStatus bc_num_k(BcNum *restrict a, BcNum *restrict b, | |||
1812 | 1816 | ||
1813 | c->len = len; | 1817 | c->len = len; |
1814 | 1818 | ||
1815 | return G.signe ? BC_STATUS_EXEC_SIGNAL : BC_STATUS_SUCCESS; | 1819 | return G_interrupt ? BC_STATUS_EXEC_SIGNAL : BC_STATUS_SUCCESS; |
1816 | } | 1820 | } |
1817 | 1821 | ||
1818 | bc_num_init(&l1, max); | 1822 | bc_num_init(&l1, max); |
@@ -1962,7 +1966,7 @@ static BcStatus bc_num_d(BcNum *a, BcNum *b, BcNum *restrict c, size_t scale) | |||
1962 | c->len = cp.len; | 1966 | c->len = cp.len; |
1963 | p = b->num; | 1967 | p = b->num; |
1964 | 1968 | ||
1965 | for (i = end - 1; !G.signe && !s && i < end; --i) { | 1969 | for (i = end - 1; !G_interrupt && !s && i < end; --i) { |
1966 | n = cp.num + i; | 1970 | n = cp.num + i; |
1967 | for (q = 0; (!s && n[len] != 0) || bc_num_compare(n, p, len) >= 0; ++q) | 1971 | for (q = 0; (!s && n[len] != 0) || bc_num_compare(n, p, len) >= 0; ++q) |
1968 | s = bc_num_subArrays(n, p, len); | 1972 | s = bc_num_subArrays(n, p, len); |
@@ -2062,20 +2066,20 @@ static BcStatus bc_num_p(BcNum *a, BcNum *b, BcNum *restrict c, size_t scale) | |||
2062 | 2066 | ||
2063 | b->neg = neg; | 2067 | b->neg = neg; |
2064 | 2068 | ||
2065 | for (powrdx = a->rdx; !G.signe && !(pow & 1); pow >>= 1) { | 2069 | for (powrdx = a->rdx; !G_interrupt && !(pow & 1); pow >>= 1) { |
2066 | powrdx <<= 1; | 2070 | powrdx <<= 1; |
2067 | s = bc_num_mul(©, ©, ©, powrdx); | 2071 | s = bc_num_mul(©, ©, ©, powrdx); |
2068 | if (s) goto err; | 2072 | if (s) goto err; |
2069 | } | 2073 | } |
2070 | 2074 | ||
2071 | if (G.signe) { | 2075 | if (G_interrupt) { |
2072 | s = BC_STATUS_EXEC_SIGNAL; | 2076 | s = BC_STATUS_EXEC_SIGNAL; |
2073 | goto err; | 2077 | goto err; |
2074 | } | 2078 | } |
2075 | 2079 | ||
2076 | bc_num_copy(c, ©); | 2080 | bc_num_copy(c, ©); |
2077 | 2081 | ||
2078 | for (resrdx = powrdx, pow >>= 1; !G.signe && pow != 0; pow >>= 1) { | 2082 | for (resrdx = powrdx, pow >>= 1; !G_interrupt && pow != 0; pow >>= 1) { |
2079 | 2083 | ||
2080 | powrdx <<= 1; | 2084 | powrdx <<= 1; |
2081 | s = bc_num_mul(©, ©, ©, powrdx); | 2085 | s = bc_num_mul(©, ©, ©, powrdx); |
@@ -2093,7 +2097,7 @@ static BcStatus bc_num_p(BcNum *a, BcNum *b, BcNum *restrict c, size_t scale) | |||
2093 | if (s) goto err; | 2097 | if (s) goto err; |
2094 | } | 2098 | } |
2095 | 2099 | ||
2096 | if (G.signe) { | 2100 | if (G_interrupt) { |
2097 | s = BC_STATUS_EXEC_SIGNAL; | 2101 | s = BC_STATUS_EXEC_SIGNAL; |
2098 | goto err; | 2102 | goto err; |
2099 | } | 2103 | } |
@@ -2650,7 +2654,7 @@ static BcStatus bc_num_sqrt(BcNum *a, BcNum *restrict b, size_t scale) | |||
2650 | resrdx = scale + 2; | 2654 | resrdx = scale + 2; |
2651 | len = BC_NUM_INT(x0) + resrdx - 1; | 2655 | len = BC_NUM_INT(x0) + resrdx - 1; |
2652 | 2656 | ||
2653 | while (!G.signe && (cmp != 0 || digs < len)) { | 2657 | while (!G_interrupt && (cmp != 0 || digs < len)) { |
2654 | 2658 | ||
2655 | s = bc_num_div(a, x0, &f, resrdx); | 2659 | s = bc_num_div(a, x0, &f, resrdx); |
2656 | if (s) goto err; | 2660 | if (s) goto err; |
@@ -2678,7 +2682,7 @@ static BcStatus bc_num_sqrt(BcNum *a, BcNum *restrict b, size_t scale) | |||
2678 | x1 = temp; | 2682 | x1 = temp; |
2679 | } | 2683 | } |
2680 | 2684 | ||
2681 | if (G.signe) { | 2685 | if (G_interrupt) { |
2682 | s = BC_STATUS_EXEC_SIGNAL; | 2686 | s = BC_STATUS_EXEC_SIGNAL; |
2683 | goto err; | 2687 | goto err; |
2684 | } | 2688 | } |
@@ -4775,7 +4779,7 @@ static BcStatus bc_parse_parse(BcParse *p) | |||
4775 | else | 4779 | else |
4776 | s = bc_parse_stmt(p); | 4780 | s = bc_parse_stmt(p); |
4777 | 4781 | ||
4778 | if ((s && s != BC_STATUS_QUIT && s != BC_STATUS_LIMITS) || G.signe) | 4782 | if ((s && s != BC_STATUS_QUIT && s != BC_STATUS_LIMITS) || G_interrupt) |
4779 | s = bc_parse_reset(p, s); | 4783 | s = bc_parse_reset(p, s); |
4780 | 4784 | ||
4781 | return s; | 4785 | return s; |
@@ -4795,7 +4799,7 @@ static BcStatus bc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next) | |||
4795 | paren_expr = rprn = done = get_token = assign = false; | 4799 | paren_expr = rprn = done = get_token = assign = false; |
4796 | bin_last = true; | 4800 | bin_last = true; |
4797 | 4801 | ||
4798 | for (; !G.signe && !s && !done && bc_parse_exprs[t]; t = p->l.t.t) { | 4802 | for (; !G_interrupt && !s && !done && bc_parse_exprs[t]; t = p->l.t.t) { |
4799 | switch (t) { | 4803 | switch (t) { |
4800 | 4804 | ||
4801 | case BC_LEX_OP_INC: | 4805 | case BC_LEX_OP_INC: |
@@ -4989,7 +4993,7 @@ static BcStatus bc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next) | |||
4989 | } | 4993 | } |
4990 | 4994 | ||
4991 | if (s) return s; | 4995 | if (s) return s; |
4992 | if (G.signe) return BC_STATUS_EXEC_SIGNAL; | 4996 | if (G_interrupt) return BC_STATUS_EXEC_SIGNAL; |
4993 | 4997 | ||
4994 | while (p->ops.len > ops_bgn) { | 4998 | while (p->ops.len > ops_bgn) { |
4995 | 4999 | ||
@@ -5249,7 +5253,7 @@ static BcStatus dc_parse_parse(BcParse *p) | |||
5249 | else | 5253 | else |
5250 | s = dc_parse_expr(p, 0); | 5254 | s = dc_parse_expr(p, 0); |
5251 | 5255 | ||
5252 | if (s || G.signe) s = bc_parse_reset(p, s); | 5256 | if (s || G_interrupt) s = bc_parse_reset(p, s); |
5253 | 5257 | ||
5254 | return s; | 5258 | return s; |
5255 | } | 5259 | } |
@@ -6632,13 +6636,11 @@ static BcStatus bc_program_reset(BcProgram *p, BcStatus s) | |||
6632 | ip = bc_vec_top(&p->stack); | 6636 | ip = bc_vec_top(&p->stack); |
6633 | ip->idx = f->code.len; | 6637 | ip->idx = f->code.len; |
6634 | 6638 | ||
6635 | if (!s && G.signe && !G.tty) return BC_STATUS_QUIT; | 6639 | if (!s && G_interrupt && !G.tty) return BC_STATUS_QUIT; |
6636 | |||
6637 | G.sigc += G.signe; | ||
6638 | G.signe = G.sig != G.sigc; | ||
6639 | 6640 | ||
6640 | if (!s || s == BC_STATUS_EXEC_SIGNAL) { | 6641 | if (!s || s == BC_STATUS_EXEC_SIGNAL) { |
6641 | if (G.ttyin) { | 6642 | if (G.ttyin) { |
6643 | fflush(stdout); | ||
6642 | fputs(bc_program_ready_msg, stderr); | 6644 | fputs(bc_program_ready_msg, stderr); |
6643 | fflush(stderr); | 6645 | fflush(stderr); |
6644 | s = BC_STATUS_SUCCESS; | 6646 | s = BC_STATUS_SUCCESS; |
@@ -6959,7 +6961,7 @@ static BcStatus bc_program_exec(BcProgram *p) | |||
6959 | #endif // ENABLE_DC | 6961 | #endif // ENABLE_DC |
6960 | } | 6962 | } |
6961 | 6963 | ||
6962 | if ((s && s != BC_STATUS_QUIT) || G.signe) s = bc_program_reset(p, s); | 6964 | if ((s && s != BC_STATUS_QUIT) || G_interrupt) s = bc_program_reset(p, s); |
6963 | 6965 | ||
6964 | // If the stack has changed, pointers may be invalid. | 6966 | // If the stack has changed, pointers may be invalid. |
6965 | ip = bc_vec_top(&p->stack); | 6967 | ip = bc_vec_top(&p->stack); |
@@ -6970,19 +6972,6 @@ static BcStatus bc_program_exec(BcProgram *p) | |||
6970 | return s; | 6972 | return s; |
6971 | } | 6973 | } |
6972 | 6974 | ||
6973 | #if ENABLE_FEATURE_BC_SIGNALS | ||
6974 | static void bc_vm_sig(int sig) | ||
6975 | { | ||
6976 | int err = errno; | ||
6977 | size_t len = strlen(G.sig_msg); | ||
6978 | if (sig == SIGINT && write(2, G.sig_msg, len) == (ssize_t) len) { | ||
6979 | G.signe = G.sig == G.sigc; | ||
6980 | G.sig += G.signe; | ||
6981 | } | ||
6982 | errno = err; | ||
6983 | } | ||
6984 | #endif | ||
6985 | |||
6986 | static void bc_vm_info(void) | 6975 | static void bc_vm_info(void) |
6987 | { | 6976 | { |
6988 | printf("%s "BB_VER"\n" | 6977 | printf("%s "BB_VER"\n" |
@@ -7268,21 +7257,17 @@ static void bc_vm_free(void) | |||
7268 | static void bc_vm_init(const char *env_len) | 7257 | static void bc_vm_init(const char *env_len) |
7269 | { | 7258 | { |
7270 | size_t len = bc_vm_envLen(env_len); | 7259 | size_t len = bc_vm_envLen(env_len); |
7271 | #if ENABLE_FEATURE_BC_SIGNALS | ||
7272 | struct sigaction sa; | ||
7273 | 7260 | ||
7274 | sigemptyset(&sa.sa_mask); | 7261 | #if ENABLE_FEATURE_BC_SIGNALS |
7275 | sa.sa_handler = bc_vm_sig; | 7262 | signal_no_SA_RESTART_empty_mask(SIGINT, record_signo); |
7276 | sa.sa_flags = 0; | ||
7277 | sigaction(SIGINT, &sa, NULL); | ||
7278 | #endif | 7263 | #endif |
7279 | 7264 | ||
7280 | bc_vec_init(&G.files, sizeof(char *), NULL); | 7265 | bc_vec_init(&G.files, sizeof(char *), NULL); |
7281 | 7266 | ||
7282 | #if ENABLE_BC | 7267 | if (IS_BC) { |
7283 | G.flags |= BC_FLAG_S * IS_BC * (getenv("POSIXLY_CORRECT") != NULL); | 7268 | G.flags |= BC_FLAG_S * (getenv("POSIXLY_CORRECT") != NULL); |
7284 | if (IS_BC) bc_vm_envArgs(); | 7269 | bc_vm_envArgs(); |
7285 | #endif | 7270 | } |
7286 | 7271 | ||
7287 | bc_program_init(&G.prog, len, G.init, G.exp); | 7272 | bc_program_init(&G.prog, len, G.init, G.exp); |
7288 | G.init(&G.prs, &G.prog, BC_PROG_MAIN); | 7273 | G.init(&G.prs, &G.prog, BC_PROG_MAIN); |
@@ -7311,9 +7296,6 @@ int bc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | |||
7311 | int bc_main(int argc, char **argv) | 7296 | int bc_main(int argc, char **argv) |
7312 | { | 7297 | { |
7313 | INIT_G(); | 7298 | INIT_G(); |
7314 | # if ENABLE_FEATURE_BC_SIGNALS | ||
7315 | G.sig_msg = "\ninterrupt (type \"quit\" to exit)\n"; | ||
7316 | # endif | ||
7317 | G.init = bc_parse_init; | 7299 | G.init = bc_parse_init; |
7318 | G.exp = bc_parse_expression; | 7300 | G.exp = bc_parse_expression; |
7319 | G.sbgn = G.send = '"'; | 7301 | G.sbgn = G.send = '"'; |
@@ -7327,9 +7309,6 @@ int dc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | |||
7327 | int dc_main(int argc, char **argv) | 7309 | int dc_main(int argc, char **argv) |
7328 | { | 7310 | { |
7329 | INIT_G(); | 7311 | INIT_G(); |
7330 | # if ENABLE_FEATURE_BC_SIGNALS | ||
7331 | G.sig_msg = "\ninterrupt (type \"q\" to exit)\n"; | ||
7332 | # endif | ||
7333 | G.init = dc_parse_init; | 7312 | G.init = dc_parse_init; |
7334 | G.exp = dc_parse_expr; | 7313 | G.exp = dc_parse_expr; |
7335 | G.sbgn = '['; | 7314 | G.sbgn = '['; |