⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 75.html

📁 linux 0.11中文版 有注释
💻 HTML
📖 第 1 页 / 共 2 页
字号:
<a name='L73'>  tmp.sa_restorer = (<b>void</b> (*)(<b>void</b>)) restorer;  <i><font color='green'>// 保存返回地址。</font></i>
<a name='L74'>  handler = (<b>long</b>) current-&gt;sigaction[signum - 1].sa_handler;
<a name='L75'>  current-&gt;sigaction[signum - 1] = tmp;
<a name='L76'>  <b>return</b> handler;
<a name='L77'><font color='red'>}</font>
<a name='L78'>
<a name='L79'><i><font color='green'>// sigaction()系统调用。改变进程在收到一个信号时的操作。signum 是除了SIGKILL 以外的任何</font></i>
<a name='L80'><i><font color='green'>// 信号。[如果新操作(action)不为空]则新操作被安装。如果oldaction 指针不为空,则原操作</font></i>
<a name='L81'><i><font color='green'>// 被保留到oldaction。成功则返回0,否则为-1。</font></i>
<a name='L82'><b>int</b>
<a name='L83'><a href='../R/680.html' title='Multiple refered from 2 places.'>sys_sigaction</a> (<b>int</b> signum, <b>const</b> <b>struct</b> sigaction *action,
<a name='L84'>               <b>struct</b> sigaction *oldaction)
<a name='L85'><font color='red'>{</font>
<a name='L86'>  <b>struct</b> sigaction tmp;
<a name='L87'>
<a name='L88'><i><font color='green'>// 信号值要在(1-32)范围内,并且信号SIGKILL 的处理句柄不能被改变。</font></i>
<a name='L89'>  <b>if</b> (signum &lt; 1 || signum &gt; 32 || signum == <a href='../S/39.html#L22' title='Defined at 22 in include/signal.h.'>SIGKILL</a>)
<a name='L90'>    <b>return</b> -1;
<a name='L91'><i><font color='green'>// 在信号的sigaction 结构中设置新的操作(动作)。</font></i>
<a name='L92'>  tmp = current-&gt;sigaction[signum - 1];
<a name='L93'>  <a href='../S/75.html#L50' title='Defined at 50 in kernel/signal.c.'>get_new</a> ((<b>char</b> *) action, (<b>char</b> *) (signum - 1 + current-&gt;sigaction));
<a name='L94'><i><font color='green'>// 如果oldaction 指针不为空的话,则将原操作指针保存到oldaction 所指的位置。</font></i>
<a name='L95'>  <b>if</b> (oldaction)
<a name='L96'>    <a href='../S/75.html#L35' title='Defined at 35 in kernel/signal.c.'>save_old</a> ((<b>char</b> *) &amp;tmp, (<b>char</b> *) oldaction);
<a name='L97'><i><font color='green'>// 如果允许信号在自己的信号句柄中收到,则令屏蔽码为0,否则设置屏蔽本信号。</font></i>
<a name='L98'>  <b>if</b> (current-&gt;sigaction[signum - 1].sa_flags &amp; <a href='../S/39.html#L40' title='Defined at 40 in include/signal.h.'>SA_NOMASK</a>)
<a name='L99'>    current-&gt;sigaction[signum - 1].sa_mask = 0;
<a name='L100'>  <b>else</b>
<a name='L101'>    current-&gt;sigaction[signum - 1].sa_mask |= (1 &lt;&lt; (signum - 1));
<a name='L102'>  <b>return</b> 0;
<a name='L103'><font color='red'>}</font>
<a name='L104'>
<a name='L105'><i><font color='green'>// 系统调用中断处理程序中真正的信号处理程序(在kernel/system_call.s,119 行)。</font></i>
<a name='L106'><i><font color='green'>// 该段代码的主要作用是将信号的处理句柄插入到用户程序堆栈中,并在本系统调用结束</font></i>
<a name='L107'><i><font color='green'>// 返回后立刻执行信号句柄程序,然后继续执行用户的程序。</font></i>
<a name='L108'><b>void</b>
<a name='L109'><a href='../S/77.html#L158' title='Refered from 158 in kernel/system_call.s.'>do_signal</a> (<b>long</b> signr, <b>long</b> eax, <b>long</b> ebx, <b>long</b> ecx, <b>long</b> edx,
<a name='L110'>           <b>long</b> fs, <b>long</b> es, <b>long</b> ds,
<a name='L111'>           <b>long</b> eip, <b>long</b> cs, <b>long</b> eflags, <b>unsigned</b> <b>long</b> *esp, <b>long</b> ss)
<a name='L112'><font color='red'>{</font>
<a name='L113'>  <b>unsigned</b> <b>long</b> sa_handler;
<a name='L114'>  <b>long</b> old_eip = eip;
<a name='L115'>  <b>struct</b> sigaction *sa = current-&gt;sigaction + signr - 1;        <i><font color='green'>//current-&gt;sigaction[signu-1]。</font></i>
<a name='L116'>  <b>int</b> longs;
<a name='L117'>  <b>unsigned</b> <b>long</b> *tmp_esp;
<a name='L118'>
<a name='L119'>  sa_handler = (<b>unsigned</b> <b>long</b>) sa-&gt;sa_handler;
<a name='L120'><i><font color='green'>// 如果信号句柄为SIG_IGN(忽略),则返回;如果句柄为SIG_DFL(默认处理),则如果信号是</font></i>
<a name='L121'><i><font color='green'>// SIGCHLD 则返回,否则终止进程的执行</font></i>
<a name='L122'>  <b>if</b> (sa_handler == 1)
<a name='L123'>    <b>return</b>;
<a name='L124'>  <b>if</b> (!sa_handler)
<a name='L125'>    <font color='red'>{</font>
<a name='L126'>      <b>if</b> (signr == <a href='../S/39.html#L30' title='Defined at 30 in include/signal.h.'>SIGCHLD</a>)
<a name='L127'>        <b>return</b>;
<a name='L128'>      <b>else</b>
<a name='L129'>        <a href='../S/67.html#L139' title='Defined at 139 in kernel/exit.c.'>do_exit</a> (1 &lt;&lt; (signr - 1));     <i><font color='green'>// [?? 为什么以信号位图为参数?不为什么!??]</font></i>
<a name='L130'><i><font color='green'>// 这里应该是do_exit(1&lt;&lt;signr))。</font></i>
<a name='L131'>    <font color='red'>}</font>
<a name='L132'><i><font color='green'>// 如果该信号句柄只需使用一次,则将该句柄置空(该信号句柄已经保存在sa_handler 指针中)。</font></i>
<a name='L133'>  <b>if</b> (sa-&gt;sa_flags &amp; <a href='../S/39.html#L41' title='Defined at 41 in include/signal.h.'>SA_ONESHOT</a>)
<a name='L134'>    sa-&gt;sa_handler = <a href='../D/261.html' title='Multiple defined in 12 places.'>NULL</a>;
<a name='L135'><i><font color='green'>// 下面这段代码将信号处理句柄插入到用户堆栈中,同时也将sa_restorer,signr,进程屏蔽码(如果</font></i>
<a name='L136'><i><font color='green'>// SA_NOMASK 没置位),eax,ecx,edx 作为参数以及原调用系统调用的程序返回指针及标志寄存器值</font></i>
<a name='L137'><i><font color='green'>// 压入堆栈。因此在本次系统调用中断(0x80)返回用户程序时会首先执行用户的信号句柄程序,然后</font></i>
<a name='L138'><i><font color='green'>// 再继续执行用户程序。</font></i>
<a name='L139'><i><font color='green'>// 将用户调用系统调用的代码指针eip 指向该信号处理句柄。</font></i>
<a name='L140'>  *(&amp;eip) = sa_handler;
<a name='L141'><i><font color='green'>// 如果允许信号自己的处理句柄收到信号自己,则也需要将进程的阻塞码压入堆栈。</font></i>
<a name='L142'>  longs = (sa-&gt;sa_flags &amp; <a href='../S/39.html#L40' title='Defined at 40 in include/signal.h.'>SA_NOMASK</a>) ? 7 : 8;
<a name='L143'><i><font color='green'>// 将原调用程序的用户的堆栈指针向下扩展7(或8)个长字(用来存放调用信号句柄的参数等),</font></i>
<a name='L144'><i><font color='green'>// 并检查内存使用情况(例如如果内存超界则分配新页等)。</font></i>
<a name='L145'>  *(&amp;esp) -= longs;
<a name='L146'>  <a href='../S/68.html#L34' title='Defined at 34 in kernel/fork.c.'>verify_area</a> (esp, longs * 4);
<a name='L147'><i><font color='green'>// 在用户堆栈中从下到上存放sa_restorer, 信号signr, 屏蔽码blocked(如果SA_NOMASK 置位),</font></i>
<a name='L148'><i><font color='green'>// eax, ecx, edx, eflags 和用户程序原代码指针。</font></i>
<a name='L149'>  tmp_esp = esp;
<a name='L150'>  <a href='../S/24.html#L62' title='Defined at 62 in include/asm/segment.h.'>put_fs_long</a> ((<b>long</b>) sa-&gt;sa_restorer, tmp_esp++);
<a name='L151'>  <a href='../S/24.html#L62' title='Defined at 62 in include/asm/segment.h.'>put_fs_long</a> (signr, tmp_esp++);
<a name='L152'>  <b>if</b> (!(sa-&gt;sa_flags &amp; <a href='../S/39.html#L40' title='Defined at 40 in include/signal.h.'>SA_NOMASK</a>))
<a name='L153'>    <a href='../S/24.html#L62' title='Defined at 62 in include/asm/segment.h.'>put_fs_long</a> (current-&gt;blocked, tmp_esp++);
<a name='L154'>  <a href='../S/24.html#L62' title='Defined at 62 in include/asm/segment.h.'>put_fs_long</a> (eax, tmp_esp++);
<a name='L155'>  <a href='../S/24.html#L62' title='Defined at 62 in include/asm/segment.h.'>put_fs_long</a> (ecx, tmp_esp++);
<a name='L156'>  <a href='../S/24.html#L62' title='Defined at 62 in include/asm/segment.h.'>put_fs_long</a> (edx, tmp_esp++);
<a name='L157'>  <a href='../S/24.html#L62' title='Defined at 62 in include/asm/segment.h.'>put_fs_long</a> (eflags, tmp_esp++);
<a name='L158'>  <a href='../S/24.html#L62' title='Defined at 62 in include/asm/segment.h.'>put_fs_long</a> (old_eip, tmp_esp++);
<a name='L159'>  current-&gt;blocked |= sa-&gt;sa_mask;      <i><font color='green'>// 进程阻塞码(屏蔽码)添上sa_mask 中的码位。</font></i>
<a name='L160'><font color='red'>}</font>
</pre>
<hr>
<a name='BOTTOM'>
<i><font color='green'>/* [&lt;][&gt;]<a href='#L18'>[^]</a><a href='#L109'>[v]</a><a href='#TOP'>[top]</a>[bottom]<a href='../mains.html'>[index]</a><a href='../help.html'>[help]</a> */</font></i>
</body>
</html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -