突然想起使用sigaction注册信号处理函数时,信号处理函数类型有二个:
struct sigaction
{
void (*sa_handler)(int);
void (*sa_sigaction)(int, siginfo_t *, void *);
sigset_t sa_mask;
int sa_flags;
void (*sa_restorer)(void);
};
通过指定sa_flags为SA_SIGINFO,让系统使用多参数的信号处理函数。在处理函数中,由于传进来一个siginfo_t的参数,我们可以通过它获取到哪个进程传进来的消息。
今天试了下,有点问题,在产生信号时,应当调用注册的信号处理函数,但此时,报出段错误,去除注册信号处理函数那行,一切OK。所以断定系统在调用信号处理函数时发生错误。网上查找相关资料也没有看到原因,故此记下来,继续寻找答案。(注:如果使用sa_handler,完全没有问题)
1 #include <stdlib.h>
2 #include <unistd.h>
3 #include <signal.h>
4 #include <errno.h>
5 #include <string.h>
6 #include <stdio.h>
7 #include <sys/types.h>
8
9 void child_process_exit_handle(int signo,siginfo_t *info, void *context);
10
11 int main(int argc, char **argv)
12 {
13 struct sigaction new_action , old_action;
14 memset(&new_action,0,sizeof(new_action));
15 memset(&old_action,0,sizeof(old_action));
16
17 new_action.sa_sigaction = child_process_exit_handle;
18 sigemptyset(&new_action.sa_mask);
19 new_action.sa_flags = SA_SIGINFO;
20
21 sigaction(SIGCHLD,&new_action,&old_action);
22
23 puts("output before vfork!");
24 pid_t child_pid = fork();
25 if(child_pid < 0)
26 {
27 printf(strerror(errno));
28 return -1;
29 }
30 else if(child_pid == 0)
31 {
32 printf("In the Child Process!\n");
33 _exit(0);
34 }
35 printf("Do nothing!\n");
36 int ch = 0x00;
37 while(ch = getchar(),ch != 'q'){}
38
39 sigaction(SIGCHLD,&old_action,&new_action);
40 return 1;
41 }
42
43 void child_process_exit_handle(int signo, siginfo_t *info, void *context)
44 {
45 int state;
46 printf("child process %d exit!\n",info->si_pid);
47 pid_t pid = waitpid(info->si_pid,&state,0);
48 if(pid < 0 )
49 printf("Wait process exit failured!\n");
50
51 }
52
53