67.html
来自「linux 0.11中文版 有注释」· HTML 代码 · 共 295 行 · 第 1/2 页
HTML
295 行
<html>
<head>
<title>kernel/exit.c</title>
<meta name='robots' content='noindex,nofollow'>
<meta name='generator' content='GLOBAL-5.4.1'>
</head>
<body text='#191970' bgcolor='#f5f5dc' vlink='gray'>
<a name='TOP'><h2><a href='../mains.html'>root</a>/<a href='../files/104.html'>kernel</a>/exit.c</h2>
<i><font color='green'>/* [<][>]<a href='#L22'>[^]</a><a href='#L203'>[v]</a>[top]<a href='#BOTTOM'>[bottom]</a><a href='../mains.html'>[index]</a><a href='../help.html'>[help]</a> */</font></i>
<hr>
<h2>DEFINITIONS</h2>
This source file includes following definitions.
<ol>
<li><a href='#L22' title='Defined at 22.'>release</a>
<li><a href='#L41' title='Defined at 41.'>send_sig</a>
<li><a href='#L57' title='Defined at 57.'>kill_session</a>
<li><a href='#L83' title='Defined at 83.'>sys_kill</a>
<li><a href='#L117' title='Defined at 117.'>tell_father</a>
<li><a href='#L139' title='Defined at 139.'>do_exit</a>
<li><a href='#L187' title='Defined at 187.'>sys_exit</a>
<li><a href='#L203' title='Defined at 203.'>sys_waitpid</a>
</ol>
<hr>
<pre>
<a name='L1'><i><font color='green'>/*</font></i>
<a name='L2'><i><font color='green'>* linux/kernel/exit.c</font></i>
<a name='L3'><i><font color='green'>*</font></i>
<a name='L4'><i><font color='green'>* (C) 1991 Linus Torvalds</font></i>
<a name='L5'><i><font color='green'>*/</font></i>
<a name='L6'>
<a name='L7'><font color='darkred'>#include</font> <<a href='28.html'>errno.h</a>> <i><font color='green'>// 错误号头文件。包含系统中各种出错号。(Linus 从minix 中引进的)</font></i>
<a name='L8'><font color='darkred'>#include</font> <<a href='39.html'>signal.h</a>> <i><font color='green'>// 信号头文件。定义信号符号常量,信号结构以及信号操作函数原型。</font></i>
<a name='L9'><font color='darkred'>#include</font> <<a href='47.html'>sys/wait.h</a>> <i><font color='green'>// 等待调用头文件。定义系统调用wait()和waitpid()及相关常数符号。</font></i>
<a name='L10'>
<a name='L11'><font color='darkred'>#include</font> <<a href='36.html'>linux/sched.h</a>> <i><font color='green'>// 调度程序头文件,定义了任务结构task_struct、初始任务0 的数据,</font></i>
<a name='L12'><i><font color='green'>// 还有一些有关描述符参数设置和获取的嵌入式汇编函数宏语句。</font></i>
<a name='L13'><font color='darkred'>#include</font> <<a href='34.html'>linux/kernel.h</a>> <i><font color='green'>// 内核头文件。含有一些内核常用函数的原形定义。</font></i>
<a name='L14'><font color='darkred'>#include</font> <<a href='38.html'>linux/tty.h</a>> <i><font color='green'>// tty 头文件,定义了有关tty_io,串行通信方面的参数、常数。</font></i>
<a name='L15'><font color='darkred'>#include</font> <<a href='24.html'>asm/segment.h</a>> <i><font color='green'>// 段操作头文件。定义了有关段寄存器操作的嵌入式汇编函数。</font></i>
<a name='L16'>
<a name='L17'><b>int</b> <a href='../S/74.html#L208' title='Defined at 208 in kernel/sched.c.'>sys_pause</a> (<b>void</b>);
<a name='L18'><b>int</b> <a href='../S/15.html#L299' title='Defined at 299 in fs/open.c.'>sys_close</a> (<b>int</b> fd);
<a name='L19'>
<a name='L20'><i><font color='green'>//// 释放指定进程(任务)。</font></i>
<a name='L21'><b>void</b>
<a name='L22'><a href='../R/569.html' title='Multiple refered from 3 places.'>release</a> (<b>struct</b> task_struct *p)
<a name='L23'><font color='red'>{</font>
<a name='L24'> <b>int</b> <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>;
<a name='L25'>
<a name='L26'> <b>if</b> (!p)
<a name='L27'> <b>return</b>;
<a name='L28'> <b>for</b> (<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> = 1; <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> < <a href='../S/36.html#L4' title='Defined at 4 in include/linux/sched.h.'>NR_TASKS</a>; <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>++) <i><font color='green'>// 扫描任务数组,寻找指定任务。</font></i>
<a name='L29'> <b>if</b> (task[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>] == p)
<a name='L30'> <font color='red'>{</font>
<a name='L31'> task[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>] = <a href='../D/261.html' title='Multiple defined in 12 places.'>NULL</a>; <i><font color='green'>// 置空该任务项并释放相关内存页。</font></i>
<a name='L32'> <a href='../S/94.html#L130' title='Defined at 130 in mm/memory.c.'>free_page</a> ((<b>long</b>) p);
<a name='L33'> <a href='../S/74.html#L146' title='Defined at 146 in kernel/sched.c.'>schedule</a> (); <i><font color='green'>// 重新调度。</font></i>
<a name='L34'> <b>return</b>;
<a name='L35'> <font color='red'>}</font>
<a name='L36'> <a href='../S/72.html#L24' title='Defined at 24 in kernel/panic.c.'>panic</a> ("trying to release non-existent task"); <i><font color='green'>// 指定任务若不存在则死机。</font></i>
<a name='L37'><font color='red'>}</font>
<a name='L38'>
<a name='L39'><i><font color='green'>//// 向指定任务(*p)发送信号(sig),权限为priv。</font></i>
<a name='L40'><b>static</b> <b>inline</b> <b>int</b>
<a name='L41'><a href='../R/591.html' title='Multiple refered from 5 places.'>send_sig</a> (<b>long</b> sig, <b>struct</b> task_struct *p, <b>int</b> priv)
<a name='L42'><font color='red'>{</font>
<a name='L43'><i><font color='green'>// 若信号不正确或任务指针为空则出错退出。</font></i>
<a name='L44'> <b>if</b> (!p || sig < 1 || sig > 32)
<a name='L45'> <b>return</b> -<a href='../S/28.html#L51' title='Defined at 51 in include/errno.h.'>EINVAL</a>;
<a name='L46'><i><font color='green'>// 若有权或进程有效用户标识符(euid)就是指定进程的euid 或者是超级用户,则在进程位图中添加</font></i>
<a name='L47'><i><font color='green'>// 该信号,否则出错退出。其中suser()定义为(current->euid==0),用于判断是否超级用户。</font></i>
<a name='L48'> <b>if</b> (priv || (current->euid == p->euid) || <a href='../S/34.html#L37' title='Defined at 37 in include/linux/kernel.h.'>suser</a> ())
<a name='L49'> p->signal |= (1 << (sig - 1));
<a name='L50'> <b>else</b>
<a name='L51'> <b>return</b> -<a href='../D/112.html' title='Multiple defined in 2 places.'>EPERM</a>;
<a name='L52'> <b>return</b> 0;
<a name='L53'><font color='red'>}</font>
<a name='L54'>
<a name='L55'><i><font color='green'>//// 终止会话(session)。</font></i>
<a name='L56'><b>static</b> <b>void</b>
<a name='L57'><a href='../S/67.html#L175' title='Refered from 175 in kernel/exit.c.'>kill_session</a> (<b>void</b>)
<a name='L58'><font color='red'>{</font>
<a name='L59'> <b>struct</b> task_struct **p = <a href='../S/36.html#L4' title='Defined at 4 in include/linux/sched.h.'>NR_TASKS</a> + task; <i><font color='green'>// 指针*p 首先指向任务数组最末端。</font></i>
<a name='L60'>
<a name='L61'><i><font color='green'>// 对于所有的任务(除任务0 以外),如果其会话等于当前进程的会话就向它发送挂断进程信号。</font></i>
<a name='L62'> <b>while</b> (--p > &<a href='../S/36.html#L7' title='Defined at 7 in include/linux/sched.h.'>FIRST_TASK</a>)
<a name='L63'> <font color='red'>{</font>
<a name='L64'> <b>if</b> (*p && (*p)->session == current->session)
<a name='L65'> (*p)->signal |= 1 << (<a href='../S/39.html#L13' title='Defined at 13 in include/signal.h.'>SIGHUP</a> - 1); <i><font color='green'>// 发送挂断进程信号。</font></i>
<a name='L66'> <font color='red'>}</font>
<a name='L67'><font color='red'>}</font>
<a name='L68'>
<a name='L69'><i><font color='green'>/*</font></i>
<a name='L70'><i><font color='green'>* XXX need to check permissions needed to send signals to process</font></i>
<a name='L71'><i><font color='green'>* groups, etc. etc. kill() permissions semantics are tricky!</font></i>
<a name='L72'><i><font color='green'>*/</font></i>
<a name='L73'><i><font color='green'>/*</font></i>
<a name='L74'><i><font color='green'>* 为了向进程组等发送信号,XXX 需要检查许可。kill()的许可机制非常巧妙!</font></i>
<a name='L75'><i><font color='green'>*/</font></i>
<a name='L76'><i><font color='green'>//// kill()系统调用可用于向任何进程或进程组发送任何信号。</font></i>
<a name='L77'><i><font color='green'>// 如果pid 值>0,则信号被发送给pid。</font></i>
<a name='L78'><i><font color='green'>// 如果pid=0,那么信号就会被发送给当前进程的进程组中的所有进程。</font></i>
<a name='L79'><i><font color='green'>// 如果pid=-1,则信号sig 就会发送给除第一个进程外的所有进程。</font></i>
<a name='L80'><i><font color='green'>// 如果pid < -1,则信号sig 将发送给进程组-pid 的所有进程。</font></i>
<a name='L81'><i><font color='green'>// 如果信号sig 为0,则不发送信号,但仍会进行错误检查。如果成功则返回0。</font></i>
<a name='L82'><b>int</b>
<a name='L83'><a href='../R/654.html' title='Multiple refered from 2 places.'>sys_kill</a> (<b>int</b> pid, <b>int</b> sig)
<a name='L84'><font color='red'>{</font>
<a name='L85'> <b>struct</b> task_struct **p = <a href='../S/36.html#L4' title='Defined at 4 in include/linux/sched.h.'>NR_TASKS</a> + task;
<a name='L86'> <b>int</b> err, retval = 0;
<a name='L87'>
<a name='L88'> <b>if</b> (!pid)
<a name='L89'> <b>while</b> (--p > &<a href='../S/36.html#L7' title='Defined at 7 in include/linux/sched.h.'>FIRST_TASK</a>)
<a name='L90'> <font color='red'>{</font>
<a name='L91'> <b>if</b> (*p && (*p)->pgrp == current->pid)
<a name='L92'> <b>if</b> (err = <a href='../S/67.html#L41' title='Defined at 41 in kernel/exit.c.'>send_sig</a> (sig, *p, 1))
<a name='L93'> retval = err;
<a name='L94'> <font color='red'>}</font>
<a name='L95'> <b>else</b> <b>if</b> (pid > 0)
<a name='L96'> <b>while</b> (--p > &<a href='../S/36.html#L7' title='Defined at 7 in include/linux/sched.h.'>FIRST_TASK</a>)
<a name='L97'> <font color='red'>{</font>
<a name='L98'> <b>if</b> (*p && (*p)->pid == pid)
<a name='L99'> <b>if</b> (err = <a href='../S/67.html#L41' title='Defined at 41 in kernel/exit.c.'>send_sig</a> (sig, *p, 0))
<a name='L100'> retval = err;
<a name='L101'> <font color='red'>}</font>
<a name='L102'> <b>else</b> <b>if</b> (pid == -1)
<a name='L103'> <b>while</b> (--p > &<a href='../S/36.html#L7' title='Defined at 7 in include/linux/sched.h.'>FIRST_TASK</a>)
<a name='L104'> <b>if</b> (err = <a href='../S/67.html#L41' title='Defined at 41 in kernel/exit.c.'>send_sig</a> (sig, *p, 0))
<a name='L105'> retval = err;
<a name='L106'> <b>else</b>
<a name='L107'> <b>while</b> (--p > &<a href='../S/36.html#L7' title='Defined at 7 in include/linux/sched.h.'>FIRST_TASK</a>)
<a name='L108'> <b>if</b> (*p && (*p)->pgrp == -pid)
<a name='L109'> <b>if</b> (err = <a href='../S/67.html#L41' title='Defined at 41 in kernel/exit.c.'>send_sig</a> (sig, *p, 0))
<a name='L110'> retval = err;
<a name='L111'> <b>return</b> retval;
<a name='L112'><font color='red'>}</font>
<a name='L113'>
<a name='L114'><i><font color='green'>//// 通知父进程 -- 向进程pid 发送信号SIGCHLD:子进程将停止或终止。</font></i>
<a name='L115'><i><font color='green'>// 如果没有找到父进程,则自己释放。</font></i>
<a name='L116'><b>static</b> <b>void</b>
<a name='L117'><a href='../S/67.html#L180' title='Refered from 180 in kernel/exit.c.'>tell_father</a> (<b>int</b> pid)
<a name='L118'><font color='red'>{</font>
<a name='L119'> <b>int</b> <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>;
<a name='L120'>
<a name='L121'> <b>if</b> (pid)
<a name='L122'> <b>for</b> (<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> = 0; <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> < <a href='../S/36.html#L4' title='Defined at 4 in include/linux/sched.h.'>NR_TASKS</a>; <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>++)
<a name='L123'> <font color='red'>{</font>
<a name='L124'> <b>if</b> (!task[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>])
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?