summaryrefslogtreecommitdiffstats
path: root/usr.sbin/tcpdump/tcpdump.c
diff options
context:
space:
mode:
authormoritz <moritz@openbsd.org>2005-05-22 18:41:33 +0000
committermoritz <moritz@openbsd.org>2005-05-22 18:41:33 +0000
commit05e0bb15959592f20a5ae2040aed3f3e50d5ba18 (patch)
tree44ce132d151c852db56a4014a2888f27b12b9676 /usr.sbin/tcpdump/tcpdump.c
parentno need to search for the kif before callig pf_get_kif, it does that for us (diff)
downloadwireguard-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.c38
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)