8.html

来自「linux 0.11中文版 有注释」· HTML 代码 · 共 573 行 · 第 1/4 页

HTML
573
字号
<a name='L268'>  <b>__asm__</b> ("pushl $0x17\n\tpop %%fs"::);
<a name='L269'><i><font color='green'>// 将参数和环境空间已存放数据的页面(共可有MAX_ARG_PAGES 页,128kB)放到数据段线性地址的</font></i>
<a name='L270'><i><font color='green'>// 末端。是调用函数put_page()进行操作的(mm/memory.c, 197)。</font></i>
<a name='L271'>  data_base += data_limit;
<a name='L272'>  <b>for</b> (<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> - 1; <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> &gt;= 0; <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>--)
<a name='L273'>    <font color='red'>{</font>
<a name='L274'>      data_base -= <a href='../D/324.html' title='Multiple defined in 4 places.'>PAGE_SIZE</a>;
<a name='L275'>      <b>if</b> (page[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>])              <i><font color='green'>// 如果该页面存在,</font></i>
<a name='L276'>        <a href='../S/94.html#L306' title='Defined at 306 in mm/memory.c.'>put_page</a> (page[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>], data_base);  <i><font color='green'>// 就放置该页面。</font></i>
<a name='L277'>    <font color='red'>}</font>
<a name='L278'>  <b>return</b> data_limit;            <i><font color='green'>// 最后返回数据段限长(64MB)。</font></i>
<a name='L279'><font color='red'>}</font>
<a name='L280'>
<a name='L281'><i><font color='green'>/*</font></i>
<a name='L282'><i><font color='green'>* 'do_execve()' executes a new program.</font></i>
<a name='L283'><i><font color='green'>*/</font></i>
<a name='L284'><i><font color='green'>/*</font></i>
<a name='L285'><i><font color='green'>* 'do_execve()'函数执行一个新程序。</font></i>
<a name='L286'><i><font color='green'>*/</font></i>
<a name='L287'><i><font color='green'>//// execve()系统中断调用函数。加载并执行子进程(其它程序)。</font></i>
<a name='L288'><i><font color='green'>// 该函数系统中断调用(int 0x80)功能号__NR_execve 调用的函数。</font></i>
<a name='L289'><i><font color='green'>// 参数:eip - 指向堆栈中调用系统中断的程序代码指针eip 处,参见kernel/system_call.s 程序</font></i>
<a name='L290'><i><font color='green'>// 开始部分的说明;tmp - 系统中断调用本函数时的返回地址,无用;</font></i>
<a name='L291'><i><font color='green'>// filename - 被执行程序文件名;argv - 命令行参数指针数组;envp - 环境变量指针数组。</font></i>
<a name='L292'><i><font color='green'>// 返回:如果调用成功,则不返回;否则设置出错号,并返回-1。</font></i>
<a name='L293'><b>int</b>
<a name='L294'><a href='../S/77.html#L262' title='Refered from 262 in kernel/system_call.s.'>do_execve</a> (<b>unsigned</b> <b>long</b> *eip, <b>long</b> tmp, <b>char</b> *filename,
<a name='L295'>           <b>char</b> **argv, <b>char</b> **envp)
<a name='L296'><font color='red'>{</font>
<a name='L297'>  <b>struct</b> m_inode *inode;        <i><font color='green'>// 内存中I 节点指针结构变量。</font></i>
<a name='L298'>  <b>struct</b> buffer_head *bh;       <i><font color='green'>// 高速缓存块头指针。</font></i>
<a name='L299'>  <b>struct</b> exec ex;               <i><font color='green'>// 执行文件头部数据结构变量。</font></i>
<a name='L300'>  <b>unsigned</b> <b>long</b> page[<a href='../S/8.html#L55' title='Defined at 55 in fs/exec.c.'>MAX_ARG_PAGES</a>];    <i><font color='green'>// 参数和环境字符串空间的页面指针数组。</font></i>
<a name='L301'>  <b>int</b> <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>, argc, envc;
<a name='L302'>  <b>int</b> e_uid, e_gid;             <i><font color='green'>// 有效用户id 和有效组id。</font></i>
<a name='L303'>  <b>int</b> retval;                   <i><font color='green'>// 返回值。</font></i>
<a name='L304'>  <b>int</b> sh_bang = 0;              <i><font color='green'>// 控制是否需要执行脚本处理代码。</font></i>
<a name='L305'><i><font color='green'>// 参数和环境字符串空间中的偏移指针,初始化为指向该空间的最后一个长字处。</font></i>
<a name='L306'>  <b>unsigned</b> <b>long</b> p = <a href='../D/324.html' title='Multiple defined in 4 places.'>PAGE_SIZE</a> * <a href='../S/8.html#L55' title='Defined at 55 in fs/exec.c.'>MAX_ARG_PAGES</a> - 4;
<a name='L307'>
<a name='L308'><i><font color='green'>// eip[1]中是原代码段寄存器cs,其中的选择符不可以是内核段选择符,也即内核不能调用本函数。</font></i>
<a name='L309'>  <b>if</b> ((0xffff &amp; eip[1]) != 0x000f)
<a name='L310'>    <a href='../S/72.html#L24' title='Defined at 24 in kernel/panic.c.'>panic</a> ("execve called from supervisor mode");
<a name='L311'><i><font color='green'>// 初始化参数和环境串空间的页面指针数组(表)。</font></i>
<a name='L312'>  <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> &lt; <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>++)   <i><font color='green'>/* clear page-table */</font></i>
<a name='L313'>    page[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>] = 0;
<a name='L314'><i><font color='green'>// 取可执行文件的对应i 节点号。</font></i>
<a name='L315'>  <b>if</b> (!(inode = <a href='../S/14.html#L470' title='Defined at 470 in fs/namei.c.'>namei</a> (filename)))      <i><font color='green'>/* get executables inode */</font></i>
<a name='L316'>    <b>return</b> -<a href='../S/28.html#L31' title='Defined at 31 in include/errno.h.'>ENOENT</a>;
<a name='L317'><i><font color='green'>// 计算参数个数和环境变量个数。</font></i>
<a name='L318'>  argc = <a href='../D/738.html' title='Multiple defined in 17 places.'>count</a> (argv);
<a name='L319'>  envc = <a href='../D/738.html' title='Multiple defined in 17 places.'>count</a> (envp);
<a name='L320'>
<a name='L321'><i><font color='green'>// 执行文件必须是常规文件。若不是常规文件则置出错返回码,跳转到exec_error2(第347 行)。</font></i>
<a name='L322'>restart_interp:
<a name='L323'>  <b>if</b> (!<a href='../S/43.html#L34' title='Defined at 34 in include/sys/stat.h.'>S_ISREG</a> (inode-&gt;i_mode))
<a name='L324'>    <font color='red'>{</font>                           <i><font color='green'>/* must be regular file */</font></i>
<a name='L325'>      retval = -<a href='../S/28.html#L42' title='Defined at 42 in include/errno.h.'>EACCES</a>;
<a name='L326'>      <b>goto</b> exec_error2;
<a name='L327'>    <font color='red'>}</font>
<a name='L328'><i><font color='green'>// 检查被执行文件的执行权限。根据其属性(对应i 节点的uid 和gid),看本进程是否有权执行它。</font></i>
<a name='L329'>  <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> = inode-&gt;i_mode;
<a name='L330'>  e_uid = (<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> &amp; <a href='../S/43.html#L30' title='Defined at 30 in include/sys/stat.h.'>S_ISUID</a>) ? inode-&gt;i_uid : current-&gt;euid;
<a name='L331'>  e_gid = (<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> &amp; <a href='../S/43.html#L31' title='Defined at 31 in include/sys/stat.h.'>S_ISGID</a>) ? inode-&gt;i_gid : current-&gt;egid;
<a name='L332'>  <b>if</b> (current-&gt;euid == inode-&gt;i_uid)
<a name='L333'>    <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> &gt;&gt;= 6;
<a name='L334'>  <b>else</b> <b>if</b> (current-&gt;egid == inode-&gt;i_gid)
<a name='L335'>    <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> &gt;&gt;= 3;
<a name='L336'>  <b>if</b> (!(<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> &amp; 1) &amp;&amp; !((inode-&gt;i_mode &amp; 0111) &amp;&amp; <a href='../S/34.html#L37' title='Defined at 37 in include/linux/kernel.h.'>suser</a> ()))
<a name='L337'>    <font color='red'>{</font>
<a name='L338'>      retval = -<a href='../S/28.html#L37' title='Defined at 37 in include/errno.h.'>ENOEXEC</a>;
<a name='L339'>      <b>goto</b> exec_error2;
<a name='L340'>    <font color='red'>}</font>
<a name='L341'><i><font color='green'>// 读取执行文件的第一块数据到高速缓冲区,若出错则置出错码,跳转到exec_error2 处去处理。</font></i>
<a name='L342'>  <b>if</b> (!(bh = <a href='../S/6.html#L397' title='Defined at 397 in fs/buffer.c.'>bread</a> (inode-&gt;i_dev, inode-&gt;i_zone[0])))
<a name='L343'>    <font color='red'>{</font>
<a name='L344'>      retval = -<a href='../S/28.html#L42' title='Defined at 42 in include/errno.h.'>EACCES</a>;
<a name='L345'>      <b>goto</b> exec_error2;
<a name='L346'>    <font color='red'>}</font>
<a name='L347'><i><font color='green'>// 下面对执行文件的头结构数据进行处理,首先让ex 指向执行头部分的数据结构。</font></i>
<a name='L348'>  ex = *((<b>struct</b> exec *) bh-&gt;b_data);   <i><font color='green'>/* read exec-header */</font></i><i><font color='green'>/* 读取执行头部分 */</font></i>
<a name='L349'><i><font color='green'>// 如果执行文件开始的两个字节为'#!',并且sh_bang 标志没有置位,则处理脚本文件的执行。</font></i>
<a name='L350'>  <b>if</b> ((bh-&gt;b_data[0] == '#') &amp;&amp; (bh-&gt;b_data[1] == '!') &amp;&amp; (!sh_bang))
<a name='L351'>    <font color='red'>{</font>
<a name='L352'><i><font color='green'>/*</font></i>
<a name='L353'><i><font color='green'>* This section does the #! interpretation.</font></i>
<a name='L354'><i><font color='green'>* Sorta complicated, but hopefully it will work. -TYT</font></i>
<a name='L355'><i><font color='green'>*/</font></i>
<a name='L356'><i><font color='green'>/*</font></i>
<a name='L357'><i><font color='green'>* 这部分处理对'#!'的解释,有些复杂,但希望能工作。-TYT</font></i>
<a name='L358'><i><font color='green'>*/</font></i>
<a name='L359'>
<a name='L360'>      <b>char</b> <a href='../D/716.html' title='Multiple defined in 16 places.'>buf</a>[1023], *cp, *interp, *i_name, *i_arg;
<a name='L361'>      <b>unsigned</b> <b>long</b> old_fs;
<a name='L362'>
<a name='L363'><i><font color='green'>// 复制执行程序头一行字符'#!'后面的字符串到buf 中,其中含有脚本处理程序名。</font></i>
<a name='L364'>      <a href='../S/42.html#L56' title='Defined at 56 in include/string.h.'>strncpy</a> (<a href='../D/716.html' title='Multiple defined in 16 places.'>buf</a>, bh-&gt;b_data + 2, 1022);
<a name='L365'><i><font color='green'>// 释放高速缓冲块和该执行文件i 节点。</font></i>
<a name='L366'>      <a href='../S/6.html#L377' title='Defined at 377 in fs/buffer.c.'>brelse</a> (bh);
<a name='L367'>      <a href='../S/12.html#L221' title='Defined at 221 in fs/inode.c.'>iput</a> (inode);
<a name='L368'><i><font color='green'>// 取第一行内容,并删除开始的空格、制表符。</font></i>
<a name='L369'>      <a href='../D/716.html' title='Multiple defined in 16 places.'>buf</a>[1022] = '\0';
<a name='L370'>      <b>if</b> (cp = <a href='../S/42.html#L168' title='Defined at 168 in include/string.h.'>strchr</a> (<a href='../D/716.html' title='Multiple defined in 16 places.'>buf</a>, '\n'))
<a name='L371'>        <font color='red'>{</font>
<a name='L372'>          *cp = '\0';
<a name='L373'>          <b>for</b> (cp = <a href='../D/716.html' title='Multiple defined in 16 places.'>buf</a>; (*cp == ' ') || (*cp == '\t'); cp++);
<a name='L374'>        <font color='red'>}</font>
<a name='L375'><i><font color='green'>// 若该行没有其它内容,则出错。置出错码,跳转到exec_error1 处。</font></i>
<a name='L376'>      <b>if</b> (!cp || *cp == '\0')
<a name='L377'>        <font color='red'>{</font>
<a name='L378'>          retval = -<a href='../S/28.html#L37' title='Defined at 37 in include/errno.h.'>ENOEXEC</a>;    <i><font color='green'>/* No interpreter name found */</font></i>
<a name='L379'>          <b>goto</b> exec_error1;
<a name='L380'>        <font color='red'>}</font>
<a name='L381'><i><font color='green'>// 否则就得到了开头是脚本解释执行程序名称的一行内容。</font></i>
<a name='L382'>      interp = i_name = cp;
<a name='L383'><i><font color='green'>// 下面分析该行。首先取第一个字符串,其应该是脚本解释程序名,iname 指向该名称。</font></i>
<a name='L384'>      i_arg = 0;
<a name='L385'>      <b>for</b> (; *cp &amp;&amp; (*cp != ' ') &amp;&amp; (*cp != '\t'); cp++)
<a name='L386'>        <font color='red'>{</font>
<a name='L387'>          <b>if</b> (*cp == '/')
<a name='L388'>            i_name = cp + 1;
<a name='L389'>        <font color='red'>}</font>
<a name='L390'><i><font color='green'>// 若文件名后还有字符,则应该是参数串,令i_arg 指向该串。</font></i>
<a name='L391'>      <b>if</b> (*cp)
<a name='L392'>        <font color='red'>{</font>
<a name='L393'>          *cp++ = '\0';
<a name='L394'>          i_arg = cp;
<a name='L395'>        <font color='red'>}</font>
<a name='L396'><i><font color='green'>/*</font></i>
<a name='L397'><i><font color='green'>* OK, we've parsed out the interpreter name and</font></i>
<a name='L398'><i><font color='green'>* (optional) argument.</font></i>
<a name='L399'><i><font color='green'>*/</font></i>
<a name='L400'><i><font color='green'>/*</font></i>
<a name='L401'><i><font color='green'>* OK,我们已经解析出解释程序的文件名以及(可选的)参数。</font></i>
<a name='L402'><i><font color='green'>*/</font></i>
<a name='L403'><i><font color='green'>// 若sh_bang 标志没有设置,则设置它,并复制指定个数的环境变量串和参数串到参数和环境空间中。</font></i>
<a name='L404'>      <b>if</b> (sh_bang++ == 0)
<a name='L405'>        <font color='red'>{</font>
<a name='L406'>          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='L407'>          p = <a href='../S/8.html#L166' title='Defined at 166 in fs/exec.c.'>copy_strings</a> (--argc, argv + 1, page, p, 0);
<a name='L408'>        <font color='red'>}</font>
<a name='L409'><i><font color='green'>/*</font></i>
<a name='L410'><i><font color='green'>* Splice in (1) the interpreter's name for argv[0]</font></i>
<a name='L411'><i><font color='green'>* (2) (optional) argument to interpreter</font></i>

⌨️ 快捷键说明

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