/* * Copyright 2002-2011, Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. */ #ifndef _SIGNAL_H_ #define _SIGNAL_H_ #include 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_ */