2007-08-16 21:05:14 +04:00
|
|
|
/*
|
2009-01-14 16:52:13 +03:00
|
|
|
* Copyright 2002-2009, Haiku, Inc. All Rights Reserved.
|
2007-08-16 21:05:14 +04:00
|
|
|
* Distributed under the terms of the MIT License.
|
|
|
|
*/
|
2002-10-23 21:31:10 +04:00
|
|
|
#ifndef _SIGNAL_H_
|
|
|
|
#define _SIGNAL_H_
|
|
|
|
|
2004-07-07 16:48:27 +04:00
|
|
|
|
2002-10-23 21:31:10 +04:00
|
|
|
#include <sys/types.h>
|
|
|
|
|
|
|
|
|
2004-07-07 16:48:27 +04:00
|
|
|
typedef int sig_atomic_t;
|
2002-11-18 10:24:07 +03:00
|
|
|
typedef long sigset_t;
|
|
|
|
|
2007-08-17 15:01:09 +04:00
|
|
|
typedef void (*sighandler_t)(int);
|
|
|
|
/* GNU-like signal handler typedef */
|
2002-10-23 21:31:10 +04:00
|
|
|
|
2007-08-17 15:01:09 +04:00
|
|
|
typedef void (*__signal_func_ptr)(int);
|
|
|
|
/* deprecated, for compatibility with BeOS only */
|
2002-10-23 21:31:10 +04:00
|
|
|
|
2006-04-21 13:47:43 +04:00
|
|
|
|
2007-08-17 15:01:09 +04:00
|
|
|
/* 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 */
|
2006-04-21 13:47:43 +04:00
|
|
|
|
2008-05-11 01:30:34 +04:00
|
|
|
/* TODO: Support this structure, or more precisely the SA_SIGINFO flag. To do
|
|
|
|
* this properly we need real-time signal support. Both are commented out for
|
|
|
|
* the time being to not make "configure" scripts think we do support them. */
|
2008-03-18 20:33:03 +03:00
|
|
|
#if 0
|
2004-07-07 16:48:27 +04:00
|
|
|
typedef struct {
|
|
|
|
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 */
|
|
|
|
} siginfo_t;
|
2008-03-18 20:33:03 +03:00
|
|
|
#endif /* 0 */
|
2004-07-07 16:48:27 +04:00
|
|
|
|
2002-11-18 10:24:07 +03:00
|
|
|
/*
|
|
|
|
* structure used by sigaction()
|
|
|
|
*
|
2007-08-17 15:01:09 +04:00
|
|
|
* Note: the 'sa_userdata' field is a non-POSIX extension.
|
|
|
|
* See the documentation for more info on this.
|
2002-11-18 10:24:07 +03:00
|
|
|
*/
|
|
|
|
struct sigaction {
|
2007-08-17 15:01:09 +04:00
|
|
|
sighandler_t sa_handler;
|
2004-07-07 16:48:27 +04:00
|
|
|
sigset_t sa_mask;
|
|
|
|
int sa_flags;
|
|
|
|
void *sa_userdata; /* will be passed to the signal handler */
|
2002-11-18 10:24:07 +03:00
|
|
|
};
|
|
|
|
|
2007-08-16 21:05:14 +04:00
|
|
|
/* values for sa_flags */
|
|
|
|
#define SA_NOCLDSTOP 0x01
|
2007-08-17 15:01:09 +04:00
|
|
|
#define SA_NOCLDWAIT 0x02
|
|
|
|
#define SA_RESETHAND 0x04
|
|
|
|
#define SA_NODEFER 0x08
|
|
|
|
#define SA_RESTART 0x10
|
|
|
|
#define SA_ONSTACK 0x20
|
2008-05-11 01:30:34 +04:00
|
|
|
/* #define SA_SIGINFO 0x40 */
|
2007-08-17 15:01:09 +04:00
|
|
|
#define SA_NOMASK SA_NODEFER
|
|
|
|
#define SA_STACK SA_ONSTACK
|
|
|
|
#define SA_ONESHOT SA_RESETHAND
|
2006-04-21 13:47:43 +04:00
|
|
|
|
2007-08-16 21:05:14 +04:00
|
|
|
/* values for ss_flags */
|
|
|
|
#define SS_ONSTACK 0x1
|
|
|
|
#define SS_DISABLE 0x2
|
2002-11-17 07:43:13 +03:00
|
|
|
|
2007-08-16 21:05:14 +04:00
|
|
|
#define MINSIGSTKSZ 4096
|
|
|
|
#define SIGSTKSZ 16384
|
2002-11-17 07:43:13 +03:00
|
|
|
|
2002-10-23 21:31:10 +04:00
|
|
|
/*
|
2002-11-18 10:24:07 +03:00
|
|
|
* for signals using an alternate stack
|
|
|
|
*/
|
|
|
|
typedef struct stack_t {
|
2004-07-07 16:48:27 +04:00
|
|
|
void *ss_sp;
|
|
|
|
size_t ss_size;
|
2007-08-16 21:05:14 +04:00
|
|
|
int ss_flags;
|
2002-11-18 10:24:07 +03:00
|
|
|
} stack_t;
|
|
|
|
|
2006-04-21 13:47:43 +04:00
|
|
|
typedef struct sigstack {
|
|
|
|
int ss_onstack;
|
|
|
|
void *ss_sp;
|
|
|
|
} sigstack;
|
2002-11-18 10:24:07 +03:00
|
|
|
|
2007-08-16 21:05:14 +04:00
|
|
|
/* for the 'how' arg of sigprocmask() */
|
2007-08-17 15:01:09 +04:00
|
|
|
#define SIG_BLOCK 1
|
|
|
|
#define SIG_UNBLOCK 2
|
|
|
|
#define SIG_SETMASK 3
|
2002-11-18 10:24:07 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* The list of all defined signals:
|
|
|
|
*
|
2009-01-14 16:52:13 +03:00
|
|
|
* The numbering of signals for Haiku attempts to maintain
|
|
|
|
* some consistency with UN*X conventions so that things
|
2002-11-17 07:43:13 +03:00
|
|
|
* like "kill -9" do what you expect.
|
2002-11-18 10:24:07 +03:00
|
|
|
*/
|
2005-10-31 15:39:29 +03:00
|
|
|
#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 */
|
2002-10-23 21:31:10 +04:00
|
|
|
|
2007-08-16 21:05:14 +04:00
|
|
|
#define SIGBUS SIGSEGV /* for old style code */
|
2002-11-17 07:43:13 +03:00
|
|
|
|
2002-10-23 21:31:10 +04:00
|
|
|
/*
|
2005-10-31 15:39:29 +03:00
|
|
|
* Signal numbers 30-32 are currently free but may be used in future
|
2002-11-17 07:43:13 +03:00
|
|
|
* releases. Use them at your own peril (if you do use them, at least
|
|
|
|
* be smart and use them backwards from signal 32).
|
|
|
|
*/
|
2007-08-17 15:01:09 +04:00
|
|
|
#define MAX_SIGNO 32 /* the most signals that a single thread can reference */
|
|
|
|
#define __signal_max 29 /* the largest signal number that is actually defined */
|
|
|
|
#define NSIG (__signal_max+1)
|
|
|
|
/* the number of defined signals */
|
2002-10-23 21:31:10 +04:00
|
|
|
|
|
|
|
|
2002-11-18 10:24:07 +03:00
|
|
|
/* the global table of text strings containing descriptions for each signal */
|
|
|
|
extern const char * const sys_siglist[NSIG];
|
2002-10-23 21:31:10 +04:00
|
|
|
|
|
|
|
|
2002-10-26 17:31:22 +04:00
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
2002-10-23 21:31:10 +04:00
|
|
|
|
2007-08-17 15:01:09 +04:00
|
|
|
sighandler_t signal(int sig, sighandler_t signalHandler);
|
2007-11-18 19:39:18 +03:00
|
|
|
sighandler_t sigset(int sig, sighandler_t signalHandler);
|
2006-04-21 13:47:43 +04:00
|
|
|
int raise(int sig);
|
|
|
|
int kill(pid_t pid, int sig);
|
2006-06-16 03:39:15 +04:00
|
|
|
int send_signal(pid_t tid, unsigned int sig);
|
2007-10-24 17:49:42 +04:00
|
|
|
int killpg(pid_t processGroupID, int sig);
|
2006-04-21 13:47:43 +04:00
|
|
|
|
|
|
|
int sigaction(int sig, const struct sigaction *act, struct sigaction *oact);
|
2009-01-14 16:52:13 +03:00
|
|
|
int siginterrupt(int sig, int flag);
|
2006-04-21 13:47:43 +04:00
|
|
|
int sigprocmask(int how, const sigset_t *set, sigset_t *oset);
|
|
|
|
int sigpending(sigset_t *set);
|
|
|
|
int sigsuspend(const sigset_t *mask);
|
|
|
|
int sigwait(const sigset_t *set, int *sig);
|
|
|
|
|
|
|
|
int sigemptyset(sigset_t *set);
|
|
|
|
int sigfillset(sigset_t *set);
|
|
|
|
int sigaddset(sigset_t *set, int signo);
|
|
|
|
int sigdelset(sigset_t *set, int signo);
|
|
|
|
int sigismember(const sigset_t *set, int signo);
|
2007-11-01 21:03:36 +03:00
|
|
|
int sigignore(int signo);
|
2007-11-07 01:11:43 +03:00
|
|
|
int sighold(int signo);
|
2007-11-10 02:23:46 +03:00
|
|
|
int sigrelse(int signo);
|
2008-05-28 19:28:49 +04:00
|
|
|
int sigpause(int signo);
|
2002-11-17 07:43:13 +03:00
|
|
|
|
2002-10-23 21:31:10 +04:00
|
|
|
const char *strsignal(int sig);
|
2002-11-17 07:43:13 +03:00
|
|
|
|
2007-08-16 21:05:14 +04:00
|
|
|
void set_signal_stack(void *ptr, size_t size);
|
|
|
|
int sigaltstack(const stack_t *ss, stack_t *oss);
|
2002-11-17 07:43:13 +03:00
|
|
|
|
2007-08-16 21:05:14 +04:00
|
|
|
/* pthread extension : equivalent of sigprocmask() */
|
2009-01-14 16:52:13 +03:00
|
|
|
int pthread_sigmask(int how, const sigset_t *set, sigset_t *oset);
|
2006-04-21 13:47:43 +04:00
|
|
|
|
2002-11-18 10:24:07 +03:00
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
2002-10-23 21:31:10 +04:00
|
|
|
|
2007-08-17 15:01:09 +04:00
|
|
|
/* TODO: move this into the documentation!
|
2002-11-18 10:24:07 +03:00
|
|
|
* ==================================================
|
|
|
|
* !!! 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);
|
2009-01-14 16:52:13 +03:00
|
|
|
*
|
2002-11-18 10:24:07 +03:00
|
|
|
* 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
|
2007-08-17 15:01:09 +04:00
|
|
|
* my_signal_handler(int sig, char *userData, vregs regs)
|
2002-11-18 10:24:07 +03:00
|
|
|
* {
|
|
|
|
* . . .
|
|
|
|
* }
|
|
|
|
*
|
|
|
|
* struct sigaction sa;
|
|
|
|
* char data_buffer[32];
|
|
|
|
*
|
2007-08-17 15:01:09 +04:00
|
|
|
* sa.sa_handler = (sighandler_t)my_signal_handler;
|
2002-11-18 10:24:07 +03:00
|
|
|
* sigemptyset(&sa.sa_mask);
|
2007-08-17 15:01:09 +04:00
|
|
|
* sa.sa_userdata = userData;
|
2002-11-18 10:24:07 +03:00
|
|
|
*
|
|
|
|
* // 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
|
2007-08-16 21:05:14 +04:00
|
|
|
* by Haiku. However, to remain compatible with Posix and ANSI C, the type
|
2007-08-17 15:01:09 +04:00
|
|
|
* of the sa_handler field is defined as 'sighandler_t'. This requires the handler
|
2002-11-18 10:24:07 +03:00
|
|
|
* to be cast when assigned to the sa_handler field, as in the example above.
|
|
|
|
*
|
2007-08-16 21:05:14 +04:00
|
|
|
* The 3 arguments that Haiku provides to signal handlers are as follows:
|
2007-08-17 15:01:09 +04:00
|
|
|
* 1) The first argument is the (usual) signal number.
|
2002-11-18 10:24:07 +03:00
|
|
|
*
|
2007-08-17 15:01:09 +04:00
|
|
|
* 2) The second argument is whatever value is put in the sa_userdata field
|
2002-11-18 10:24:07 +03:00
|
|
|
* of the sigaction struct.
|
|
|
|
*
|
2007-08-17 15:01:09 +04:00
|
|
|
* 3) The third argument is a pointer to a vregs struct (defined below).
|
2002-11-18 10:24:07 +03:00
|
|
|
* 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.
|
|
|
|
*/
|
2002-10-23 21:31:10 +04:00
|
|
|
|
2002-11-18 10:24:07 +03:00
|
|
|
/*
|
|
|
|
* the vregs struct:
|
|
|
|
*
|
|
|
|
* signal handlers get this as the last argument
|
|
|
|
*/
|
2002-11-17 07:43:13 +03:00
|
|
|
|
2002-10-26 17:31:22 +04:00
|
|
|
typedef struct vregs vregs;
|
|
|
|
|
2008-05-11 01:30:34 +04:00
|
|
|
/* include architecture specific definitions */
|
2007-10-25 04:36:36 +04:00
|
|
|
#ifdef __INTEL__
|
|
|
|
#include <arch/x86/signal.h>
|
|
|
|
#elif __POWERPC__
|
|
|
|
#include <arch/ppc/signal.h>
|
|
|
|
#elif __M68K__
|
|
|
|
#include <arch/m68k/signal.h>
|
|
|
|
#else
|
|
|
|
#error #include <arch/<cpu>/signal.h>
|
|
|
|
#endif
|
|
|
|
|
2002-10-26 17:31:22 +04:00
|
|
|
|
2002-10-23 21:31:10 +04:00
|
|
|
#endif /* _SIGNAL_H_ */
|