- 部分內核宏及函數對照
/*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. */ ```
- 例子:
/*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(®ister_mask); //清空sigset_t結構體 sigaddset(®ister_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, ®ister_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(®ister_mask); //清空sigset_t結構體 sigaddset(®ister_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, ®ister_mask, NULL); /*註冊信號處理完成後解除阻塞SIGCHLD、SIGQUIT、SIGTSTP信號*/ while(1); } return 0; }
Linux --sigaction舉例(改變信號默認操作)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.