]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - include/linux/signal.h
signal/timer/event: signalfd core
[linux-2.6-omap-h63xx.git] / include / linux / signal.h
index 70739f51a09f5fe963c89c8bea9e8c1a3a97e36d..9a5eac508e5e2497b5936e7b6a07166958af52b4 100644 (file)
@@ -1,38 +1,12 @@
 #ifndef _LINUX_SIGNAL_H
 #define _LINUX_SIGNAL_H
 
-#include <linux/list.h>
-#include <linux/spinlock.h>
 #include <asm/signal.h>
 #include <asm/siginfo.h>
 
 #ifdef __KERNEL__
-
-/*
- * These values of sa_flags are used only by the kernel as part of the
- * irq handling routines.
- *
- * SA_INTERRUPT is also used by the irq handling routines.
- * SA_SHIRQ is for shared interrupt support on PCI and EISA.
- * SA_PROBEIRQ is set by callers when they expect sharing mismatches to occur
- */
-#define SA_SAMPLE_RANDOM       SA_RESTART
-#define SA_SHIRQ               0x04000000
-#define SA_PROBEIRQ            0x08000000
-
-/*
- * As above, these correspond to the IORESOURCE_IRQ_* defines in
- * linux/ioport.h to select the interrupt line behaviour.  When
- * requesting an interrupt without specifying a SA_TRIGGER, the
- * setting should be assumed to be "as already configured", which
- * may be as per machine or firmware initialisation.
- */
-#define SA_TRIGGER_LOW         0x00000008
-#define SA_TRIGGER_HIGH                0x00000004
-#define SA_TRIGGER_FALLING     0x00000002
-#define SA_TRIGGER_RISING      0x00000001
-#define SA_TRIGGER_MASK        (SA_TRIGGER_HIGH|SA_TRIGGER_LOW|\
-                                SA_TRIGGER_RISING|SA_TRIGGER_FALLING)
+#include <linux/list.h>
+#include <linux/spinlock.h>
 
 /*
  * Real Time signals may be queued.
@@ -259,6 +233,7 @@ static inline int valid_signal(unsigned long sig)
        return sig <= _NSIG ? 1 : 0;
 }
 
+extern int next_signal(struct sigpending *pending, sigset_t *mask);
 extern int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p);
 extern int __group_send_sig_info(int, struct siginfo *, struct task_struct *);
 extern long do_sigpending(void __user *, unsigned long);
@@ -267,6 +242,133 @@ extern int sigprocmask(int, sigset_t *, sigset_t *);
 struct pt_regs;
 extern int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, struct pt_regs *regs, void *cookie);
 
+extern struct kmem_cache *sighand_cachep;
+
+/*
+ * In POSIX a signal is sent either to a specific thread (Linux task)
+ * or to the process as a whole (Linux thread group).  How the signal
+ * is sent determines whether it's to one thread or the whole group,
+ * which determines which signal mask(s) are involved in blocking it
+ * from being delivered until later.  When the signal is delivered,
+ * either it's caught or ignored by a user handler or it has a default
+ * effect that applies to the whole thread group (POSIX process).
+ *
+ * The possible effects an unblocked signal set to SIG_DFL can have are:
+ *   ignore    - Nothing Happens
+ *   terminate - kill the process, i.e. all threads in the group,
+ *               similar to exit_group.  The group leader (only) reports
+ *               WIFSIGNALED status to its parent.
+ *   coredump  - write a core dump file describing all threads using
+ *               the same mm and then kill all those threads
+ *   stop      - stop all the threads in the group, i.e. TASK_STOPPED state
+ *
+ * SIGKILL and SIGSTOP cannot be caught, blocked, or ignored.
+ * Other signals when not blocked and set to SIG_DFL behaves as follows.
+ * The job control signals also have other special effects.
+ *
+ *     +--------------------+------------------+
+ *     |  POSIX signal      |  default action  |
+ *     +--------------------+------------------+
+ *     |  SIGHUP            |  terminate       |
+ *     |  SIGINT            |  terminate       |
+ *     |  SIGQUIT           |  coredump        |
+ *     |  SIGILL            |  coredump        |
+ *     |  SIGTRAP           |  coredump        |
+ *     |  SIGABRT/SIGIOT    |  coredump        |
+ *     |  SIGBUS            |  coredump        |
+ *     |  SIGFPE            |  coredump        |
+ *     |  SIGKILL           |  terminate(+)    |
+ *     |  SIGUSR1           |  terminate       |
+ *     |  SIGSEGV           |  coredump        |
+ *     |  SIGUSR2           |  terminate       |
+ *     |  SIGPIPE           |  terminate       |
+ *     |  SIGALRM           |  terminate       |
+ *     |  SIGTERM           |  terminate       |
+ *     |  SIGCHLD           |  ignore          |
+ *     |  SIGCONT           |  ignore(*)       |
+ *     |  SIGSTOP           |  stop(*)(+)      |
+ *     |  SIGTSTP           |  stop(*)         |
+ *     |  SIGTTIN           |  stop(*)         |
+ *     |  SIGTTOU           |  stop(*)         |
+ *     |  SIGURG            |  ignore          |
+ *     |  SIGXCPU           |  coredump        |
+ *     |  SIGXFSZ           |  coredump        |
+ *     |  SIGVTALRM         |  terminate       |
+ *     |  SIGPROF           |  terminate       |
+ *     |  SIGPOLL/SIGIO     |  terminate       |
+ *     |  SIGSYS/SIGUNUSED  |  coredump        |
+ *     |  SIGSTKFLT         |  terminate       |
+ *     |  SIGWINCH          |  ignore          |
+ *     |  SIGPWR            |  terminate       |
+ *     |  SIGRTMIN-SIGRTMAX |  terminate       |
+ *     +--------------------+------------------+
+ *     |  non-POSIX signal  |  default action  |
+ *     +--------------------+------------------+
+ *     |  SIGEMT            |  coredump        |
+ *     +--------------------+------------------+
+ *
+ * (+) For SIGKILL and SIGSTOP the action is "always", not just "default".
+ * (*) Special job control effects:
+ * When SIGCONT is sent, it resumes the process (all threads in the group)
+ * from TASK_STOPPED state and also clears any pending/queued stop signals
+ * (any of those marked with "stop(*)").  This happens regardless of blocking,
+ * catching, or ignoring SIGCONT.  When any stop signal is sent, it clears
+ * any pending/queued SIGCONT signals; this happens regardless of blocking,
+ * catching, or ignored the stop signal, though (except for SIGSTOP) the
+ * default action of stopping the process may happen later or never.
+ */
+
+#ifdef SIGEMT
+#define SIGEMT_MASK    rt_sigmask(SIGEMT)
+#else
+#define SIGEMT_MASK    0
+#endif
+
+#if SIGRTMIN > BITS_PER_LONG
+#define rt_sigmask(sig)        (1ULL << ((sig)-1))
+#else
+#define rt_sigmask(sig)        sigmask(sig)
+#endif
+#define siginmask(sig, mask) (rt_sigmask(sig) & (mask))
+
+#define SIG_KERNEL_ONLY_MASK (\
+       rt_sigmask(SIGKILL)   |  rt_sigmask(SIGSTOP))
+
+#define SIG_KERNEL_STOP_MASK (\
+       rt_sigmask(SIGSTOP)   |  rt_sigmask(SIGTSTP)   | \
+       rt_sigmask(SIGTTIN)   |  rt_sigmask(SIGTTOU)   )
+
+#define SIG_KERNEL_COREDUMP_MASK (\
+        rt_sigmask(SIGQUIT)   |  rt_sigmask(SIGILL)    | \
+       rt_sigmask(SIGTRAP)   |  rt_sigmask(SIGABRT)   | \
+        rt_sigmask(SIGFPE)    |  rt_sigmask(SIGSEGV)   | \
+       rt_sigmask(SIGBUS)    |  rt_sigmask(SIGSYS)    | \
+        rt_sigmask(SIGXCPU)   |  rt_sigmask(SIGXFSZ)   | \
+       SIGEMT_MASK                                    )
+
+#define SIG_KERNEL_IGNORE_MASK (\
+        rt_sigmask(SIGCONT)   |  rt_sigmask(SIGCHLD)   | \
+       rt_sigmask(SIGWINCH)  |  rt_sigmask(SIGURG)    )
+
+#define sig_kernel_only(sig) \
+       (((sig) < SIGRTMIN) && siginmask(sig, SIG_KERNEL_ONLY_MASK))
+#define sig_kernel_coredump(sig) \
+       (((sig) < SIGRTMIN) && siginmask(sig, SIG_KERNEL_COREDUMP_MASK))
+#define sig_kernel_ignore(sig) \
+       (((sig) < SIGRTMIN) && siginmask(sig, SIG_KERNEL_IGNORE_MASK))
+#define sig_kernel_stop(sig) \
+       (((sig) < SIGRTMIN) && siginmask(sig, SIG_KERNEL_STOP_MASK))
+
+#define sig_needs_tasklist(sig)        ((sig) == SIGCONT)
+
+#define sig_user_defined(t, signr) \
+       (((t)->sighand->action[(signr)-1].sa.sa_handler != SIG_DFL) &&  \
+        ((t)->sighand->action[(signr)-1].sa.sa_handler != SIG_IGN))
+
+#define sig_fatal(t, signr) \
+       (!siginmask(signr, SIG_KERNEL_IGNORE_MASK|SIG_KERNEL_STOP_MASK) && \
+        (t)->sighand->action[(signr)-1].sa.sa_handler == SIG_DFL)
+
 #endif /* __KERNEL__ */
 
 #endif /* _LINUX_SIGNAL_H */