Linux --sigaction举例(改变信号默认操作)

环境 -- ubuntu64位
  1. 部分内核宏及函数对照
    /*signal number*/
    #define SIGHUP       1
    #define SIGINT       2
    #define SIGQUIT      3
    #define SIGILL       4
    #define SIGTRAP      5
    #define SIGABRT      6
    #define SIGIOT       6
    #define SIGBUS       7       
    #define SIGFPE       8
    #define SIGKILL      9
    #define SIGUSR1     10
    #define SIGSEGV     11
    #define SIGUSR2     12
    #define SIGPIPE     13
    #define SIGALRM     14
    #define SIGTERM     15
    #define SIGSTKFLT   16
    #define SIGCHLD     17
    #define SIGCONT     18
    #define SIGSTOP     19
    #define SIGTSTP     20
    #define SIGTTIN     21
    #define SIGTTOU     22
    #define SIGURG      23
    #define SIGXCPU     24
    #define SIGXFSZ     25
    #define SIGVTALRM   26
    #define SIGPROF     27
    #define SIGWINCH    28
    #define SIGIO       29
    #define SIGPOLL     SIGIO
    /*
    #define SIGLOST     29
    */
    #define SIGPWR      30
    #define SIGSYS      31
    #define SIGUNUSED   31
    /* 这些不应该被考虑 */
    #define SIGRTMIN    32
    #ifndef SIGRTMAX
    #define SIGRTMAX    _NSIG
    #endif
    
    /*int sa_flags*/
    #define SA_NOCLDSTOP    0x00000001
    #define SA_NOCLDWAIT    0x00000002
    #define SA_SIGINFO  0x00000004
    #define SA_ONSTACK  0x08000000
    #define SA_RESTART  0x10000000
    #define SA_NODEFER  0x40000000
    #define SA_RESETHAND    0x80000000
    
    #define SA_NOMASK   SA_NODEFER
    #define SA_ONESHOT  SA_RESETHAND
    
    /********************************/
    
    #define __BITS_PER_LONG 32
    
    #define _NSIG       64
    #define _NSIG_BPW   __BITS_PER_LONG       
    #define _NSIG_WORDS (_NSIG / _NSIG_BPW)
    /*sigset_t结构体*/
    typedef struct {
        unsigned long sig[_NSIG_WORDS]; /*  unsigned long sig[2];*/
    } sigset_t;
    
    /*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);
    };
    
    /*how值*/
    #ifndef SIG_BLOCK
    #define SIG_BLOCK          0    /* for blocking signals */
    #endif
    #ifndef SIG_UNBLOCK
    #define SIG_UNBLOCK        1    /* for unblocking signals */
    #endif
    #ifndef SIG_SETMASK                                                
    #define SIG_SETMASK        2    /* for setting the signal mask */
    #endif
    
    /*handler提供的三种信号处理方式*/
    #define SIG_DFL ((__sighandler_t)0) /* 系统默认处理信号 */
    #define SIG_IGN ((__sighandler_t)1) /* 忽略该信号 */
    #define SIG_ERR ((__sighandler_t)-1)    /* 从信号返回错误 */
    
    /* 标准文件描述符  */
    #define STDIN_FILENO    0   /* Standard input.  */       
    #define STDOUT_FILENO   1   /* Standard output.  */
    #define STDERR_FILENO   2   /* Standard error output.  */
    
    	```
    
  2. 例子:
    /*1.部分信号处理举例*/
    #include <stdio.h>
    #include <stdlib.h>
    #include <signal.h>
    
    /**
     * 函数名:sa_quit_handler
     * 描述:  用户自定义SIGQUIT、SIGTSTP信号处理函数
     * 参数:  int signo -- 响应的信号
     * 返回值:nonu
     */
    void
    sa_user_handler(int signo){
    	
    	if(SIGQUIT == signo){		
    		fprintf(stderr, "rec: SIGQUIT\n");
    	}else if(SIGTSTP == signo){
    		fprintf(stderr, "rec: SIGTSTP\n");
    	}
    	
    }
    /*ctrl + z : 从键盘发送SIGTSTP信号给进程,暂停进程*/
    /*ctrl + \ : 从键盘发送SIGQUIT信号给进程,进程退出*/
    /*ctrl + c : 终止进程*/
    int
    main(void){
    	
    	struct sigaction act;
    	sigset_t register_mask;
    	sigemptyset(&register_mask); //清空sigset_t结构体
    	sigaddset(&register_mask, SIGQUIT|SIGTSTP); /*添加要阻塞的信号*/
    	
    	sigprocmask(SIG_BLOCK, &act.sa_mask, NULL); /*注册信号处理函数前阻塞SIGQUIT、SIGTSTP信号*/
    	
    	/*注册SIGQUIT信号处理函数部分*/
    	sigemptyset(&act.sa_mask); //清空sa_mask结构体成员
    	sigaddset(&act.sa_mask, SIGTSTP); /*在处理SIGQUIT信号程序中阻塞SIGTSTP信号*/
    	act.sa_handler=sa_user_handler;
    	act.sa_flags=SA_RESTART; //被信号中断的系统调用会自行重启
    	sigaction(SIGQUIT, &act, NULL); //注册SIGQUIT信号处理函数
    
    	/*注册SIGTSTP信号处理函数部分*/
    	sigemptyset(&act.sa_mask); //清空sa_mask结构体成员
    	sigaddset(&act.sa_mask, SIGQUIT); /*在处理SIGTSTP信号程序中阻塞SIGQUIT信号*/
    	act.sa_handler=sa_user_handler;
    	act.sa_flags=SA_RESTART; //被信号中断的系统调用会自行重启
    	sigaction(SIGTSTP, &act, NULL); //注册SIGTSTP信号处理函数
    	
    	sigprocmask(SIG_UNBLOCK, &register_mask, NULL); /*注册信号处理完成后解除阻塞SIGQUIT、SIGTSTP信号*/
    	
    	while(1);
    	return 0;
    }
    
    /*2.子进程不产生僵尸进程的方法*/
    #include <stdio.h>
    #include <stdlib.h>
    #include <signal.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <string.h>
    	
    #define handle_error(msg) \
    	do { perror(msg); exit(EXIT_FAILURE); } while (0) 
    /**
     * 函数名:sa_quit_handler
     * 描述:  用户自定义SIGQUIT、SIGTSTP信号处理函数
     * 参数:  int signo -- 响应的信号
     * 返回值:nonu
     */
    void 
    sa_user_handler(int signo){
    /**
     *linux中,使用SA_NOPOSIX标志下,POSIX.1不指定在子进程终止时是否生成SIGCHLD信号,
     * 在这个例子中是会生成一个SIGCHLD信号;在其他一些实现中,则不是这样。
     */
    	if(SIGCHLD == signo){		
    		fprintf(stderr, "rec: SIGCHLD\n");
    	}
    }
    /*ctrl + z : 从键盘发送SIGTSTP信号给进程,暂停进程*/
    /*ctrl + \ : 从键盘发送SIGQUIT信号给进程,进程退出*/
    /*ctrl + c : 终止进程*/
    int
    main(void){
    	
    	struct sigaction act;
    	sigset_t register_mask;
    	pid_t ret;
    	
    	if((ret=fork())==-1){
    		handle_error("fork");
    	}
    	if(0==ret){ /*在子进程中*/
    	
    		 write(STDERR_FILENO, (char *)"In child!\n", strlen("In child!\n"));	
    		 sleep(3);
    		 write(STDOUT_FILENO, (char *)"child exit!\n", strlen("child exit\n!"));	
    		 
    	}else{ /*在父进程中*/
    	
    		write(STDOUT_FILENO, (char *)"In parent!\n", strlen("In parent\n!"));	
    		sigemptyset(&register_mask); //清空sigset_t结构体
    		sigaddset(&register_mask, SIGQUIT|SIGTSTP); /*添加要阻塞的信号*/
    		
    		sigprocmask(SIG_BLOCK, &act.sa_mask, NULL); 
    		/*注册信号处理函数前阻塞SIGCHLD、SIGQUIT、SIGTSTP信号*/
    		
    		/*注册SIGQUIT信号处理函数部分*/
    		sigemptyset(&act.sa_mask); //清空sa_mask结构体成员
    		sigaddset(&act.sa_mask, SIGQUIT|SIGINT); /*在处理SIGCHLD信号程序中阻塞SIGQUIT、SIGINT信号*/
    		act.sa_handler=sa_user_handler;
    		act.sa_flags=SA_NOCLDWAIT|SA_RESTART; 
    		/*被信号中断的系统调用会自行重启,子进程结束后不通知父进程,由init释放子进程资源*/
    		sigaction(SIGCHLD, &act, NULL); //注册SIGCHLD信号处理函数
    		
    		sigprocmask(SIG_UNBLOCK, &register_mask, NULL); 
    		/*注册信号处理完成后解除阻塞SIGCHLD、SIGQUIT、SIGTSTP信号*/
    		while(1);
    		
    	}
    	
    	return 0;
    }	
    
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值