Seems like it's a small bug in top
.
See source code top.c:
645 /*
646 * Catches:
647 * SIGTSTP, SIGTTIN and SIGTTOU */
648 static void sig_paused (int dont_care_sig) {
661 fflush(stdout);
662 raise(SIGSTOP);
663 // later, after SIGCONT...
664 if (-1 == tcsetattr(STDIN_FILENO, TCSAFLUSH, &Tty_raw))
665 error_exit(fmtmk(N_fmt(FAIL_tty_set_fmt), strerror(errno)));
666 #ifndef RMAN_IGNORED
667 putp(Cap_rmam);
668 #endif
669 if (keypad_xmit) putp(keypad_xmit);
670 putp(Cursor_state);
671 Frames_signal = BREAK_sig;
672 (void)dont_care_sig;
673 } // end: sig_paused
...
3798 // lastly, establish a robust signals environment
3799 memset(&sa, 0, sizeof(sa));
3800 sigemptyset(&sa.sa_mask);
3801 //with user position preserved through SIGWINCH,we must avoid SA_RESTART
3802 sa.sa_flags = 0;
3803 for (i = SIGRTMAX; i; i--) {
3804 switch (i) {
....
3810 case SIGTSTP: case SIGTTIN: case SIGTTOU:
3811 sa.sa_handler = sig_paused;
3812 break;
....
3823 }
3824 sigaction(i, &sa, NULL);
3825 }
This is what happens:
- In line 3810,
top
explicitly registers its SIGTSTP handler sig_paused()
.
- When CTRL-Z is pressed, it sends SIGTSTP to
top -b
.
- When
top
receives SIGTSTP, in sig_paused()
it stops itself by sending SIGSTOP (line 662).
fg
sends SIGCONT to top
and wakes it up.
- In line 664 when
top
is waken up, it puts the tty in raw mode (it should not do this when -b
is specified).
- When the tty is in raw mode, keys like CTRL-C will not generate SIGINT so CTRL-C cannot kill it.