/*************************************************************************** sigset_test.c - description ------------------- begin : Wed Nov 16 2005 copyright : (C) 2005 by Qlusters Ltd email : linux@qlusters.com ***************************************************************************/ #ifdef DEF_KERNEL #include #include #include #include #include static int sigset_test_init(void); static void sigset_test_exit(void); module_init(sigset_test_init); module_exit(sigset_test_exit); #define SIGADDSET sigaddset #define SIGISMEMBER sigismember //#define SIGADDSET(x, y) set_bit(y, (long *)x) #else extern int printf(const char *format, ...); #define printk printf #define KERN_INFO typedef struct { unsigned long sig[2]; } sigset_t; #include #define _NSIG (64) #define _NSIG_BPW (32) static __inline__ int __const_sigismember(sigset_t *set, int _sig) { unsigned long sig = _sig - 1; return 1 & (set->sig[sig / _NSIG_BPW] >> (sig % _NSIG_BPW)); } static __inline__ int __gen_sigismember(sigset_t *set, int _sig) { int ret; __asm__("btl %2,%1\n\tsbbl %0,%0" : "=r"(ret) : "m"(*set), "Ir"(_sig-1) : "cc"); return ret; } #define SIGISMEMBER(set,sig) \ (__builtin_constant_p(sig) ? \ __const_sigismember((set),(sig)) : \ __gen_sigismember((set),(sig))) #define SIGADDSET1(set,sig) \ (__builtin_constant_p(sig) ? \ __const_sigaddset((set),(sig)) : \ __gen_sigaddset((set),(sig))) static __inline__ void __gen_sigaddset(sigset_t *set, int _sig) { __asm__("btsl %1,%0" : "=m"(*set) : "Ir"(_sig-1) : "cc"); } static __inline__ void __const_sigaddset(sigset_t *set, int _sig) { unsigned long sig = _sig - 1; set->sig[sig / _NSIG_BPW] |= 1 << (sig % _NSIG_BPW); } #define SIGADDSET __gen_sigaddset //#define SIGADDSET SIGADDSET1 /* fixes the problem */ #endif sigset_t ssi_fatal_sigset; static sigset_t ssi_stop_set; static void print_pending_signals(sigset_t *pending, sigset_t *blocked); void sigset_test_exit(void) { return; } #ifdef DEF_KERNEL static int sigset_test_init() #else int main() #endif { sigset_t cleaned; cleaned = (sigset_t) { {0, 0} }; /* these are non-fatal signals. Other signals are if their action is SIG_DFL */ SIGADDSET(&cleaned, SIGCONT); SIGADDSET(&cleaned, SIGCHLD); SIGADDSET(&cleaned, SIGWINCH); SIGADDSET(&cleaned, SIGURG); SIGADDSET(&cleaned, SIGTSTP); SIGADDSET(&cleaned, SIGTTIN); SIGADDSET(&cleaned, SIGTTOU); SIGADDSET(&cleaned, SIGTTOU); ssi_fatal_sigset = (sigset_t) { {-1, -1} }; //uncomenting this line fixes the problem //printk(KERN_INFO "sigset_test: fatal %p, stop %p\n", &ssi_fatal_sigset, &ssi_stop_set); /* ssi_fatal_sigset is a mask of all signals that are fatal */ //commenting the line below fixes the problem ssi_fatal_sigset = cleaned; ssi_stop_set = (sigset_t) { {0, 0} }; printk(KERN_INFO "sigset_test after zeroing\n"); print_pending_signals(&ssi_stop_set, NULL); SIGADDSET(&ssi_stop_set, SIGTSTP); printk(KERN_INFO "sigset_test after %d\n", SIGTSTP); print_pending_signals(&ssi_stop_set, NULL); SIGADDSET(&ssi_stop_set, SIGTTIN); printk(KERN_INFO "sigset_test after %d\n", SIGTTIN); print_pending_signals(&ssi_stop_set, NULL); SIGADDSET(&ssi_stop_set, SIGTTOU); printk(KERN_INFO "sigset_test after %d\n", SIGTTOU); print_pending_signals(&ssi_stop_set, NULL); SIGADDSET(&ssi_stop_set, SIGSTOP); printk(KERN_INFO "sigset_test after %d\n", SIGSTOP); print_pending_signals(&ssi_stop_set, NULL); return 1; } static void print_pending_signals(sigset_t *pending, sigset_t *blocked) { int i; if(pending->sig[0] == 0 && pending->sig[1] == 0) { printk(KERN_INFO "sigset_t: no set signals\n"); return; } if(blocked) { for(i = 0; i < _NSIG; i++) { if(SIGISMEMBER(pending, i+1)) { printk(KERN_INFO "sigset_test: set signal %d is%sblocked\n", i+1, SIGISMEMBER(blocked, i+1) ? " " : " not "); } } } else { for(i = 0; i < _NSIG; i++) { if(SIGISMEMBER(pending, i+1)) { printk(KERN_INFO "sigset_test: set signal %d\n", i+1); } } } }