24df65921b
* Reorganized the kernel locking related to threads and teams. * We now discriminate correctly between process and thread signals. Signal handlers have been moved to teams. Fixes #5679. * Implemented real-time signal support, including signal queuing, SA_SIGINFO support, sigqueue(), sigwaitinfo(), sigtimedwait(), waitid(), and the addition of the real-time signal range. Closes #1935 and #2695. * Gave SIGBUS a separate signal number. Fixes #6704. * Implemented <time.h> clock and timer support, and fixed/completed alarm() and [set]itimer(). Closes #5682. * Implemented support for thread cancellation. Closes #5686. * Moved send_signal() from <signal.h> to <OS.h>. Fixes #7554. * Lots over smaller more or less related changes. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42116 a95241bf-73f2-0310-859d-f6bbb57e9c96
365 lines
12 KiB
C
365 lines
12 KiB
C
/*
|
|
* Copyright 2002-2011, Haiku, Inc. All Rights Reserved.
|
|
* Distributed under the terms of the MIT License.
|
|
*/
|
|
#ifndef _SIGNAL_H_
|
|
#define _SIGNAL_H_
|
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
|
typedef int sig_atomic_t;
|
|
typedef __haiku_uint64 sigset_t;
|
|
|
|
|
|
/* macros defining the standard signal handling behavior */
|
|
#define SIG_DFL ((__sighandler_t)0) /* "default" signal behaviour */
|
|
#define SIG_IGN ((__sighandler_t)1) /* ignore signal */
|
|
#define SIG_ERR ((__sighandler_t)-1) /* an error occurred during signal
|
|
processing */
|
|
#define SIG_HOLD ((__sighandler_t)3) /* the signal was hold */
|
|
|
|
/* macros specifying the event notification type (sigevent::sigev_notify) */
|
|
#define SIGEV_NONE 0 /* no notification */
|
|
#define SIGEV_SIGNAL 1 /* notify via queued signal */
|
|
#define SIGEV_THREAD 2 /* notify via function called in new thread */
|
|
|
|
|
|
union sigval {
|
|
int sival_int;
|
|
void* sival_ptr;
|
|
};
|
|
|
|
struct sigevent {
|
|
int sigev_notify; /* notification type */
|
|
int sigev_signo; /* signal number */
|
|
union sigval sigev_value; /* user-defined signal value */
|
|
void (*sigev_notify_function)(union sigval);
|
|
/* notification function in case of
|
|
SIGEV_THREAD */
|
|
pthread_attr_t* sigev_notify_attributes;
|
|
/* pthread creation attributes in case of
|
|
SIGEV_THREAD */
|
|
};
|
|
|
|
typedef struct __siginfo_t {
|
|
int si_signo; /* signal number */
|
|
int si_code; /* signal code */
|
|
int si_errno; /* if non zero, an error number associated with
|
|
this signal */
|
|
pid_t si_pid; /* sending process ID */
|
|
uid_t si_uid; /* real user ID of sending process */
|
|
void* si_addr; /* address of faulting instruction */
|
|
int si_status; /* exit value or signal */
|
|
long si_band; /* band event for SIGPOLL */
|
|
union sigval si_value; /* signal value */
|
|
} siginfo_t;
|
|
|
|
|
|
/* signal handler function types */
|
|
typedef void (*__sighandler_t)(int);
|
|
typedef void (*__siginfo_handler_t)(int, siginfo_t*, void*);
|
|
|
|
#ifdef __USE_GNU
|
|
typedef __sighandler_t sighandler_t;
|
|
/* GNU-like signal handler typedef */
|
|
#endif
|
|
|
|
|
|
/* structure used by sigaction() */
|
|
struct sigaction {
|
|
union {
|
|
__sighandler_t sa_handler;
|
|
__siginfo_handler_t sa_sigaction;
|
|
};
|
|
sigset_t sa_mask;
|
|
int sa_flags;
|
|
void* sa_userdata; /* will be passed to the signal
|
|
handler, BeOS extension */
|
|
};
|
|
|
|
/* values for sa_flags */
|
|
#define SA_NOCLDSTOP 0x01
|
|
#define SA_NOCLDWAIT 0x02
|
|
#define SA_RESETHAND 0x04
|
|
#define SA_NODEFER 0x08
|
|
#define SA_RESTART 0x10
|
|
#define SA_ONSTACK 0x20
|
|
#define SA_SIGINFO 0x40
|
|
#define SA_NOMASK SA_NODEFER
|
|
#define SA_STACK SA_ONSTACK
|
|
#define SA_ONESHOT SA_RESETHAND
|
|
|
|
/* values for ss_flags */
|
|
#define SS_ONSTACK 0x1
|
|
#define SS_DISABLE 0x2
|
|
|
|
#define MINSIGSTKSZ 4096
|
|
#define SIGSTKSZ 16384
|
|
|
|
/* for signals using an alternate stack */
|
|
typedef struct stack_t {
|
|
void* ss_sp;
|
|
size_t ss_size;
|
|
int ss_flags;
|
|
} stack_t;
|
|
|
|
/* for the 'how' arg of sigprocmask() */
|
|
#define SIG_BLOCK 1
|
|
#define SIG_UNBLOCK 2
|
|
#define SIG_SETMASK 3
|
|
|
|
/*
|
|
* The list of all defined signals:
|
|
*
|
|
* The numbering of signals for Haiku attempts to maintain
|
|
* some consistency with UN*X conventions so that things
|
|
* like "kill -9" do what you expect.
|
|
*/
|
|
#define SIGHUP 1 /* hangup -- tty is gone! */
|
|
#define SIGINT 2 /* interrupt */
|
|
#define SIGQUIT 3 /* `quit' special character typed in tty */
|
|
#define SIGILL 4 /* illegal instruction */
|
|
#define SIGCHLD 5 /* child process exited */
|
|
#define SIGABRT 6 /* abort() called, dont' catch */
|
|
#define SIGPIPE 7 /* write to a pipe w/no readers */
|
|
#define SIGFPE 8 /* floating point exception */
|
|
#define SIGKILL 9 /* kill a team (not catchable) */
|
|
#define SIGSTOP 10 /* suspend a thread (not catchable) */
|
|
#define SIGSEGV 11 /* segmentation violation (read: invalid pointer) */
|
|
#define SIGCONT 12 /* continue execution if suspended */
|
|
#define SIGTSTP 13 /* `stop' special character typed in tty */
|
|
#define SIGALRM 14 /* an alarm has gone off (see alarm()) */
|
|
#define SIGTERM 15 /* termination requested */
|
|
#define SIGTTIN 16 /* read of tty from bg process */
|
|
#define SIGTTOU 17 /* write to tty from bg process */
|
|
#define SIGUSR1 18 /* app defined signal 1 */
|
|
#define SIGUSR2 19 /* app defined signal 2 */
|
|
#define SIGWINCH 20 /* tty window size changed */
|
|
#define SIGKILLTHR 21 /* be specific: kill just the thread, not team */
|
|
#define SIGTRAP 22 /* Trace/breakpoint trap */
|
|
#define SIGPOLL 23 /* Pollable event */
|
|
#define SIGPROF 24 /* Profiling timer expired */
|
|
#define SIGSYS 25 /* Bad system call */
|
|
#define SIGURG 26 /* High bandwidth data is available at socket */
|
|
#define SIGVTALRM 27 /* Virtual timer expired */
|
|
#define SIGXCPU 28 /* CPU time limit exceeded */
|
|
#define SIGXFSZ 29 /* File size limit exceeded */
|
|
#define SIGBUS 30 /* access to undefined portion of a memory object */
|
|
#define SIGRESERVED1 31 /* reserved for future use */
|
|
#define SIGRESERVED2 32 /* reserved for future use */
|
|
|
|
#define SIGRTMIN (__signal_get_sigrtmin())
|
|
/* lowest realtime signal number */
|
|
#define SIGRTMAX (__signal_get_sigrtmax())
|
|
/* greatest realtime signal number */
|
|
|
|
#define __MAX_SIGNO 64 /* greatest possible signal number, can be used (+1)
|
|
as size of static arrays */
|
|
#define NSIG (__MAX_SIGNO + 1)
|
|
/* BSD extension, size of the sys_siglist table,
|
|
obsolete */
|
|
|
|
|
|
/* Signal code values appropriate for siginfo_t::si_code: */
|
|
/* any signal */
|
|
#define SI_USER 0 /* signal sent by user */
|
|
#define SI_QUEUE 1 /* signal sent by sigqueue() */
|
|
#define SI_TIMER 2 /* signal sent on timer_settime() timeout */
|
|
#define SI_ASYNCIO 3 /* signal sent on asynchronous I/O completion */
|
|
#define SI_MESGQ 4 /* signal sent on arrival of message on empty
|
|
message queue */
|
|
/* SIGILL */
|
|
#define ILL_ILLOPC 10 /* illegal opcode */
|
|
#define ILL_ILLOPN 11 /* illegal operand */
|
|
#define ILL_ILLADR 12 /* illegal addressing mode */
|
|
#define ILL_ILLTRP 13 /* illegal trap */
|
|
#define ILL_PRVOPC 14 /* privileged opcode */
|
|
#define ILL_PRVREG 15 /* privileged register */
|
|
#define ILL_COPROC 16 /* coprocessor error */
|
|
#define ILL_BADSTK 17 /* internal stack error */
|
|
/* SIGFPE */
|
|
#define FPE_INTDIV 20 /* integer division by zero */
|
|
#define FPE_INTOVF 21 /* integer overflow */
|
|
#define FPE_FLTDIV 22 /* floating-point division by zero */
|
|
#define FPE_FLTOVF 23 /* floating-point overflow */
|
|
#define FPE_FLTUND 24 /* floating-point underflow */
|
|
#define FPE_FLTRES 25 /* floating-point inexact result */
|
|
#define FPE_FLTINV 26 /* invalid floating-point operation */
|
|
#define FPE_FLTSUB 27 /* subscript out of range */
|
|
/* SIGSEGV */
|
|
#define SEGV_MAPERR 30 /* address not mapped to object */
|
|
#define SEGV_ACCERR 31 /* invalid permissions for mapped object */
|
|
/* SIGBUS */
|
|
#define BUS_ADRALN 40 /* invalid address alignment */
|
|
#define BUS_ADRERR 41 /* nonexistent physical address */
|
|
#define BUS_OBJERR 42 /* object-specific hardware error */
|
|
/* SIGTRAP */
|
|
#define TRAP_BRKPT 50 /* process breakpoint */
|
|
#define TRAP_TRACE 51 /* process trace trap. */
|
|
/* SIGCHLD */
|
|
#define CLD_EXITED 60 /* child exited */
|
|
#define CLD_KILLED 61 /* child terminated abnormally without core dump */
|
|
#define CLD_DUMPED 62 /* child terminated abnormally with core dump */
|
|
#define CLD_TRAPPED 63 /* traced child trapped */
|
|
#define CLD_STOPPED 64 /* child stopped */
|
|
#define CLD_CONTINUED 65 /* stopped child continued */
|
|
/* SIGPOLL */
|
|
#define POLL_IN 70 /* input available */
|
|
#define POLL_OUT 71 /* output available */
|
|
#define POLL_MSG 72 /* input message available */
|
|
#define POLL_ERR 73 /* I/O error */
|
|
#define POLL_PRI 74 /* high priority input available */
|
|
#define POLL_HUP 75 /* device disconnected */
|
|
|
|
|
|
/* the global table of text strings containing descriptions for each signal */
|
|
extern const char* const sys_siglist[NSIG];
|
|
/* BSD extension, obsolete, use strsignal() instead */
|
|
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
|
|
/* signal management (actions and block masks) */
|
|
__sighandler_t signal(int signal, __sighandler_t signalHandler);
|
|
int sigaction(int signal, const struct sigaction* action,
|
|
struct sigaction* oldAction);
|
|
__sighandler_t sigset(int signal, __sighandler_t signalHandler);
|
|
int sigignore(int signal);
|
|
int siginterrupt(int signal, int flag);
|
|
|
|
int sigprocmask(int how, const sigset_t* set, sigset_t* oldSet);
|
|
int pthread_sigmask(int how, const sigset_t* set, sigset_t* oldSet);
|
|
int sighold(int signal);
|
|
int sigrelse(int signal);
|
|
|
|
/* sending signals */
|
|
int raise(int signal);
|
|
int kill(pid_t pid, int signal);
|
|
int killpg(pid_t processGroupID, int signal);
|
|
int sigqueue(pid_t pid, int signal, const union sigval userValue);
|
|
int pthread_kill(pthread_t thread, int signal);
|
|
|
|
/* querying and waiting for signals */
|
|
int sigpending(sigset_t* set);
|
|
int sigsuspend(const sigset_t* mask);
|
|
int sigpause(int signal);
|
|
int sigwait(const sigset_t* set, int* _signal);
|
|
int sigwaitinfo(const sigset_t* set, siginfo_t* info);
|
|
int sigtimedwait(const sigset_t* set, siginfo_t* info,
|
|
const struct timespec* timeout);
|
|
|
|
/* setting the per-thread signal stack */
|
|
int sigaltstack(const stack_t* stack, stack_t* oldStack);
|
|
|
|
/* signal set (sigset_t) manipulation */
|
|
int sigemptyset(sigset_t* set);
|
|
int sigfillset(sigset_t* set);
|
|
int sigaddset(sigset_t* set, int signal);
|
|
int sigdelset(sigset_t* set, int signal);
|
|
int sigismember(const sigset_t* set, int signal);
|
|
|
|
/* printing signal names */
|
|
void psiginfo(const siginfo_t* info, const char* message);
|
|
void psignal(int signal, const char* message);
|
|
|
|
/* implementation private */
|
|
int __signal_get_sigrtmin();
|
|
int __signal_get_sigrtmax();
|
|
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
|
|
/* TODO: move this into the documentation!
|
|
* ==================================================
|
|
* !!! SPECIAL NOTES CONCERNING NON-POSIX EXTENSIONS:
|
|
* ==================================================
|
|
*
|
|
* The standard Posix interface for signal handlers is not as useful
|
|
* as it could be. The handler can define only one single argument
|
|
* (the signal number). For example:
|
|
* void
|
|
* my_signal_handler(int sig)
|
|
* {
|
|
* . . .
|
|
* }
|
|
*
|
|
* // install the handler
|
|
* signal(SIGINT, &my_signal_handler);
|
|
*
|
|
* The sigaction() function allows finer grained control of the signal
|
|
* handling. It also allows an opportunity, via the 'sigaction' struct, to
|
|
* enable additional data to be passed to the handler. For example:
|
|
* void
|
|
* my_signal_handler(int sig, char* userData, vregs* regs)
|
|
* {
|
|
* . . .
|
|
* }
|
|
*
|
|
* struct sigaction sa;
|
|
* char data_buffer[32];
|
|
*
|
|
* sa.sa_handler = (__sighandler_t)my_signal_handler;
|
|
* sigemptyset(&sa.sa_mask);
|
|
* sa.sa_userdata = userData;
|
|
*
|
|
* // install the handler
|
|
* sigaction(SIGINT, &sa, NULL);
|
|
*
|
|
* The two additional arguments available to the signal handler are extensions
|
|
* to the Posix standard. This feature was introduced by the BeOS and retained
|
|
* by Haiku. However, to remain compatible with Posix and ANSI C, the type
|
|
* of the sa_handler field is defined as '__sighandler_t'. This requires the
|
|
* handler to be cast when assigned to the sa_handler field, as in the example
|
|
* above.
|
|
*
|
|
* The 3 arguments that Haiku provides to signal handlers are as follows:
|
|
* 1) The first argument is the (usual) signal number.
|
|
*
|
|
* 2) The second argument is whatever value is put in the sa_userdata field
|
|
* of the sigaction struct.
|
|
*
|
|
* 3) The third argument is a pointer to a vregs struct (defined below).
|
|
* The vregs struct contains the contents of the volatile registers at
|
|
* the time the signal was delivered to your thread. You can change the
|
|
* fields of the structure. After your signal handler completes, the OS uses
|
|
* this struct to reload the registers for your thread (privileged registers
|
|
* are not loaded of course). The vregs struct is of course terribly machine
|
|
* dependent.
|
|
* Note that in BeOS the vregs argument was passed by value, not by pointer.
|
|
* While Haiku retains binary compability with code compiled for BeOS, code
|
|
* built under Haiku must use the pointer argument.
|
|
*/
|
|
|
|
/*
|
|
* the vregs struct:
|
|
*
|
|
* signal handlers get this as the last argument
|
|
*/
|
|
typedef struct vregs vregs;
|
|
/* BeOS extension */
|
|
|
|
|
|
/* include architecture specific definitions */
|
|
#include __HAIKU_ARCH_HEADER(signal.h)
|
|
|
|
|
|
typedef struct vregs mcontext_t;
|
|
|
|
typedef struct __ucontext_t {
|
|
struct __ucontext_t* uc_link;
|
|
sigset_t uc_sigmask;
|
|
stack_t uc_stack;
|
|
mcontext_t uc_mcontext;
|
|
} ucontext_t;
|
|
|
|
|
|
#endif /* _SIGNAL_H_ */
|