* This software has been released under the terms of the IBM Public
* License. For details, see the LICENSE file in the top-level source
* directory or online at http://www.openafs.org/dl/license10.html
+ *
+ * Portions Copyright (c) 2003 Apple Computer, Inc.
*/
-#define _POSIX_PTHREAD_SEMANTICS
+#include <afsconfig.h>
+#include <afs/param.h>
+
#include <afs/param.h>
#include <assert.h>
+#include <stdlib.h>
#include <stdio.h>
#ifndef AFS_NT40_ENV
#include <signal.h>
#include "pthread_nosigs.h"
+/*------------------------------------------------------------------------
+ * Under Darwin 6.x (including 7.0), sigwait() is broken, so we use
+ * sigsuspend() instead. We also don't block signals we don't know
+ * about, so they should kill us, rather than us returning zero status.
+ *------------------------------------------------------------------------*/
+
static pthread_t softsig_tid;
static struct {
void (*handler) (int);
int pending;
+#if !(defined(AFS_DARWIN_ENV) || (defined(AFS_NBSD_ENV) && !defined(AFS_NBSD50_ENV)))
int fatal;
+#endif /* !defined(AFS_DARWIN_ENV) || !defined(AFS_NBSD_ENV) */
int inited;
} softsig_sigs[NSIG];
pthread_sigmask(SIG_BLOCK, &ss, &os);
pthread_sigmask(SIG_SETMASK, &os, NULL);
sigaddset(&ss, SIGUSR1);
+#if defined(AFS_DARWIN_ENV) || (defined(AFS_NBSD_ENV) && !defined(AFS_NBSD50_ENV))
+ pthread_sigmask (SIG_BLOCK, &ss, NULL);
+ sigdelset (&os, SIGUSR1);
+#elif !defined(AFS_HPUX_ENV)
+ /* On HPUX, don't wait for 'critical' signals, as things such as
+ * SEGV won't cause a core, then. Some non-HPUX platforms may need
+ * this, though, since apparently if we wait on some signals but not
+ * e.g. SEGV, the softsig thread will still wait around when the
+ * other threads were killed by the SEGV. */
for (i = 0; i < NSIG; i++) {
if (!sigismember(&os, i) && i != SIGSTOP && i != SIGKILL) {
sigaddset(&ss, i);
softsig_sigs[i].fatal = 1;
}
}
+#endif /* defined(AFS_DARWIN_ENV) || defined(AFS_NBSD_ENV) */
while (1) {
void (*h) (int);
+#if !defined(AFS_DARWIN_ENV) && !defined(AFS_NBSD_ENV)
int sigw;
+#endif
h = NULL;
for (i = 0; i < NSIG; i++) {
if (softsig_sigs[i].handler && !softsig_sigs[i].inited) {
sigaddset(&ss, i);
+#if defined(AFS_DARWIN_ENV) || (defined(AFS_NBSD_ENV) && !defined(AFS_NBSD50_ENV))
+ pthread_sigmask (SIG_BLOCK, &ss, NULL);
+ sigdelset (&os, i);
+#endif /* defined(AFS_DARWIN_ENV) || defined(AFS_NBSD_ENV) */
softsig_sigs[i].inited = 1;
}
if (softsig_sigs[i].pending) {
}
}
if (i == NSIG) {
+#if defined(AFS_DARWIN_ENV) || (defined(AFS_NBSD_ENV) && !defined(AFS_NBSD50_ENV))
+ sigsuspend (&os);
+#else /* !defined(AFS_DARWIN_ENV) && !defined(AFS_NBSD_ENV) */
sigwait(&ss, &sigw);
if (sigw != SIGUSR1) {
if (softsig_sigs[sigw].fatal)
exit(0);
softsig_sigs[sigw].pending = 1;
}
+#endif /* defined(AFS_DARWIN_ENV) || defined(AFS_NBSD_ENV) */
} else if (h)
h(i);
}
+ return NULL;
+}
+
+static void
+softsig_usr1(int signo)
+{
+ signal (SIGUSR1, softsig_usr1);
}
void
-softsig_init()
+softsig_init(void)
{
int rc;
AFS_SIGSET_DECL;
rc = pthread_create(&softsig_tid, NULL, &softsig_thread, NULL);
assert(0 == rc);
AFS_SIGSET_RESTORE();
+ signal (SIGUSR1, softsig_usr1);
}
static void
}
int
-main()
+main(int argc, char **argv)
{
softsig_init();
softsig_signal(SIGINT, print_foo);