参考文献:《UNIX 环境高级编程》
信号是软件中断。很多比较重要的应用程序都需处理信号。信号提供了一种处理异步事件的方法:终端用户键入中断键,则会通过信号机构停止一个程序。
。。。
/* Type of a signal handler. */ typedef void (*__sighandler_t)(int); typedef __sighandler_t sighandler_t; /* Set the handler for the signal SIG to HANDLER, returning the old handler, or SIG_ERR on error. */ extern __sighandler_t signal(int __sig, __sighandler_t __handler) __THROW; /* Send signal SIG to process number PID. If PID is zero, send SIG to all processes in the current process's process group. If PID is < -1, send SIG to all processes in process group - PID. */ extern int kill(__pid_t __pid, int __sig) __THROW; /* Raise signal SIG, i.e., send SIG to yourself. */ extern int raise(int __sig) __THROW;
。。。
/* Fake signal functions. */ #define SIG_ERR ((__sighandler_t) -1) /* Error return. */ #define SIG_DFL ((__sighandler_t) 0) /* Default action. */ #define SIG_IGN ((__sighandler_t) 1) /* Ignore signal. */ /* Signals. */ #define SIGHUP 1 /* Hangup (POSIX). */ #define SIGINT 2 /* Interrupt (ANSI). */ #define SIGQUIT 3 /* Quit (POSIX). */ #define SIGILL 4 /* Illegal instruction (ANSI). */ #define SIGTRAP 5 /* Trace trap (POSIX). */ #define SIGABRT 6 /* Abort (ANSI). */ #define SIGIOT 6 /* IOT trap (4.2 BSD). */ #define SIGBUS 7 /* BUS error (4.2 BSD). */ #define SIGFPE 8 /* Floating-point exception (ANSI). */ #define SIGKILL 9 /* Kill, unblockable (POSIX). */ #define SIGUSR1 10 /* User-defined signal 1 (POSIX). */ #define SIGSEGV 11 /* Segmentation violation (ANSI). */ #define SIGUSR2 12 /* User-defined signal 2 (POSIX). */ #define SIGPIPE 13 /* Broken pipe (POSIX). */ #define SIGALRM 14 /* Alarm clock (POSIX). */ #define SIGTERM 15 /* Termination (ANSI). */ #define SIGSTKFLT 16 /* Stack fault. */ #define SIGCLD SIGCHLD /* Same as SIGCHLD (System V). */ #define SIGCHLD 17 /* Child status has changed (POSIX). */ #define SIGCONT 18 /* Continue (POSIX). */ #define SIGSTOP 19 /* Stop, unblockable (POSIX). */ #define SIGTSTP 20 /* Keyboard stop (POSIX). */ #define SIGTTIN 21 /* Background read from tty (POSIX). */ #define SIGTTOU 22 /* Background write to tty (POSIX). */ #define SIGURG 23 /* Urgent condition on socket (4.2 BSD). */ #define SIGXCPU 24 /* CPU limit exceeded (4.2 BSD). */ #define SIGXFSZ 25 /* File size limit exceeded (4.2 BSD). */ #define SIGVTALRM 26 /* Virtual alarm clock (4.2 BSD). */ #define SIGPROF 27 /* Profiling alarm clock (4.2 BSD). */ #define SIGWINCH 28 /* Window size change (4.3 BSD, Sun). */ #define SIGPOLL SIGIO /* Pollable event occurred (System V). */ #define SIGIO 29 /* I/O now possible (4.2 BSD). */ #define SIGPWR 30 /* Power failure restart (System V). */ #define SIGSYS 31 /* Bad system call. */ #define SIGUNUSED 31
。。。
/* Structure describing the action to be taken when a signal arrives. */ struct sigaction { __sighandler_t sa_handler; /* Signal handler. */ __sigset_t sa_mask; /* Additional set of signals to be blocked. */ int sa_flags; /* Special flags. */ void (*sa_restorer)(void); /* Restore handler. */ };
。。。
typedef __sigset_t sigset_t; /* Clear all signals from SET. */ extern int sigemptyset(sigset_t *__set) __THROW __nonnull ((1)); /* Set all signals in SET. */ extern int sigfillset(sigset_t *__set) __THROW __nonnull ((1)); /* Add SIGNO to SET. */ extern int sigaddset(sigset_t *__set, int __signo) __THROW __nonnull ((1)); /* Remove SIGNO from SET. */ extern int sigdelset(sigset_t *__set, int __signo) __THROW __nonnull ((1)); /* Return 1 if SIGNO is in SET, 0 if not. */ extern int sigismember(const sigset_t *__set, int __signo) __THROW __nonnull ((1)); /* Return non-empty value is SET is not empty. */ extern int sigisemptyset(const sigset_t *__set) __THROW __nonnull ((1)); /* Build new signal set by combining the two inputs set using logical AND. */ extern int sigandset (sigset_t *__set, const sigset_t *__left, const sigset_t *__right) __THROW __nonnull ((1, 2, 3)); /* Build new signal set by combining the two inputs set using logical OR. */ extern int sigorset (sigset_t *__set, const sigset_t *__left, const sigset_t *__right) __THROW __nonnull ((1, 2, 3));
。。。
/* A `sigset_t' has a bit for each signal. */ #define _SIGSET_NWORDS (1024 / (8 * sizeof (unsigned long int))) typedef struct { unsigned long int __val[_SIGSET_NWORDS]; } __sigset_t; #define __sigemptyset(set) \ (__extension__ ({ int __cnt = _SIGSET_NWORDS; \ sigset_t *__set = (set); \ while (--__cnt >= 0) __set->__val[__cnt] = 0; \ 0; })) #define __sigfillset(set) \ (__extension__ ({ int __cnt = _SIGSET_NWORDS; \ sigset_t *__set = (set); \ while (--__cnt >= 0) __set->__val[__cnt] = ~0UL; \ 0; })) #define __sigisemptyset(set) \ (__extension__ ({ int __cnt = _SIGSET_NWORDS; \ const sigset_t *__set = (set); \ int __ret = __set->__val[--__cnt]; \ while (!__ret && --__cnt >= 0) \ __ret = __set->__val[__cnt]; \ __ret == 0; })) #define __sigandset(dest, left, right) \ (__extension__ ({ int __cnt = _SIGSET_NWORDS; \ sigset_t *__dest = (dest); \ const sigset_t *__left = (left); \ const sigset_t *__right = (right); \ while (--__cnt >= 0) \ __dest->__val[__cnt] = (__left->__val[__cnt] & __right->__val[__cnt]); \ 0; })) #define __sigorset(dest, left, right) \ (__extension__ ({ int __cnt = _SIGSET_NWORDS; \ sigset_t *__dest = (dest); \ const sigset_t *__left = (left); \ const sigset_t *__right = (right); \ while (--__cnt >= 0) \ __dest->__val[__cnt] = (__left->__val[__cnt] | __right->__val[__cnt]); \ 0; })) /* Return a mask that includes the bit for SIG only. */ #define __sigmask(sig) (((unsigned long int) 1) << (((sig) - 1) % (8 * sizeof(unsigned long int)))) /* Return the word index for SIG. */ #define __sigword(sig) (((sig) - 1) / (8 * sizeof(unsigned long int))) /* These functions needn't check for a bogus signal number -- error checking is done in the non __ versions. */ extern int __sigismember(const __sigset_t *__set, int __sig) { unsigned long int __mask = __sigmask(__sig); unsigned long int __word = __sigword(__sig); return (__set->__val[__word] & __mask) ? 1 : 0; } extern int __sigaddset(__sigset_t *__set, int __sig) { unsigned long int __mask = __sigmask(__sig); unsigned long int __word = __sigword(__sig); return ((__set->__val[__word] |= __mask), 0); } extern int __sigdelset(__sigset_t *__set, int __sig) { unsigned long int __mask = __sigmask(__sig); unsigned long int __word = __sigword(__sig); return ((__set->__val[__word] &= ~__mask), 0); }
。。。
/* Bits in `sa_flags'. */ #define SA_NOCLDSTOP 1 /* Don't send SIGCHLD when children stop. */ #define SA_NOCLDWAIT 2 /* Don't create zombie on child death. */ #define SA_SIGINFO 4 /* Invoke signal-catching function with three arguments instead of one. */ #if defined __USE_UNIX98 || defined __USE_MISC # define SA_ONSTACK 0x08000000 /* Use signal stack by using `sa_restorer'. */ #endif #if defined __USE_UNIX98 || defined __USE_MISC || defined __USE_XOPEN2K8 # define SA_RESTART 0x10000000 /* Restart syscall on signal return. */ # define SA_NODEFER 0x40000000 /* Don't automatically block the signal when its handler is being executed. */ # define SA_RESETHAND 0x80000000 /* Reset to SIG_DFL on entry to handler. */ #endif #ifdef __USE_MISC # define SA_INTERRUPT 0x20000000 /* Historical no-op. */ /* Some aliases for the SA_ constants. */ # define SA_NOMASK SA_NODEFER # define SA_ONESHOT SA_RESETHAND # define SA_STACK SA_ONSTACK #endif
。。。
/* Values for the HOW argument to `sigprocmask'. */ #define SIG_BLOCK 0 /* Block signals. */ #define SIG_UNBLOCK 1 /* Unblock signals. */ #define SIG_SETMASK 2 /* Set the set of blocked signals. */ /* Get and/or change the set of blocked signals. */ extern int sigprocmask(int __how, const sigset_t *__restrict __set, sigset_t *__restrict __oset) __THROW; /* Change the set of blocked signals to SET, wait until a signal arrives, and restore the set of blocked signals. */ extern int sigsuspend(const sigset_t *__set) __nonnull ((1)); /* Get and/or set the action for signal SIG. */ extern int sigaction(int __sig, const struct sigaction *__restrict __act, struct sigaction *__restrict __oact) __THROW; /* Put in SET all signals that are blocked and waiting to be delivered. */ extern int sigpending(sigset_t *__set) __THROW __nonnull ((1)); /* Select any of pending signals from SET or wait for any to arrive. */ extern int sigwait(const sigset_t *__restrict __set, int *__restrict __sig) __nonnull ((1, 2));
。。。