Signal


参考文献:《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));

。。。

Leave a comment

邮箱地址不会被公开。 必填项已用*标注