aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2017-01-11 16:17:59 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2017-01-11 16:17:59 +0100
commit01ccdd1d3c5221789f1ac62ced12b7984d910705 (patch)
treea6eb44f24c1324ddf18bfcec57fd4c3735aa1245
parent8944c67b1f61ca6a51a485772d5d1e6a8ff3d83d (diff)
downloadbusybox-w32-01ccdd1d3c5221789f1ac62ced12b7984d910705.tar.gz
busybox-w32-01ccdd1d3c5221789f1ac62ced12b7984d910705.tar.bz2
busybox-w32-01ccdd1d3c5221789f1ac62ced12b7984d910705.zip
libbb: consolidate the code to set termios unbuffered mode
function old new delta set_termios_to_raw - 116 +116 count_lines 72 74 +2 powertop_main 1458 1430 -28 top_main 943 914 -29 more_main 759 714 -45 fsck_minix_main 2969 2921 -48 conspy_main 1197 1135 -62 rawmode 99 36 -63 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 1/6 up/down: 118/-275) Total: -157 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--editors/vi.c15
-rw-r--r--include/libbb.h4
-rw-r--r--libbb/lineedit.c2
-rw-r--r--libbb/xfuncs.c37
-rw-r--r--loginutils/getty.c2
-rw-r--r--loginutils/vlock.c8
-rw-r--r--miscutils/chat.c1
-rw-r--r--miscutils/conspy.c17
-rw-r--r--miscutils/microcom.c1
-rw-r--r--miscutils/rx.c1
-rw-r--r--procps/powertop.c10
-rw-r--r--procps/top.c10
-rw-r--r--shell/shell_common.c2
-rw-r--r--util-linux/fsck_minix.c6
-rw-r--r--util-linux/more.c10
15 files changed, 71 insertions, 55 deletions
diff --git a/editors/vi.c b/editors/vi.c
index b56b04bdd..1e5ef44fb 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -354,7 +354,7 @@ struct globals {
354#if ENABLE_FEATURE_VI_USE_SIGNALS 354#if ENABLE_FEATURE_VI_USE_SIGNALS
355 sigjmp_buf restart; // catch_sig() 355 sigjmp_buf restart; // catch_sig()
356#endif 356#endif
357 struct termios term_orig, term_vi; // remember what the cooked mode was 357 struct termios term_orig; // remember what the cooked mode was
358#if ENABLE_FEATURE_VI_COLON 358#if ENABLE_FEATURE_VI_COLON
359 char *initial_cmds[3]; // currently 2 entries, NULL terminated 359 char *initial_cmds[3]; // currently 2 entries, NULL terminated
360#endif 360#endif
@@ -462,7 +462,6 @@ struct globals {
462#define context_end (G.context_end ) 462#define context_end (G.context_end )
463#define restart (G.restart ) 463#define restart (G.restart )
464#define term_orig (G.term_orig ) 464#define term_orig (G.term_orig )
465#define term_vi (G.term_vi )
466#define initial_cmds (G.initial_cmds ) 465#define initial_cmds (G.initial_cmds )
467#define readbuffer (G.readbuffer ) 466#define readbuffer (G.readbuffer )
468#define scr_out_buf (G.scr_out_buf ) 467#define scr_out_buf (G.scr_out_buf )
@@ -2731,15 +2730,9 @@ static char *swap_context(char *p) // goto new context for '' command make this
2731//----- Set terminal attributes -------------------------------- 2730//----- Set terminal attributes --------------------------------
2732static void rawmode(void) 2731static void rawmode(void)
2733{ 2732{
2734 tcgetattr(0, &term_orig); 2733 // no TERMIOS_CLEAR_ISIG: leave ISIG on - allow signals
2735 term_vi = term_orig; 2734 set_termios_to_raw(STDIN_FILENO, &term_orig, TERMIOS_RAW_CRNL);
2736 term_vi.c_lflag &= (~ICANON & ~ECHO); // leave ISIG on - allow intr's 2735 erase_char = term_orig.c_cc[VERASE];
2737 term_vi.c_iflag &= (~IXON & ~ICRNL);
2738 term_vi.c_oflag &= (~ONLCR);
2739 term_vi.c_cc[VMIN] = 1;
2740 term_vi.c_cc[VTIME] = 0;
2741 erase_char = term_vi.c_cc[VERASE];
2742 tcsetattr_stdin_TCSANOW(&term_vi);
2743} 2736}
2744 2737
2745static void cookmode(void) 2738static void cookmode(void)
diff --git a/include/libbb.h b/include/libbb.h
index abdc8c2b8..87f89c76d 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -1438,6 +1438,10 @@ int get_terminal_width_height(int fd, unsigned *width, unsigned *height) FAST_FU
1438int get_terminal_width(int fd) FAST_FUNC; 1438int get_terminal_width(int fd) FAST_FUNC;
1439 1439
1440int tcsetattr_stdin_TCSANOW(const struct termios *tp) FAST_FUNC; 1440int tcsetattr_stdin_TCSANOW(const struct termios *tp) FAST_FUNC;
1441#define TERMIOS_CLEAR_ISIG (1 << 0)
1442#define TERMIOS_RAW_CRNL (1 << 1)
1443#define TERMIOS_RAW_INPUT (1 << 2)
1444int set_termios_to_raw(int fd, struct termios *oldterm, int flags) FAST_FUNC;
1441 1445
1442/* NB: "unsigned request" is crucial! "int request" will break some arches! */ 1446/* NB: "unsigned request" is crucial! "int request" will break some arches! */
1443int ioctl_or_perror(int fd, unsigned request, void *argp, const char *fmt,...) __attribute__ ((format (printf, 4, 5))) FAST_FUNC; 1447int ioctl_or_perror(int fd, unsigned request, void *argp, const char *fmt,...) __attribute__ ((format (printf, 4, 5))) FAST_FUNC;
diff --git a/libbb/lineedit.c b/libbb/lineedit.c
index 31e392147..2a5d4e704 100644
--- a/libbb/lineedit.c
+++ b/libbb/lineedit.c
@@ -2325,7 +2325,7 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman
2325 /* ~ECHO, ~ECHONL: turn off echoing, including newline echoing */ 2325 /* ~ECHO, ~ECHONL: turn off echoing, including newline echoing */
2326 /* ~ISIG: turn off INTR (ctrl-C), QUIT, SUSP */ 2326 /* ~ISIG: turn off INTR (ctrl-C), QUIT, SUSP */
2327 new_settings.c_lflag &= ~(ICANON | ECHO | ECHONL | ISIG); 2327 new_settings.c_lflag &= ~(ICANON | ECHO | ECHONL | ISIG);
2328 /* reads would block only if < 1 char is available */ 2328 /* reads will block only if < 1 char is available */
2329 new_settings.c_cc[VMIN] = 1; 2329 new_settings.c_cc[VMIN] = 1;
2330 /* no timeout (reads block forever) */ 2330 /* no timeout (reads block forever) */
2331 new_settings.c_cc[VTIME] = 0; 2331 new_settings.c_cc[VTIME] = 0;
diff --git a/libbb/xfuncs.c b/libbb/xfuncs.c
index 45650edba..98d3531d6 100644
--- a/libbb/xfuncs.c
+++ b/libbb/xfuncs.c
@@ -311,6 +311,43 @@ int FAST_FUNC tcsetattr_stdin_TCSANOW(const struct termios *tp)
311 return tcsetattr(STDIN_FILENO, TCSANOW, tp); 311 return tcsetattr(STDIN_FILENO, TCSANOW, tp);
312} 312}
313 313
314int FAST_FUNC set_termios_to_raw(int fd, struct termios *oldterm, int flags)
315{
316//TODO: lineedit, microcom and less might be adapted to use this too:
317// grep for "tcsetattr"
318
319 struct termios newterm;
320
321 tcgetattr(fd, oldterm);
322 newterm = *oldterm;
323
324 /* Turn off buffered input (ICANON)
325 * Turn off echoing (ECHO)
326 * and separate echoing of newline (ECHONL, normally off anyway)
327 */
328 newterm.c_lflag &= ~(ICANON | ECHO | ECHONL);
329 if (flags & TERMIOS_CLEAR_ISIG) {
330 /* dont recognize INT/QUIT/SUSP chars */
331 newterm.c_lflag &= ~ISIG;
332 }
333 /* reads will block only if < 1 char is available */
334 newterm.c_cc[VMIN] = 1;
335 /* no timeout (reads block forever) */
336 newterm.c_cc[VTIME] = 0;
337 if (flags & TERMIOS_RAW_CRNL) {
338 /* dont convert CR to NL on input */
339 newterm.c_iflag &= ~(IXON | ICRNL);
340 /* dont convert NL to CR on output */
341 newterm.c_oflag &= ~(ONLCR);
342 }
343 if (flags & TERMIOS_RAW_INPUT) {
344 /* dont convert anything on input */
345 newterm.c_iflag &= ~(BRKINT|INLCR|ICRNL|IXON|IXOFF|IUCLC|IXANY|IMAXBEL);
346 }
347
348 return tcsetattr(fd, TCSANOW, &newterm);
349}
350
314pid_t FAST_FUNC safe_waitpid(pid_t pid, int *wstat, int options) 351pid_t FAST_FUNC safe_waitpid(pid_t pid, int *wstat, int options)
315{ 352{
316 pid_t r; 353 pid_t r;
diff --git a/loginutils/getty.c b/loginutils/getty.c
index 162c1697e..ba6c784a3 100644
--- a/loginutils/getty.c
+++ b/loginutils/getty.c
@@ -316,7 +316,7 @@ static void init_tty_attrs(int speed)
316 /* non-raw output; add CR to each NL */ 316 /* non-raw output; add CR to each NL */
317 G.tty_attrs.c_oflag = OPOST | ONLCR; 317 G.tty_attrs.c_oflag = OPOST | ONLCR;
318 318
319 /* reads would block only if < 1 char is available */ 319 /* reads will block only if < 1 char is available */
320 G.tty_attrs.c_cc[VMIN] = 1; 320 G.tty_attrs.c_cc[VMIN] = 1;
321 /* no timeout (reads block forever) */ 321 /* no timeout (reads block forever) */
322 G.tty_attrs.c_cc[VTIME] = 0; 322 G.tty_attrs.c_cc[VTIME] = 0;
diff --git a/loginutils/vlock.c b/loginutils/vlock.c
index 52ae607c9..5ba6a8780 100644
--- a/loginutils/vlock.c
+++ b/loginutils/vlock.c
@@ -105,12 +105,12 @@ int vlock_main(int argc UNUSED_PARAM, char **argv)
105 ioctl(STDIN_FILENO, VT_SETMODE, &vtm); 105 ioctl(STDIN_FILENO, VT_SETMODE, &vtm);
106#endif 106#endif
107 107
108//TODO: use set_termios_to_raw()
108 tcgetattr(STDIN_FILENO, &oterm); 109 tcgetattr(STDIN_FILENO, &oterm);
109 term = oterm; 110 term = oterm;
110 term.c_iflag &= ~BRKINT; 111 term.c_iflag |= IGNBRK; /* ignore serial break (why? VTs don't have breaks, right?) */
111 term.c_iflag |= IGNBRK; 112 term.c_iflag &= ~BRKINT; /* redundant? "dont translate break to SIGINT" */
112 term.c_lflag &= ~ISIG; 113 term.c_lflag &= ~(ISIG | ECHO | ECHOCTL); /* ignore ^C ^Z, echo off */
113 term.c_lflag &= ~(ECHO | ECHOCTL);
114 tcsetattr_stdin_TCSANOW(&term); 114 tcsetattr_stdin_TCSANOW(&term);
115 115
116 while (1) { 116 while (1) {
diff --git a/miscutils/chat.c b/miscutils/chat.c
index dc85f82fb..8df194534 100644
--- a/miscutils/chat.c
+++ b/miscutils/chat.c
@@ -213,6 +213,7 @@ int chat_main(int argc UNUSED_PARAM, char **argv)
213 , signal_handler); 213 , signal_handler);
214 214
215#if ENABLE_FEATURE_CHAT_TTY_HIFI 215#if ENABLE_FEATURE_CHAT_TTY_HIFI
216//TODO: use set_termios_to_raw()
216 tcgetattr(STDIN_FILENO, &tio); 217 tcgetattr(STDIN_FILENO, &tio);
217 tio0 = tio; 218 tio0 = tio;
218 cfmakeraw(&tio); 219 cfmakeraw(&tio);
diff --git a/miscutils/conspy.c b/miscutils/conspy.c
index d9d09d482..1f0278b47 100644
--- a/miscutils/conspy.c
+++ b/miscutils/conspy.c
@@ -363,7 +363,6 @@ int conspy_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
363int conspy_main(int argc UNUSED_PARAM, char **argv) 363int conspy_main(int argc UNUSED_PARAM, char **argv)
364{ 364{
365 char tty_name[sizeof(DEV_TTY "NN")]; 365 char tty_name[sizeof(DEV_TTY "NN")];
366 struct termios termbuf;
367 unsigned opts; 366 unsigned opts;
368 unsigned ttynum; 367 unsigned ttynum;
369 int poll_timeout_ms; 368 int poll_timeout_ms;
@@ -414,16 +413,14 @@ int conspy_main(int argc UNUSED_PARAM, char **argv)
414 413
415 bb_signals(BB_FATAL_SIGS, cleanup); 414 bb_signals(BB_FATAL_SIGS, cleanup);
416 415
417 // All characters must be passed through to us unaltered
418 G.kbd_fd = xopen(CURRENT_TTY, O_RDONLY); 416 G.kbd_fd = xopen(CURRENT_TTY, O_RDONLY);
419 tcgetattr(G.kbd_fd, &G.term_orig); 417
420 termbuf = G.term_orig; 418 // All characters must be passed through to us unaltered
421 termbuf.c_iflag &= ~(BRKINT|INLCR|ICRNL|IXON|IXOFF|IUCLC|IXANY|IMAXBEL); 419 set_termios_to_raw(G.kbd_fd, &G.term_orig, 0
422 //termbuf.c_oflag &= ~(OPOST); - no, we still want \n -> \r\n 420 | TERMIOS_CLEAR_ISIG // no signals on ^C ^Z etc
423 termbuf.c_lflag &= ~(ISIG|ICANON|ECHO); 421 | TERMIOS_RAW_INPUT // turn off all input conversions
424 termbuf.c_cc[VMIN] = 1; 422 );
425 termbuf.c_cc[VTIME] = 0; 423 //Note: termios.c_oflag &= ~(OPOST); - no, we still want \n -> \r\n
426 tcsetattr(G.kbd_fd, TCSANOW, &termbuf);
427 424
428 poll_timeout_ms = 250; 425 poll_timeout_ms = 250;
429 while (1) { 426 while (1) {
diff --git a/miscutils/microcom.c b/miscutils/microcom.c
index 04605d883..5a4bbefa9 100644
--- a/miscutils/microcom.c
+++ b/miscutils/microcom.c
@@ -33,6 +33,7 @@
33// set raw tty mode 33// set raw tty mode
34static void xget1(int fd, struct termios *t, struct termios *oldt) 34static void xget1(int fd, struct termios *t, struct termios *oldt)
35{ 35{
36//TODO: use set_termios_to_raw()
36 tcgetattr(fd, oldt); 37 tcgetattr(fd, oldt);
37 *t = *oldt; 38 *t = *oldt;
38 cfmakeraw(t); 39 cfmakeraw(t);
diff --git a/miscutils/rx.c b/miscutils/rx.c
index 660f66a89..36fc20a72 100644
--- a/miscutils/rx.c
+++ b/miscutils/rx.c
@@ -263,6 +263,7 @@ int rx_main(int argc UNUSED_PARAM, char **argv)
263 263
264 termios_err = tcgetattr(read_fd, &tty); 264 termios_err = tcgetattr(read_fd, &tty);
265 if (termios_err == 0) { 265 if (termios_err == 0) {
266//TODO: use set_termios_to_raw()
266 orig_tty = tty; 267 orig_tty = tty;
267 cfmakeraw(&tty); 268 cfmakeraw(&tty);
268 tcsetattr(read_fd, TCSAFLUSH, &tty); 269 tcsetattr(read_fd, TCSAFLUSH, &tty);
diff --git a/procps/powertop.c b/procps/powertop.c
index ce85f4191..ee806161f 100644
--- a/procps/powertop.c
+++ b/procps/powertop.c
@@ -683,7 +683,6 @@ int powertop_main(int UNUSED_PARAM argc, char UNUSED_PARAM **argv)
683 ullong cur_duration[MAX_CSTATE_COUNT]; 683 ullong cur_duration[MAX_CSTATE_COUNT];
684 char cstate_lines[MAX_CSTATE_COUNT + 2][64]; 684 char cstate_lines[MAX_CSTATE_COUNT + 2][64];
685#if ENABLE_FEATURE_USE_TERMIOS 685#if ENABLE_FEATURE_USE_TERMIOS
686 struct termios new_settings;
687 struct pollfd pfd[1]; 686 struct pollfd pfd[1];
688 687
689 pfd[0].fd = 0; 688 pfd[0].fd = 0;
@@ -707,14 +706,11 @@ int powertop_main(int UNUSED_PARAM argc, char UNUSED_PARAM **argv)
707 puts("Collecting data for "DEFAULT_SLEEP_STR" seconds"); 706 puts("Collecting data for "DEFAULT_SLEEP_STR" seconds");
708 707
709#if ENABLE_FEATURE_USE_TERMIOS 708#if ENABLE_FEATURE_USE_TERMIOS
710 tcgetattr(0, (void *)&G.init_settings); 709 /* Turn on unbuffered input; turn off echoing, ^C ^Z etc */
711 memcpy(&new_settings, &G.init_settings, sizeof(new_settings)); 710 set_termios_to_raw(STDIN_FILENO, &G.init_settings, TERMIOS_CLEAR_ISIG);
712 /* Turn on unbuffered input, turn off echoing */ 711 bb_signals(BB_FATAL_SIGS, sig_handler);
713 new_settings.c_lflag &= ~(ISIG | ICANON | ECHO | ECHONL);
714 /* So we don't forget to reset term settings */ 712 /* So we don't forget to reset term settings */
715 atexit(reset_term); 713 atexit(reset_term);
716 bb_signals(BB_FATAL_SIGS, sig_handler);
717 tcsetattr_stdin_TCSANOW(&new_settings);
718#endif 714#endif
719 715
720 /* Collect initial data */ 716 /* Collect initial data */
diff --git a/procps/top.c b/procps/top.c
index 491acb574..91bb8a883 100644
--- a/procps/top.c
+++ b/procps/top.c
@@ -1089,9 +1089,6 @@ int top_main(int argc UNUSED_PARAM, char **argv)
1089 unsigned interval; 1089 unsigned interval;
1090 char *str_interval, *str_iterations; 1090 char *str_interval, *str_iterations;
1091 unsigned scan_mask = TOP_MASK; 1091 unsigned scan_mask = TOP_MASK;
1092#if ENABLE_FEATURE_USE_TERMIOS
1093 struct termios new_settings;
1094#endif
1095 1092
1096 INIT_G(); 1093 INIT_G();
1097 1094
@@ -1141,11 +1138,8 @@ int top_main(int argc UNUSED_PARAM, char **argv)
1141 } 1138 }
1142#if ENABLE_FEATURE_USE_TERMIOS 1139#if ENABLE_FEATURE_USE_TERMIOS
1143 else { 1140 else {
1144 tcgetattr(0, (void *) &initial_settings); 1141 /* Turn on unbuffered input; turn off echoing, ^C ^Z etc */
1145 memcpy(&new_settings, &initial_settings, sizeof(new_settings)); 1142 set_termios_to_raw(STDIN_FILENO, &initial_settings, TERMIOS_CLEAR_ISIG);
1146 /* unbuffered input, turn off echo */
1147 new_settings.c_lflag &= ~(ISIG | ICANON | ECHO | ECHONL);
1148 tcsetattr_stdin_TCSANOW(&new_settings);
1149 } 1143 }
1150 1144
1151 bb_signals(BB_FATAL_SIGS, sig_catcher); 1145 bb_signals(BB_FATAL_SIGS, sig_catcher);
diff --git a/shell/shell_common.c b/shell/shell_common.c
index 98d862744..549b17ca1 100644
--- a/shell/shell_common.c
+++ b/shell/shell_common.c
@@ -143,7 +143,7 @@ shell_builtin_read(void FAST_FUNC (*setvar)(const char *name, const char *val),
143 // Setting it to more than 1 breaks poll(): 143 // Setting it to more than 1 breaks poll():
144 // it blocks even if there's data. !?? 144 // it blocks even if there's data. !??
145 //tty.c_cc[VMIN] = nchars < 256 ? nchars : 255; 145 //tty.c_cc[VMIN] = nchars < 256 ? nchars : 255;
146 /* reads would block only if < 1 char is available */ 146 /* reads will block only if < 1 char is available */
147 tty.c_cc[VMIN] = 1; 147 tty.c_cc[VMIN] = 1;
148 /* no timeout (reads block forever) */ 148 /* no timeout (reads block forever) */
149 tty.c_cc[VTIME] = 0; 149 tty.c_cc[VTIME] = 0;
diff --git a/util-linux/fsck_minix.c b/util-linux/fsck_minix.c
index 0eaac17c0..2ab7530ea 100644
--- a/util-linux/fsck_minix.c
+++ b/util-linux/fsck_minix.c
@@ -1226,7 +1226,6 @@ void check2(void);
1226int fsck_minix_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 1226int fsck_minix_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
1227int fsck_minix_main(int argc UNUSED_PARAM, char **argv) 1227int fsck_minix_main(int argc UNUSED_PARAM, char **argv)
1228{ 1228{
1229 struct termios tmp;
1230 int retcode = 0; 1229 int retcode = 0;
1231 1230
1232 xfunc_error_retval = 8; 1231 xfunc_error_retval = 8;
@@ -1271,10 +1270,7 @@ int fsck_minix_main(int argc UNUSED_PARAM, char **argv)
1271 read_tables(); 1270 read_tables();
1272 1271
1273 if (OPT_manual) { 1272 if (OPT_manual) {
1274 tcgetattr(0, &sv_termios); 1273 set_termios_to_raw(STDIN_FILENO, &sv_termios, 0);
1275 tmp = sv_termios;
1276 tmp.c_lflag &= ~(ICANON | ECHO);
1277 tcsetattr_stdin_TCSANOW(&tmp);
1278 termios_set = 1; 1274 termios_set = 1;
1279 } 1275 }
1280 1276
diff --git a/util-linux/more.c b/util-linux/more.c
index 7fa60bdba..debad81bd 100644
--- a/util-linux/more.c
+++ b/util-linux/more.c
@@ -43,7 +43,6 @@ struct globals {
43 unsigned terminal_width; 43 unsigned terminal_width;
44 unsigned terminal_height; 44 unsigned terminal_height;
45 struct termios initial_settings; 45 struct termios initial_settings;
46 struct termios new_settings;
47} FIX_ALIASING; 46} FIX_ALIASING;
48#define G (*(struct globals*)bb_common_bufsiz1) 47#define G (*(struct globals*)bb_common_bufsiz1)
49#define INIT_G() do { setup_common_bufsiz(); } while (0) 48#define INIT_G() do { setup_common_bufsiz(); } while (0)
@@ -101,12 +100,9 @@ int more_main(int argc UNUSED_PARAM, char **argv)
101 return bb_cat(argv); 100 return bb_cat(argv);
102 101
103 G.tty_fileno = fileno(tty); 102 G.tty_fileno = fileno(tty);
104 tcgetattr(G.tty_fileno, &G.initial_settings); 103
105 G.new_settings = G.initial_settings; 104 /* Turn on unbuffered input; turn off echoing */
106 G.new_settings.c_lflag &= ~(ICANON | ECHO); 105 set_termios_to_raw(G.tty_fileno, &G.initial_settings, 0);
107 G.new_settings.c_cc[VMIN] = 1;
108 G.new_settings.c_cc[VTIME] = 0;
109 tcsetattr_tty_TCSANOW(&G.new_settings);
110 bb_signals(BB_FATAL_SIGS, gotsig); 106 bb_signals(BB_FATAL_SIGS, gotsig);
111 107
112 do { 108 do {