I suspect I haven't gone far enough.

Simplify and correct signal handling in tcpdump:
 * RETSIGTYPE == void, so kill the define for it
 * simplify and strengthen setsignal():
   * we have sigaction(), so use it
   * in general, CLI tools shouldn't catch a signal that was ignored on 
     entry.  Enforce that here, which eliminates the need to return the
     previous signal disposition
   * for SIGCHLD, use SA_NOCLDSTOP to avoid superfluous signals if the
     child is stopped
 * with setsignal() Doing The Right Thing, set_slave_signals() is *really* 
   simple

As I understand it, we're not tracking upstream tcpdump, so I don't think 
this is a (new) hinderance for merges.

ok?

Philip Guenther


PS: on OpenBSD, execve(2) resets SIGCHLD to SIG_DFL if it was set to 
SIG_IGN.  Doing otherwise breaks lots of programs, so it's explicitly 
permitted by POSIX...but we don't seem to document that.  Expect a manpage 
diff after this...


Index: Makefile
===================================================================
RCS file: /data/src/openbsd/src/usr.sbin/tcpdump/Makefile,v
retrieving revision 1.57
diff -u -p -r1.57 Makefile
--- Makefile    10 Oct 2015 07:52:30 -0000      1.57
+++ Makefile    11 Oct 2015 05:21:58 -0000
@@ -28,7 +28,7 @@ CFLAGS+=-Wall -I${.CURDIR}/../../sbin/pf
 # for pcap-int.h
 CFLAGS+=-I${.CURDIR}/../../lib/libpcap
 
-CFLAGS+=-DCSLIP -DPPP -DHAVE_FDDI -DETHER_SERVICE -DRETSIGTYPE=void 
-DHAVE_NET_SLIP_H -DHAVE_ETHER_NTOHOST -DINET6
+CFLAGS+=-DCSLIP -DPPP -DHAVE_FDDI -DETHER_SERVICE -DHAVE_NET_SLIP_H 
-DHAVE_ETHER_NTOHOST -DINET6
 
 LDADD+=        -lpcap -ll -lcrypto -lm
 DPADD+=        ${LIBL} ${LIBPCAP} ${LIBCRYPTO}
Index: setsignal.c
===================================================================
RCS file: /data/src/openbsd/src/usr.sbin/tcpdump/setsignal.c,v
retrieving revision 1.5
diff -u -p -r1.5 setsignal.c
--- setsignal.c 5 Apr 2015 17:02:57 -0000       1.5
+++ setsignal.c 11 Oct 2015 05:47:35 -0000
@@ -23,52 +23,23 @@
 
 #include <sys/types.h>
 
-#ifdef HAVE_MEMORY_H
-#include <memory.h>
-#endif
 #include <signal.h>
-#ifdef HAVE_SIGACTION
 #include <string.h>
-#endif
-
-#ifdef HAVE_OS_PROTO_H
-#include "os-proto.h"
-#endif
 
 #include "setsignal.h"
 
-/*
- * An os independent signal() with BSD semantics, e.g. the signal
- * catcher is restored following service of the signal.
- *
- * When sigset() is available, signal() has SYSV semantics and sigset()
- * has BSD semantics and call interface. Unfortunately, Linux does not
- * have sigset() so we use the more complicated sigaction() interface
- * there.
- *
- * Did I mention that signals suck?
- */
-RETSIGTYPE
-(*setsignal (int sig, RETSIGTYPE (*func)(int)))(int)
+void
+setsignal(int sig, void (*func)(int))
 {
-#ifdef HAVE_SIGACTION
-       struct sigaction old, new;
-
-       memset(&new, 0, sizeof(new));
-       new.sa_handler = func;
-#ifdef SA_RESTART
-       new.sa_flags |= SA_RESTART;
-#endif
-       if (sigaction(sig, &new, &old) < 0)
-               return (SIG_ERR);
-       return (old.sa_handler);
+       struct sigaction sa;
 
-#else
-#ifdef HAVE_SIGSET
-       return (sigset(sig, func));
-#else
-       return (signal(sig, func));
-#endif
-#endif
+       if (sigaction(sig, NULL, &sa) == 0 && sa.sa_handler != SIG_IGN) {
+               sa.sa_handler = func;
+               sa.sa_flags = SA_RESTART;
+               if (sig == SIGCHLD)
+                       sa.sa_flags |= SA_NOCLDSTOP;
+               sigemptyset(&sa.sa_mask);
+               sigaction(sig, &sa, NULL);
+       }
 }
 
Index: setsignal.h
===================================================================
RCS file: /data/src/openbsd/src/usr.sbin/tcpdump/setsignal.h,v
retrieving revision 1.3
diff -u -p -r1.3 setsignal.h
--- setsignal.h 7 Oct 2007 16:41:05 -0000       1.3
+++ setsignal.h 11 Oct 2015 05:21:02 -0000
@@ -25,5 +25,5 @@
 #ifndef setsignal_h
 #define setsignal_h
 
-RETSIGTYPE (*setsignal(int, RETSIGTYPE (*)(int)))(int);
+void   setsignal(int, void (*)(int));
 #endif
Index: tcpdump.c
===================================================================
RCS file: /data/src/openbsd/src/usr.sbin/tcpdump/tcpdump.c,v
retrieving revision 1.74
diff -u -p -r1.74 tcpdump.c
--- tcpdump.c   9 Oct 2015 01:37:09 -0000       1.74
+++ tcpdump.c   11 Oct 2015 05:48:13 -0000
@@ -92,8 +92,8 @@ extern void bpf_dump(struct bpf_program 
 extern int esp_init(char *);
 
 /* Forwards */
-RETSIGTYPE cleanup(int);
-RETSIGTYPE gotchld(int);
+void   cleanup(int);
+void   gotchld(int);
 extern __dead void usage(void);
 
 /* Length of saved portion of packet. */
@@ -503,8 +503,7 @@ main(int argc, char **argv)
 }
 
 /* make a clean exit on interrupts */
-/* ARGSUSED */
-RETSIGTYPE
+void
 cleanup(int signo)
 {
        struct pcap_stat stat;
@@ -533,8 +532,7 @@ cleanup(int signo)
        _exit(0);
 }
 
-/* ARGSUSED */
-RETSIGTYPE
+void
 gotchld(int signo)
 {
        pid_t pid;
@@ -681,14 +679,10 @@ default_print(register const u_char *bp,
 void
 set_slave_signals(void)
 {
-       RETSIGTYPE (*oldhandler)(int);
-
        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);
+       setsignal(SIGHUP, cleanup);
 }
 
 __dead void

Reply via email to