日期:2014-05-16  浏览次数:21092 次

《linux 内核完全剖析》 signal.c 代码分析笔记

signal.c 代码分析笔记

sgetmask



int sys_sgetmask()// 获取当前进程阻塞的信号
{
         returncurrent->blocked;
}

 sys_ssetmask



int sys_ssetmask(int newmask) //设置当前进程阻塞信号,确保SIGKILL 和SIGSTOP不被阻塞
{

         int old=current->blocked;

         current->blocked= newmask & ~(1<<(SIGKILL-1)) & ~(1<<(SIGSTOP-1));

         return old;
}

 sys_sigpending



int sys_sigpending(sigset_t *set)//verify_area的水有点深。嘿嘿。。。
{
   /* fill in "set" with signals pending but blocked. */

   verify_area(set,4); //验证set指向的地址处4字节是否可写,不可写就给他分配一页内存,并给与读写权限。。。。
   put_fs_long(current->blocked & current->signal, (unsigned long*)set); //这里理解成把第一个参数的值赋值给set指向的地址就好。。。。

   return 0;
}

 

 

 

 put_fs_byte



extern inline void put_fs_byte(charval,char *addr)
{

__asm__ ("movb%0,%%fs:%1"::"r" (val),"m" (*addr));

}

 

需要说明的就是这里fs寄存器是指向LDT的数据段描述符0x17,即fs用于访问数据

 

 sys_sigsuspend



int sys_sigsuspend(int restart, unsignedlong old_mask, unsigned long set)
{
   extern int sys_pause(void); //声明引用sys_pause

   if (restart) {//如果restart 非零,进程的阻塞信号为old_mask
         /*we're restarting */
         current->blocked= old_mask;

         return-EINTR;
    }

   //如果restart 非零
   /* we're not restarting.  do thework */
   *(&restart) = 1;
   *(&old_mask) = current->blocked; //把当前进程的阻塞信号做oldmask

   //额。。。我不知道给一个局部变量赋值之后又不返回,先的函数也不引用这变量,

   //这究竟有什么用!我必须质疑这是冗余的赋值操作
   current->blocked = set;
   (void) sys_pause();                     /*return after a signal arrives */

   //我不得不感叹,这个sys_pause就相当于sleep(很短的时间)

   //这么做就是为了捕获信号

   return -ERESTARTNOINTR;               /*handle the signal, and come back */
}

 save_old



static inline void save_old(char *from,char * to) //把内核段的数据copy到用户段(local date space)
{
         inti;

         verify_area(to,sizeof(struct sigaction)); //确保to地址处有结构体大小的内存可读写
         for(i=0 ; i< sizeof(struct sigaction) ; i++) { //一个字节一个字节的copy,from到to
                   put_fs_byte(*from,to);
                   from++;
                   to++;
         }
}

 get_new