diff options
author | moritz <moritz@openbsd.org> | 2005-05-22 18:41:33 +0000 |
---|---|---|
committer | moritz <moritz@openbsd.org> | 2005-05-22 18:41:33 +0000 |
commit | 05e0bb15959592f20a5ae2040aed3f3e50d5ba18 (patch) | |
tree | 44ce132d151c852db56a4014a2888f27b12b9676 /usr.sbin/tcpdump/tcpdump.c | |
parent | no need to search for the kif before callig pf_get_kif, it does that for us (diff) | |
download | wireguard-openbsd-05e0bb15959592f20a5ae2040aed3f3e50d5ba18.tar.xz wireguard-openbsd-05e0bb15959592f20a5ae2040aed3f3e50d5ba18.zip |
fix signal race in statistics output. ok cloder@ henning@
Diffstat (limited to 'usr.sbin/tcpdump/tcpdump.c')
-rw-r--r-- | usr.sbin/tcpdump/tcpdump.c | 38 |
1 files changed, 32 insertions, 6 deletions
diff --git a/usr.sbin/tcpdump/tcpdump.c b/usr.sbin/tcpdump/tcpdump.c index 7b33e9ac6ed..cf6f18e62c1 100644 --- a/usr.sbin/tcpdump/tcpdump.c +++ b/usr.sbin/tcpdump/tcpdump.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcpdump.c,v 1.44 2005/03/30 22:13:54 moritz Exp $ */ +/* $OpenBSD: tcpdump.c,v 1.45 2005/05/22 18:41:34 moritz Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 @@ -26,7 +26,7 @@ static const char copyright[] = "@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997\n\ The Regents of the University of California. All rights reserved.\n"; static const char rcsid[] = - "@(#) $Header: /home/cvs/src/usr.sbin/tcpdump/tcpdump.c,v 1.44 2005/03/30 22:13:54 moritz Exp $ (LBL)"; + "@(#) $Header: /home/cvs/src/usr.sbin/tcpdump/tcpdump.c,v 1.45 2005/05/22 18:41:34 moritz Exp $ (LBL)"; #endif /* @@ -40,6 +40,7 @@ static const char rcsid[] = #include <sys/types.h> #include <sys/time.h> #include <sys/ioctl.h> +#include <sys/wait.h> #include <netinet/in.h> @@ -51,6 +52,7 @@ static const char rcsid[] = #include <unistd.h> #include <ctype.h> #include <err.h> +#include <errno.h> #include "interface.h" #include "addrtoname.h" @@ -89,12 +91,15 @@ char *program_name; int32_t thiszone; /* seconds offset from gmt to local time */ +extern volatile pid_t child_pid; + /* Externs */ extern void bpf_dump(struct bpf_program *, int); extern int esp_init(char *); /* Forwards */ RETSIGTYPE cleanup(int); +RETSIGTYPE gotchld(int); extern __dead void usage(void); /* Length of saved portion of packet. */ @@ -508,6 +513,7 @@ main(int argc, char **argv) setsignal(SIGTERM, cleanup); setsignal(SIGINT, cleanup); + setsignal(SIGCHLD, gotchld); /* Cooperate with nohup(1) XXX is this still necessary/working? */ if ((oldhandler = setsignal(SIGHUP, cleanup)) != SIG_DFL) (void)setsignal(SIGHUP, oldhandler); @@ -559,14 +565,15 @@ RETSIGTYPE cleanup(int signo) { struct pcap_stat stat; + sigset_t allsigs; char buf[1024]; + sigfillset(&allsigs); + sigprocmask(SIG_BLOCK, &allsigs, NULL); + /* Can't print the summary if reading from a savefile */ + (void)write(STDERR_FILENO, "\n", 1); if (pd != NULL && pcap_file(pd) == NULL) { -#if 0 - (void)fflush(stdout); /* XXX unsafe */ -#endif - (void)write(STDERR_FILENO, "\n", 1); if (pcap_stats(pd, &stat) < 0) { (void)snprintf(buf, sizeof buf, "pcap_stats: %s\n", pcap_geterr(pd)); @@ -583,6 +590,25 @@ cleanup(int signo) _exit(0); } +RETSIGTYPE +gotchld(int signo) +{ + pid_t pid; + int status; + int save_err = errno; + + do { + pid = waitpid(child_pid, &status, WNOHANG); + if (pid > 0 && (WIFEXITED(status) || WIFSIGNALED(status))) + cleanup(0); + } while (pid == -1 && errno == EINTR); + + if (pid == -1) + _exit(1); + + errno = save_err; +} + /* dump the buffer in `emacs-hexl' style */ void default_print_hexl(const u_char *cp, unsigned int length, unsigned int offset) |