12949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/*
22949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Copyright (c) 1997
32949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *	The Regents of the University of California.  All rights reserved.
42949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *
52949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Redistribution and use in source and binary forms, with or without
62949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * modification, are permitted provided that: (1) source code distributions
72949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * retain the above copyright notice and this paragraph in its entirety, (2)
82949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * distributions including binary code include the above copyright notice and
92949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * this paragraph in its entirety in the documentation or other materials
102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * provided with the distribution, and (3) all advertising materials mentioning
112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * features or use of this software display the following acknowledgement:
122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * ``This product includes software developed by the University of California,
132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * the University nor the names of its contributors may be used to endorse
152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * or promote products derived from this software without specific prior
162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * written permission.
172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */
212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef HAVE_CONFIG_H
232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "config.h"
242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif
252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
26e2e3bd11bd7561bc9d6686283a668fa94e1206b7Elliott Hughes#include <netdissect-stdinc.h>
272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <signal.h>
292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef HAVE_SIGACTION
302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <string.h>
312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif
322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef HAVE_OS_PROTO_H
342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "os-proto.h"
352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif
362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "setsignal.h"
382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/*
402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * An OS-independent signal() with, whenever possible, partial BSD
412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * semantics, i.e. the signal handler is restored following service
422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * of the signal, but system calls are *not* restarted, so that if
432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * "pcap_breakloop()" is called in a signal handler in a live capture,
442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * the read/recvfrom/whatever in the live capture doesn't get restarted,
452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * it returns -1 and sets "errno" to EINTR, so we can break out of the
462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * live capture loop.
472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *
482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * We use "sigaction()" if available.  We don't specify that the signal
492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * should restart system calls, so that should always do what we want.
502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *
512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Otherwise, if "sigset()" is available, it probably has BSD semantics
522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * while "signal()" has traditional semantics, so we use "sigset()"; it
532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * might cause system calls to be restarted for the signal, however.
542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * I don't know whether, in any systems where it did cause system calls to
552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * be restarted, there was a way to ask it not to do so; there may no
562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * longer be any interesting systems without "sigaction()", however,
572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * and, if there are, they might have "sigvec()" with SV_INTERRUPT
582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * (which I think first appeared in 4.3BSD).
592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *
602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Otherwise, we use "signal()" - which means we might get traditional
612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * semantics, wherein system calls don't get restarted *but* the
622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * signal handler is reset to SIG_DFL and the signal is not blocked,
632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * so that a subsequent signal would kill the process immediately.
642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *
652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Did I mention that signals suck?  At least in POSIX-compliant systems
662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * they suck far less, as those systems have "sigaction()".
672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */
682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source ProjectRETSIGTYPE
692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project(*setsignal (int sig, RETSIGTYPE (*func)(int)))(int)
702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef HAVE_SIGACTION
722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	struct sigaction old, new;
732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	memset(&new, 0, sizeof(new));
752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	new.sa_handler = func;
7653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (sig == SIGCHLD)
7753f17a9db278d33517d9888dd77848f554522a38JP Abgrall		new.sa_flags = SA_RESTART;
782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (sigaction(sig, &new, &old) < 0)
792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return (SIG_ERR);
802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return (old.sa_handler);
812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#else
832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef HAVE_SIGSET
842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return (sigset(sig, func));
852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#else
862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return (signal(sig, func));
872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif
882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif
892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
91