summaryrefslogtreecommitdiffstats
path: root/contrib/top
diff options
context:
space:
mode:
authorkris <kris@FreeBSD.org>2001-08-06 03:19:22 +0000
committerkris <kris@FreeBSD.org>2001-08-06 03:19:22 +0000
commitfbb6cc445422ee11280f71a645ea26345adf7a35 (patch)
tree9ff543f73d18548a534afce0d2c440ca91b69c83 /contrib/top
parenta4c9d3930da86ce541eba1b03a73d8a019737ed8 (diff)
downloadFreeBSD-src-fbb6cc445422ee11280f71a645ea26345adf7a35.zip
FreeBSD-src-fbb6cc445422ee11280f71a645ea26345adf7a35.tar.gz
Don't do unsafe activities inside signal handlers. Just set a flag and
return. Obtained from: OpenBSD Reviewed by: audit
Diffstat (limited to 'contrib/top')
-rw-r--r--contrib/top/top.c98
1 files changed, 54 insertions, 44 deletions
diff --git a/contrib/top/top.c b/contrib/top/top.c
index 94a02f2..ef1d47f 100644
--- a/contrib/top/top.c
+++ b/contrib/top/top.c
@@ -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
OpenPOWER on IntegriCloud