Kernel version:2.6.14
CPU architecture:ARM920T
Author:ce123(http://blog.csdn.net/ce123)
1.简介
假如进程要处理某一信号,那么要在进程中注册该信号。注册信号首要用来确认信号值及进程针对该信号值的动作之间的映射联系,即进程即将处理哪个进程和该信号被传递给进程时,将履行何种操作。首要有两个函数完成信号的注册:signal()和sigaction()。
2.signal()
signal()的函数原型如下:
print?
- void(*signal(intsignum,void(*handler)(int)))(int);
在运用该调用的进程中参加以下头文件:
print?
- #include
上述声明格局比较复杂,假如不清楚怎么运用,也能够经过下面这种类型界说的格局来运用(POSIX的界说):
print?
- typedefvoid(*sighandler_t)(int);
- sighandler_tsignal(intsignum,sighandler_thandler);
但这种格局在不同的体系中有不同的类型界说,所以要运用这种格局,最好仍是参阅一下手册。在调用中,参数signum指出要设置处理办法的信号。第二个参数handler是一个处理函数,或许是
- SIG_IGN:疏忽参数signum所指的信号。
- SIG_DFL:康复参数signum所指信号的处理办法为默认值。
传递给信号处理例程的整数参数是信号值,这样能够使得一个信号处理例程处理多个信号。体系调用signal()回来值是指定信号signum前一次的处理例程或许错误时回来错误代码SIG_ERR。
signal()经过体系调用sys_signal()为一个指定的信号设置用户态处理函数。sys_signal()界说如下:
print?
- /*
- *Forbackwardscompatibility.Functionalitysupersededbysigaction.
- */
- asmlinkageunsignedlong
- sys_signal(intsig,__sighandler_thandler)
- {
- structk_sigactionnew_sa,old_sa;
- intret;
- new_sa.sa.sa_handler=handler;
- new_sa.sa.sa_flags=SA_ONESHOT|SA_NOMASK;
- ret=do_sigaction(sig,&new_sa,&old_sa);
- returnret?ret:(unsignedlong)old_sa.sa.sa_handler;
- }
__sighandler_t的界说如下:
print?
- typedefvoid__signalfn_t(int);
- typedef__signalfn_t__user*__sighandler_t;
信号由sys_signal()的第一个参数指定,信号处理函数的地址由第二个参数指定。sys_signal()依据这两个参数设置一个k_sigaction结构,然后调用do_sigaction(),该函数的界说咱们会在后边详细解说。
2.sigaction()
sigaction()的函数原型如下:
print?
- sigaction(intsignum,conststructsigaction*act,structsigaction*oldact);
sigaction()对应的体系调用为do_sigaction(),下面咱们详细解说do_sigaction()函数,其界说如下:
2.1do_sigaction()
print?
- int
- do_sigaction(intsig,conststructk_sigaction*act,structk_sigaction*oact)
- {
- structk_sigaction*k;
- if(!valid_signal(sig)||sig<1||(act&&sig_kernel_only(sig)))
- return-EINVAL;
- k=¤tt->sighand->action[sig-1];
- spin_lock_irq(¤tt->sighand->siglock);
- if(signal_pending(current)){
- /*
- *Iftheremightbeafatalsignalpendingonmultiple
- *threads,makesurewetakeitbeforechangingtheaction.
- */
- spin_unlock_irq(¤tt->sighand->siglock);
- return-ERESTARTNOINTR;
- }
- if(oact)//把本来的k_sigaction保存到oact结构中,这里是对整个数据结构进行仿制
- *oact=*k;
- if(act){
- /*
- *POSIX3.3.1.3:
- *”SettingasignalactiontoSIG_IGNforasignalthatis
- *pendingshallcausethependingsignaltobediscarded,
- *whetherornotitisblocked.”
- *
- *”SettingasignalactiontoSIG_DFLforasignalthatis
- *pendingandwhosedefaultactionistoignorethesignal
- *(forexample,SIGCHLD),shallcausethependingsignalto
- *bediscarded,whetherornotitisblocked”
- */
- if(act->sa.sa_handler==SIG_IGN||
- (act->sa.sa_handler==SIG_DFL&&
- sig_kernel_ignore(sig))){
- /*
- *Thisisafairlyrarecase,soweonlytakethe
- *tasklist_lockonceweresurewellneedit.
- *Nowwemustdothislittleunlockandrelock
- *dancetomaintainthelockhierarchy.
- */
- structtask_struct*t=current;
- spin_unlock_irq(&t->sighand->siglock);
- read_lock(&tasklist_lock);
- spin_lock_irq(&t->sighand->siglock);
- *k=*act;//把新的k_sigaction结构仿制到进程的sighand->action中
- sigdelsetmask(&k->sa.sa_mask,
- sigmask(SIGKILL)|sigmask(SIGSTOP));
- rm_from_queue(sigmask(sig),&t->signal->shared_pending);
- do{
- rm_from_queue(sigmask(sig),&t->pending);
- recalc_sigpending_tsk(t);
- t=next_thread(t);
- }while(t!=current);
- spin_unlock_irq(¤t->sighand->siglock);
- read_unlock(&tasklist_lock);
- return0;
- }
- *k=*act;//把新的k_sigaction结构仿制到进程的sighand->action中
- sigdelsetmask(&k->sa.sa_mask,
- sigmask(SIGKILL)|sigmask(SIGSTOP));
- }
- spin_unlock_irq(¤tt->sighand->siglock);
- return0;
- }