summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2001-01-18 07:29:29 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2001-01-18 07:29:29 +0000
commit467db1c46ae484ae48a740421c6e177309f4561c (patch)
treeff5d7f29d79235d43ea6d2f81a215e672c642ab0 /usr.bin
parent6dfa5a01a7f1ba39a2993de6f85f61f615c02890 (diff)
remove signal races, using flags
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/top/top.c108
1 files changed, 55 insertions, 53 deletions
diff --git a/usr.bin/top/top.c b/usr.bin/top/top.c
index ac6035207d2..c3bc5fe7fbc 100644
--- a/usr.bin/top/top.c
+++ b/usr.bin/top/top.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: top.c,v 1.6 2000/12/22 22:46:57 deraadt Exp $ */
+/* $OpenBSD: top.c,v 1.7 2001/01/18 07:29:28 deraadt Exp $ */
const char copyright[] = "Copyright (c) 1984 through 1996, William LeFebvre";
@@ -70,6 +70,10 @@ static void tstop __P((int));
static void winch __P((int));
#endif
+sig_atomic_t leaveflag;
+sig_atomic_t tstopflag;
+sig_atomic_t winchflag;
+
static void reset_display __P((void));
/* values which need to be accessed by signal handlers */
@@ -483,12 +487,7 @@ Usage: %s [-ISbinqu] [-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
@@ -626,6 +625,52 @@ Usage: %s [-ISbinqu] [-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)
{
@@ -900,8 +945,7 @@ void leave(unused) /* exit under normal conditions -- INT handler */
int unused;
{
- end_screen();
- exit(0);
+ leaveflag = 1;
}
void tstop(i) /* SIGTSTP handler */
@@ -909,35 +953,7 @@ void tstop(i) /* SIGTSTP handler */
int i;
{
- int save_errno = errno;
-
- /* 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();
-
- errno = save_errno;
-
- /* jump to appropriate place */
- longjmp(jmp_int, 1);
-
- /*NOTREACHED*/
+ tstopflag = 1;
}
#ifdef SIGWINCH
@@ -946,21 +962,7 @@ void winch(i) /* SIGWINCH handler */
int i;
{
- int save_errno = errno;
-
- /* reascertain the screen dimensions */
- get_screensize();
-
- /* tell display to resize */
- max_topn = display_resize();
-
- /* reset the signal handler */
- (void) signal(SIGWINCH, winch);
-
- errno = save_errno;
-
- /* jump to appropriate place */
- longjmp(jmp_int, 1);
+ winchflag = 1;
}
#endif