Don't do unsafe activities inside signal handlers. Just set a flag and
return. Obtained from: OpenBSD Reviewed by: audit
This commit is contained in:
parent
b3a1f1765a
commit
26d889d4ff
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=81187
@ -73,6 +73,10 @@ sigret_t tstop();
|
||||
sigret_t winch();
|
||||
#endif
|
||||
|
||||
volatile sig_atomic_t leaveflag;
|
||||
volatile sig_atomic_t tstopflag;
|
||||
volatile sig_atomic_t winchflag;
|
||||
|
||||
/* internal routines */
|
||||
void quit();
|
||||
|
||||
@ -517,12 +521,7 @@ Usage: %s [-ISbinqut] [-d x] [-s x] [-o field] [-U username] [number]\n",
|
||||
fputc('\n', stderr);
|
||||
}
|
||||
|
||||
/* setup the jump buffer for stops */
|
||||
if (setjmp(jmp_int) != 0)
|
||||
{
|
||||
/* control ends up here after an interrupt */
|
||||
reset_display();
|
||||
}
|
||||
restart:
|
||||
|
||||
/*
|
||||
* main loop -- repeat while display count is positive or while it
|
||||
@ -665,6 +664,52 @@ Usage: %s [-ISbinqut] [-d x] [-s x] [-o field] [-U username] [number]\n",
|
||||
timeout.tv_sec = delay;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
if (leaveflag) {
|
||||
end_screen();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (tstopflag) {
|
||||
/* move to the lower left */
|
||||
end_screen();
|
||||
fflush(stdout);
|
||||
|
||||
/* default the signal handler action */
|
||||
(void) signal(SIGTSTP, SIG_DFL);
|
||||
|
||||
/* unblock the signal and send ourselves one */
|
||||
#ifdef SIGRELSE
|
||||
sigrelse(SIGTSTP);
|
||||
#else
|
||||
(void) sigsetmask(sigblock(0) & ~(1 << (SIGTSTP - 1)));
|
||||
#endif
|
||||
(void) kill(0, SIGTSTP);
|
||||
|
||||
/* reset the signal handler */
|
||||
(void) signal(SIGTSTP, tstop);
|
||||
|
||||
/* reinit screen */
|
||||
reinit_screen();
|
||||
reset_display();
|
||||
tstopflag = 0;
|
||||
goto restart;
|
||||
}
|
||||
|
||||
if (winchflag) {
|
||||
/* reascertain the screen dimensions */
|
||||
get_screensize();
|
||||
|
||||
/* tell display to resize */
|
||||
max_topn = display_resize();
|
||||
|
||||
/* reset the signal handler */
|
||||
(void) signal(SIGWINCH, winch);
|
||||
|
||||
reset_display();
|
||||
winchflag = 0;
|
||||
goto restart;
|
||||
}
|
||||
|
||||
/* wait for either input or the end of the delay period */
|
||||
if (select(32, &readfds, (fd_set *)NULL, (fd_set *)NULL, &timeout) > 0)
|
||||
{
|
||||
@ -949,8 +994,7 @@ reset_display()
|
||||
sigret_t leave() /* exit under normal conditions -- INT handler */
|
||||
|
||||
{
|
||||
end_screen();
|
||||
exit(0);
|
||||
leaveflag = 1;
|
||||
}
|
||||
|
||||
sigret_t tstop(i) /* SIGTSTP handler */
|
||||
@ -958,31 +1002,7 @@ sigret_t tstop(i) /* SIGTSTP handler */
|
||||
int i;
|
||||
|
||||
{
|
||||
/* move to the lower left */
|
||||
end_screen();
|
||||
fflush(stdout);
|
||||
|
||||
/* default the signal handler action */
|
||||
(void) signal(SIGTSTP, SIG_DFL);
|
||||
|
||||
/* unblock the signal and send ourselves one */
|
||||
#ifdef SIGRELSE
|
||||
sigrelse(SIGTSTP);
|
||||
#else
|
||||
(void) sigsetmask(sigblock(0) & ~(1 << (SIGTSTP - 1)));
|
||||
#endif
|
||||
(void) kill(0, SIGTSTP);
|
||||
|
||||
/* reset the signal handler */
|
||||
(void) signal(SIGTSTP, tstop);
|
||||
|
||||
/* reinit screen */
|
||||
reinit_screen();
|
||||
|
||||
/* jump to appropriate place */
|
||||
longjmp(jmp_int, 1);
|
||||
|
||||
/*NOTREACHED*/
|
||||
tstopflag = 1;
|
||||
}
|
||||
|
||||
#ifdef SIGWINCH
|
||||
@ -991,17 +1011,7 @@ sigret_t winch(i) /* SIGWINCH handler */
|
||||
int i;
|
||||
|
||||
{
|
||||
/* reascertain the screen dimensions */
|
||||
get_screensize();
|
||||
|
||||
/* tell display to resize */
|
||||
max_topn = display_resize();
|
||||
|
||||
/* reset the signal handler */
|
||||
(void) signal(SIGWINCH, winch);
|
||||
|
||||
/* jump to appropriate place */
|
||||
longjmp(jmp_int, 1);
|
||||
winchflag = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user