sigpending函数返回被阻塞而为调用进程待定的信号。信号集通过set参数返回。
-
#include <signal.h>
-
-
int sigpending(sigset_t *set);
-
- 成功返回0,错误返回-1
下面的代码展示了我们描述过的所有信号的特性。
-
#include <signal.h>
-
-
static void sig_quit(int);
-
-
int
-
main(void)
-
{
-
sigset_t newmask, oldmask, pendmask;
-
-
if (signal(SIGQUIT, sig_quit) == SIG_ERR) {
-
printf("can't catch SIGQUIT");
-
exit(1);
-
}
-
-
/*
-
* Block SIGQUIT and save current signal mask.
-
*/
-
sigemptyset(&newmask);
-
sigaddset(&newmask, SIGQUIT);
-
if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0) {
-
printf("SIG_BLOCK error\n");
-
exit(1);
-
}
-
-
sleep(5); /* SIGQUIT
here will remain pending */
-
if (sigpending(&pendmask) < 0) {
-
printf("sigpending error\n");
-
exit(1);
-
}
-
if (sigismember(&pendmask, SIGQUIT))
-
printf("\nSIGQUIT pending\n");
-
-
/*
-
* Reset signal mask which unblocks SIGQUIT.
-
*/
-
if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0) {
-
printf("SIG_SETMASK error\n");
-
exit(1);
-
}
-
printf("SIGQUIT unblocked\n");
-
-
sleep(5); /* SIGQUIT
here will terminate with core file */
-
exit(0);
-
}
-
-
static void
-
sig_quit(int signo)
-
{
-
printf("caught SIGQUIT\n");
-
if (signal(SIGQUIT, SIG_DFL) == SIG_ERR) {
-
printf("can't reset SIGQUIT\n");
-
exit(1);
-
}
- }
进程阻塞了SIGQUIT,保存它当前的信号掩码(以便稍后重置),然后睡眠5秒。在此期间的任何退出信号的发生都不会被分发,直到信号被反阻塞。在5秒的睡眠后,我们检查信号是否待定并反阻塞这个信号。
注 意我们在阻塞信号前保存了老的掩码。为了反阻塞信号,我们执行了老掩码的SIG_SETMASK。另一种方式,我们可以只SIG_UNBLOCK我们已经 阻塞的信号。然而,要知道如果我们写了一个可以被其他调用的函数,且我们需要在我们的函数里阻塞一个信号,那么我们不能使用SIG_UNBLOCK来反阻 塞这个信号。在这种情况下,我们必须使用SIG_SETMASK并把信号掩码重置为它之前的值,因为调用者在调用我们的函数前可能已经阻塞了这个信号。我 们将在10.18节里的system函数里看到一个这样的例子。
如果我们在睡眠期产生退出信号,那么信号现在是待定而无阻塞的,所以它在sigprocmask返回值被分发。我们将看到这个发生因为信号处理器里的printf在sigprocmask调用后面的printf之前输出。
进程然后又睡了5秒。如果我们在这个睡眠期间产生了退出信号,那么信号应该终止这个进程,因为我们在捕获到它后把这个信号重置到默认值。在下面的输出里,当我们输入终端退出符Control-backslash时终端打印出^\:
$ ./a.out
^\
SIGQUIT pending
caught SIGQUIT
SIGQUIT unblocked
$ ./a.out
^\^\^\^\^\^\^\^\^\^\
SIGQUIT pending
caught SIGQUIT
SIGQUIT unblocked