程序14-6  linux/include/signal.h


  1 #ifndef _SIGNAL_H

  2 #define _SIGNAL_H

  3

  4 #include <sys/types.h>                  // 类型头文件。定义了基本的系统数据类型。

  5

  6 typedef int sig_atomic_t;               // 定义信号原子操作类型。

  7 typedef unsigned int sigset_t;          /* 32 bits */  // 定义信号集类型。

  8

  9 #define _NSIG             32            // 定义信号种类 -- 32 种。

 10 #define NSIG            _NSIG           // NSIG = _NSIG

 11

    // 以下这些是Linux 0.12内核中定义的信号。其中包括了POSIX.1要求的所有20个信号。

 12 #define SIGHUP           1              // Hang Up     -- 挂断控制终端或进程。

 13 #define SIGINT           2              // Interrupt   -- 来自键盘的中断。

 14 #define SIGQUIT          3              // Quit        -- 来自键盘的退出。

 15 #define SIGILL           4              // Illeagle    -- 非法指令。

 16 #define SIGTRAP          5              // Trap        -- 跟踪断点。

 17 #define SIGABRT          6              // Abort       -- 异常结束。

 18 #define SIGIOT           6              // IO Trap     -- 同上。

 19 #define SIGUNUSED        7              // Unused      -- 没有使用。

 20 #define SIGFPE           8              // FPE         -- 协处理器出错。

 21 #define SIGKILL          9              // Kill        -- 强迫进程终止。

 22 #define SIGUSR1         10              // User1       -- 用户信号1,进程可使用。

 23 #define SIGSEGV         11              // Segment Violation -- 无效内存引用。

 24 #define SIGUSR2         12              // User2       -- 用户信号2,进程可使用。

 25 #define SIGPIPE         13              // Pipe        -- 管道写出错,无读者。

 26 #define SIGALRM         14              // Alarm       -- 实时定时器报警。

 27 #define SIGTERM         15              // Terminate   -- 进程终止。

 28 #define SIGSTKFLT       16              // Stack Fault -- 栈出错(协处理器)。

 29 #define SIGCHLD         17              // Child       -- 子进程停止或被终止。

 30 #define SIGCONT         18              // Continue    -- 恢复进程继续执行。

 31 #define SIGSTOP         19              // Stop        -- 停止进程的执行。

 32 #define SIGTSTP         20              // TTY Stop    -- tty发出停止进程,可忽略。

 33 #define SIGTTIN         21              // TTY In      -- 后台进程请求输入。

 34 #define SIGTTOU         22              // TTY Out     -- 后台进程请求输出。

 35

 36 /* Ok, I haven't implemented sigactions, but trying to keep headers POSIX */

    /* OK,我还没有实现sigactions的编制,但在头文件中仍希望遵守POSIX标准 */

    // 上面原注释已经过时,因为在0.12内核中已经实现了sigaction()。下面是sigaction结构

    // sa_flags标志字段可取的符号常数值。

 37 #define SA_NOCLDSTOP    1               // 当子进程处于停止状态,就不对SIGCHLD处理。

 38 #define SA_INTERRUPT    0x20000000      // 系统调用被信号中断后不重新启动系统调用。

 39 #define SA_NOMASK       0x40000000      // 不阻止在指定的信号处理程序中再收到该信号。

 40 #define SA_ONESHOT      0x80000000      // 信号句柄一旦被调用过就恢复到默认处理句柄。

 41

    // 以下常量用于sigprocmask(how, )-- 改变阻塞信号集(屏蔽码)。用于改变该函数的行为。

 42 #define SIG_BLOCK       0  /* for blocking signals */   // 在阻塞信号集中加上给定信号。

 43 #define SIG_UNBLOCK     1  /* for unblocking signals */ // 从阻塞信号集中删除指定信号。

 44 #define SIG_SETMASK     2  /* for setting the signal mask */   // 设置阻塞信号集。

 45

    // 以下两个常数符号都表示指向无返回值的函数指针,且都有一个int整型参数。这两个指针

    // 值是逻辑上讲实际上不可能出现的函数地址值。可作为下面signal函数的第二个参数。用

    // 于告知内核,让内核处理信号或忽略对信号的处理。使用方法参见 kernel/signal.c程序,

    // 94--96行。

 46 #define SIG_DFL         ((void (*)(int))0)      /* default signal handling */

                                                    // 默认信号处理程序(信号句柄)。

 47 #define SIG_IGN         ((void (*)(int))1)      /* ignore signal */

                                                    // 忽略信号的处理程序。

 48 #define SIG_ERR         ((void (*)(int))-1)     /* error return from signal */

                                                    // 信号处理返回错误。

 49

    // 下面定义初始操作设置sigaction结构信号屏蔽码的宏。

 50 #ifdef notdef

 51 #define sigemptyset(mask) ((*(mask) = 0), 1)    // mask清零。

 52 #define sigfillset(mask) ((*(mask) = ~0), 1)    // mask所有比特位置位。

 53 #endif

 54

    // 下面是sigaction的数据结构。

    // sa_handler是对应某信号指定要采取的行动。可以用上面的SIG_DFL,或SIG_IGN来忽略该

    // 信号,也可以是指向处理该信号函数的一个指针。

    // sa_mask给出了对信号的屏蔽码,在信号程序执行时将阻塞对这些信号的处理。

// sa_flags指定改变信号处理过程的信号集。它是由37-40行的位标志定义的。

// sa_restorer是恢复函数指针,由函数库Libc提供,用于清理用户态堆栈。参见signal.c

    // 另外,引起触发信号处理的信号也将被阻塞,除非使用了SA_NOMASK标志。

 55 struct sigaction {

 56         void (*sa_handler)(int);

 57         sigset_t sa_mask;

 58         int sa_flags;

 59         void (*sa_restorer)(void);

 60 };

 61

    // 下面signal函数用于是为信号_sig安装一新的信号处理程序(信号句柄),与sigaction()

    // 类似。该函数含有两个参数:指定需要捕获的信号_sig;具有一个参数且无返回值的函数指针

    // _func。该函数返回值也是具有一个int参数(最后一个(int))且无返回值的函数指针,它是

    // 处理该信号的原处理句柄。

 62 void (*signal(int _sig, void (*_func)(int)))(int);

    // 下面两函数用于发送信号。kill() 用于向任何进程或进程组发送信号。raise()用于向当前进

    // 程自身发送信号。其作用等价于kill(getpid(),sig)。参见kernel/exit.c60行。

 63 int raise(int sig);

 64 int kill(pid_t pid, int sig);

    // 在进程的任务结构中,除有一个以比特位表示当前进程待处理的32位信号字段signal以外,

    // 还有一个同样以比特位表示的用于屏蔽进程当前阻塞信号集(屏蔽信号集)的字段blocked

    // 也是32位,每个比特代表一个对应的阻塞信号。修改进程的屏蔽信号集可以阻塞或解除阻塞

    // 所指定的信号。 以下五个函数就是用于操作进程屏蔽信号集,虽然简单实现起来很简单,但

    // 本版本内核中还未实现。

    // 函数sigaddset() sigdelset() 用于对信号集中的信号进行增、删修改。 sigaddset()

    // 于向mask指向的信号集中增加指定的信号signosigdelset则反之。函数sigemptyset()

    // sigfillset() 用于初始化进程屏蔽信号集。 每个程序在使用信号集前,都需要使用这两个函

    // 数之一对屏蔽信号集进行初始化。 sigemptyset()用于清空屏蔽的所有信号,也即响应所有的

    // 信号。sigfillset()向信号集中置入所有信号,也即屏蔽所有信号。当然 SIGINTSIGSTOP

    // 是不能被屏蔽的。

    // sigismember()用于测试一个指定信号是否在信号集中(1 - 是,0 - 不是,-1 - 出错)。

 65 int sigaddset(sigset_t *mask, int signo);

 66 int sigdelset(sigset_t *mask, int signo);

 67 int sigemptyset(sigset_t *mask);

 68 int sigfillset(sigset_t *mask);

 69 int sigismember(sigset_t *mask, int signo); /* 1 - is, 0 - not, -1 error */

    // set中的信号进行检测,看是否有挂起的信号。在set中返回进程中当前被阻塞的信号集。

 70 int sigpending(sigset_t *set);

    // 下面函数用于改变进程目前被阻塞的信号集(信号屏蔽码)。若oldset不是NULL,则通过其

    // 返回进程当前屏蔽信号集。若set指针不是NULL,则根据how41-43行)指示修改进程屏蔽

    // 信号集。

 71 int sigprocmask(int how, sigset_t *set, sigset_t *oldset);

    // 下面函数用 sigmask 临时替换进程的信号屏蔽码,然后暂停该进程直到收到一个信号。若捕捉

    // 到某一信号并从该信号处理程序中返回,则该函数也返回,并且信号屏蔽码会恢复到调用调用

    // 前的值。

 72 int sigsuspend(sigset_t *sigmask);

    // sigaction() 函数用于改变进程在收到指定信号时所采取的行动,即改变信号的处理句柄能。

    // 参见对kernel/signal.c程序的说明。

 73 int sigaction(int sig, struct sigaction *act, struct sigaction *oldact);

 74

 75 #endif /* _SIGNAL_H */

 76