8.html
来自「linux 0.11中文版 有注释」· HTML 代码 · 共 573 行 · 第 1/4 页
HTML
573 行
<a name='L412'><i><font color='green'>* (3) filename of shell script</font></i>
<a name='L413'><i><font color='green'>*</font></i>
<a name='L414'><i><font color='green'>* This is done in reverse order, because of how the</font></i>
<a name='L415'><i><font color='green'>* user environment and arguments are stored.</font></i>
<a name='L416'><i><font color='green'>*/</font></i>
<a name='L417'><i><font color='green'>/*</font></i>
<a name='L418'><i><font color='green'>* 拼接 (1) argv[0]中放解释程序的名称</font></i>
<a name='L419'><i><font color='green'>* (2) (可选的)解释程序的参数</font></i>
<a name='L420'><i><font color='green'>* (3) 脚本程序的名称</font></i>
<a name='L421'><i><font color='green'>*</font></i>
<a name='L422'><i><font color='green'>* 这是以逆序进行处理的,是由于用户环境和参数的存放方式造成的。</font></i>
<a name='L423'><i><font color='green'>*/</font></i>
<a name='L424'><i><font color='green'>// 复制脚本程序文件名到参数和环境空间中。</font></i>
<a name='L425'> p = <a href='../S/8.html#L166' title='Defined at 166 in fs/exec.c.'>copy_strings</a> (1, &filename, page, p, 1);
<a name='L426'><i><font color='green'>// 复制解释程序的参数到参数和环境空间中。</font></i>
<a name='L427'> argc++;
<a name='L428'> <b>if</b> (i_arg)
<a name='L429'> <font color='red'>{</font>
<a name='L430'> p = <a href='../S/8.html#L166' title='Defined at 166 in fs/exec.c.'>copy_strings</a> (1, &i_arg, page, p, 2);
<a name='L431'> argc++;
<a name='L432'> <font color='red'>}</font>
<a name='L433'><i><font color='green'>// 复制解释程序文件名到参数和环境空间中。若出错,则置出错码,跳转到exec_error1。</font></i>
<a name='L434'> p = <a href='../S/8.html#L166' title='Defined at 166 in fs/exec.c.'>copy_strings</a> (1, &i_name, page, p, 2);
<a name='L435'> argc++;
<a name='L436'> <b>if</b> (!p)
<a name='L437'> <font color='red'>{</font>
<a name='L438'> retval = -<a href='../S/28.html#L41' title='Defined at 41 in include/errno.h.'>ENOMEM</a>;
<a name='L439'> <b>goto</b> exec_error1;
<a name='L440'> <font color='red'>}</font>
<a name='L441'><i><font color='green'>/*</font></i>
<a name='L442'><i><font color='green'>* OK, now restart the process with the interpreter's inode.</font></i>
<a name='L443'><i><font color='green'>*/</font></i>
<a name='L444'><i><font color='green'>/*</font></i>
<a name='L445'><i><font color='green'>* OK,现在使用解释程序的i 节点重启进程。</font></i>
<a name='L446'><i><font color='green'>*/</font></i>
<a name='L447'><i><font color='green'>// 保留原fs 段寄存器(原指向用户数据段),现置其指向内核数据段。</font></i>
<a name='L448'> old_fs = <a href='../S/24.html#L83' title='Defined at 83 in include/asm/segment.h.'>get_fs</a> ();
<a name='L449'> <a href='../S/24.html#L103' title='Defined at 103 in include/asm/segment.h.'>set_fs</a> (<a href='../S/24.html#L93' title='Defined at 93 in include/asm/segment.h.'>get_ds</a> ());
<a name='L450'><i><font color='green'>// 取解释程序的i 节点,并跳转到restart_interp 处重新处理。</font></i>
<a name='L451'> <b>if</b> (!(inode = <a href='../S/14.html#L470' title='Defined at 470 in fs/namei.c.'>namei</a> (interp)))
<a name='L452'> <font color='red'>{</font> <i><font color='green'>/* get executables inode */</font></i>
<a name='L453'> <a href='../S/24.html#L103' title='Defined at 103 in include/asm/segment.h.'>set_fs</a> (old_fs);
<a name='L454'> retval = -<a href='../S/28.html#L31' title='Defined at 31 in include/errno.h.'>ENOENT</a>;
<a name='L455'> <b>goto</b> exec_error1;
<a name='L456'> <font color='red'>}</font>
<a name='L457'> <a href='../S/24.html#L103' title='Defined at 103 in include/asm/segment.h.'>set_fs</a> (old_fs);
<a name='L458'> <b>goto</b> restart_interp;
<a name='L459'> <font color='red'>}</font>
<a name='L460'><i><font color='green'>// 释放该缓冲区。</font></i>
<a name='L461'> <a href='../S/6.html#L377' title='Defined at 377 in fs/buffer.c.'>brelse</a> (bh);
<a name='L462'><i><font color='green'>// 下面对执行头信息进行处理。</font></i>
<a name='L463'><i><font color='green'>// 对于下列情况,将不执行程序:如果执行文件不是需求页可执行文件(ZMAGIC)、或者代码重定位部分</font></i>
<a name='L464'><i><font color='green'>// 长度a_trsize 不等于0、或者数据重定位信息长度不等于0、或者代码段+数据段+堆段长度超过50MB、</font></i>
<a name='L465'><i><font color='green'>// 或者i 节点表明的该执行文件长度小于代码段+数据段+符号表长度+执行头部分长度的总和。</font></i>
<a name='L466'> <b>if</b> (<a href='../S/21.html#L31' title='Defined at 31 in include/a.out.h.'>N_MAGIC</a> (ex) != <a href='../S/21.html#L43' title='Defined at 43 in include/a.out.h.'>ZMAGIC</a> || ex.a_trsize || ex.a_drsize ||
<a name='L467'> ex.a_text + ex.a_data + ex.a_bss > 0x3000000 ||
<a name='L468'> inode->i_size < ex.a_text + ex.a_data + ex.a_syms + <a href='../S/21.html#L62' title='Defined at 62 in include/a.out.h.'>N_TXTOFF</a> (ex))
<a name='L469'> <font color='red'>{</font>
<a name='L470'> retval = -<a href='../S/28.html#L37' title='Defined at 37 in include/errno.h.'>ENOEXEC</a>;
<a name='L471'> <b>goto</b> exec_error2;
<a name='L472'> <font color='red'>}</font>
<a name='L473'><i><font color='green'>// 如果执行文件执行头部分长度不等于一个内存块大小(1024 字节),也不能执行。转exec_error2。</font></i>
<a name='L474'> <b>if</b> (<a href='../S/21.html#L62' title='Defined at 62 in include/a.out.h.'>N_TXTOFF</a> (ex) != <a href='../D/23.html' title='Multiple defined in 2 places.'>BLOCK_SIZE</a>)
<a name='L475'> <font color='red'>{</font>
<a name='L476'> <a href='../S/73.html#L30' title='Defined at 30 in kernel/printk.c.'>printk</a> ("%s: N_TXTOFF != BLOCK_SIZE. See a.out.h.", filename);
<a name='L477'> retval = -<a href='../S/28.html#L37' title='Defined at 37 in include/errno.h.'>ENOEXEC</a>;
<a name='L478'> <b>goto</b> exec_error2;
<a name='L479'> <font color='red'>}</font>
<a name='L480'><i><font color='green'>// 如果sh_bang 标志没有设置,则复制指定个数的环境变量字符串和参数到参数和环境空间中。</font></i>
<a name='L481'><i><font color='green'>// 若sh_bang 标志已经设置,则表明是将运行脚本程序,此时环境变量页面已经复制,无须再复制。</font></i>
<a name='L482'> <b>if</b> (!sh_bang)
<a name='L483'> <font color='red'>{</font>
<a name='L484'> p = <a href='../S/8.html#L166' title='Defined at 166 in fs/exec.c.'>copy_strings</a> (envc, envp, page, p, 0);
<a name='L485'> p = <a href='../S/8.html#L166' title='Defined at 166 in fs/exec.c.'>copy_strings</a> (argc, argv, page, p, 0);
<a name='L486'><i><font color='green'>// 如果p=0,则表示环境变量与参数空间页面已经被占满,容纳不下了。转至出错处理处。</font></i>
<a name='L487'> <b>if</b> (!p)
<a name='L488'> <font color='red'>{</font>
<a name='L489'> retval = -<a href='../S/28.html#L41' title='Defined at 41 in include/errno.h.'>ENOMEM</a>;
<a name='L490'> <b>goto</b> exec_error2;
<a name='L491'> <font color='red'>}</font>
<a name='L492'> <font color='red'>}</font>
<a name='L493'><i><font color='green'>/* OK, This is the point of no return */</font></i>
<a name='L494'><i><font color='green'>/* OK,下面开始就没有返回的地方了 */</font></i>
<a name='L495'><i><font color='green'>// 如果原程序也是一个执行程序,则释放其i 节点,并让进程executable 字段指向新程序i 节点。</font></i>
<a name='L496'> <b>if</b> (current->executable)
<a name='L497'> <a href='../S/12.html#L221' title='Defined at 221 in fs/inode.c.'>iput</a> (current->executable);
<a name='L498'> current->executable = inode;
<a name='L499'><i><font color='green'>// 清复位所有信号处理句柄。但对于SIG_IGN 句柄不能复位,因此在322 与323 行之间需添加一条</font></i>
<a name='L500'><i><font color='green'>// if 语句:if (current->sa[I].sa_handler != SIG_IGN)。这是源代码中的一个bug。</font></i>
<a name='L501'> <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> < 32; <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>++)
<a name='L502'> current->sigaction[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>].sa_handler = <a href='../D/261.html' title='Multiple defined in 12 places.'>NULL</a>;
<a name='L503'><i><font color='green'>// 根据执行时关闭(close_on_exec)文件句柄位图标志,关闭指定的打开文件,并复位该标志。</font></i>
<a name='L504'> <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/31.html#L59' title='Defined at 59 in include/linux/fs.h.'>NR_OPEN</a>; <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>++)
<a name='L505'> <b>if</b> ((current->close_on_exec >> <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>) & 1)
<a name='L506'> <a href='../S/15.html#L299' title='Defined at 299 in fs/open.c.'>sys_close</a> (<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>);
<a name='L507'> current->close_on_exec = 0;
<a name='L508'><i><font color='green'>// 根据指定的基地址和限长,释放原来程序代码段和数据段所对应的内存页表指定的内存块及页表本身。</font></i>
<a name='L509'> <a href='../S/94.html#L158' title='Defined at 158 in mm/memory.c.'>free_page_tables</a> (<a href='../S/36.html#L343' title='Defined at 343 in include/linux/sched.h.'>get_base</a> (current->ldt[1]), <a href='../S/36.html#L346' title='Defined at 346 in include/linux/sched.h.'>get_limit</a> (0x0f));
<a name='L510'> <a href='../S/94.html#L158' title='Defined at 158 in mm/memory.c.'>free_page_tables</a> (<a href='../S/36.html#L343' title='Defined at 343 in include/linux/sched.h.'>get_base</a> (current->ldt[2]), <a href='../S/36.html#L346' title='Defined at 346 in include/linux/sched.h.'>get_limit</a> (0x17));
<a name='L511'><i><font color='green'>// 如果“上次任务使用了协处理器”指向的是当前进程,则将其置空,并复位使用了协处理器的标志。</font></i>
<a name='L512'> <b>if</b> (last_task_used_math == current)
<a name='L513'> last_task_used_math = <a href='../D/261.html' title='Multiple defined in 12 places.'>NULL</a>;
<a name='L514'> current->used_math = 0;
<a name='L515'><i><font color='green'>// 根据a_text 修改局部表中描述符基址和段限长,并将参数和环境空间页面放置在数据段末端。</font></i>
<a name='L516'><i><font color='green'>// 执行下面语句之后,p 此时是以数据段起始处为原点的偏移值,仍指向参数和环境空间数据开始处,</font></i>
<a name='L517'><i><font color='green'>// 也即转换成为堆栈的指针。</font></i>
<a name='L518'> p += <a href='../S/8.html#L248' title='Defined at 248 in fs/exec.c.'>change_ldt</a> (ex.a_text, page) - <a href='../S/8.html#L55' title='Defined at 55 in fs/exec.c.'>MAX_ARG_PAGES</a> * <a href='../D/324.html' title='Multiple defined in 4 places.'>PAGE_SIZE</a>;
<a name='L519'><i><font color='green'>// create_tables()在新用户堆栈中创建环境和参数变量指针表,并返回该堆栈指针。</font></i>
<a name='L520'> p = (<b>unsigned</b> <b>long</b>) <a href='../S/8.html#L70' title='Defined at 70 in fs/exec.c.'>create_tables</a> ((<b>char</b> *) p, argc, envc);
<a name='L521'><i><font color='green'>// 修改当前进程各字段为新执行程序的信息。令进程代码段尾值字段end_code = a_text;令进程数据</font></i>
<a name='L522'><i><font color='green'>// 段尾字段end_data = a_data + a_text;令进程堆结尾字段brk = a_text + a_data + a_bss。</font></i>
<a name='L523'> current->brk = ex.a_bss +
<a name='L524'> (current->end_data = ex.a_data + (current->end_code = ex.a_text));
<a name='L525'><i><font color='green'>// 设置进程堆栈开始字段为堆栈指针所在的页面,并重新设置进程的用户id 和组id。</font></i>
<a name='L526'> current->start_stack = p & 0xfffff000;
<a name='L527'> current->euid = e_uid;
<a name='L528'> current->egid = e_gid;
<a name='L529'><i><font color='green'>// 初始化一页bss 段数据,全为零。</font></i>
<a name='L530'> <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> = ex.a_text + ex.a_data;
<a name='L531'> <b>while</b> (<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> & 0xfff)
<a name='L532'> <a href='../S/24.html#L44' title='Defined at 44 in include/asm/segment.h.'>put_fs_byte</a> (0, (<b>char</b> *) (<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>++));
<a name='L533'><i><font color='green'>// 将原调用系统中断的程序在堆栈上的代码指针替换为指向新执行程序的入口点,并将堆栈指针替换</font></i>
<a name='L534'><i><font color='green'>// 为新执行程序的堆栈指针。返回指令将弹出这些堆栈数据并使得CPU 去执行新的执行程序,因此不会</font></i>
<a name='L535'><i><font color='green'>// 返回到原调用系统中断的程序中去了。</font></i>
<a name='L536'> eip[0] = ex.a_entry; <i><font color='green'>/* eip, magic happens :-) */</font></i><i><font color='green'>/* eip,魔法起作用了 */</font></i>
<a name='L537'> eip[3] = p; <i><font color='green'>/* stack pointer */</font></i><i><font color='green'>/* esp,堆栈指针 */</font></i>
<a name='L538'> <b>return</b> 0;
<a name='L539'>exec_error2:
<a name='L540'> <a href='../S/12.html#L221' title='Defined at 221 in fs/inode.c.'>iput</a> (inode);
<a name='L541'>exec_error1:
<a name='L542'> <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/8.html#L55' title='Defined at 55 in fs/exec.c.'>MAX_ARG_PAGES</a>; <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>++)
<a name='L543'> <a href='../S/94.html#L130' title='Defined at 130 in mm/memory.c.'>free_page</a> (page[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>]);
<a name='L544'> <b>return</b> (retval);
<a name='L545'><font color='red'>}</font>
</pre>
<hr>
<a name='BOTTOM'>
<i><font color='green'>/* [<][>]<a href='#L70'>[^]</a><a href='#L294'>[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 + =
减小字号Ctrl + -
显示快捷键?